Giriş metni iletişim kutusu Android


298

Bir kullanıcı ButtonUygulamamda a'yı tıkladığında (a ile yazdırılır SurfaceView), bir metnin Dialoggörünmesini istiyorum ve sonucu a olarak saklamak istiyorum String. Metnin Dialoggeçerli ekranın üzerine yerleşmesini istiyorum . Bunu nasıl yapabilirim?

Yanıtlar:


586

AlertDialog kullanmak için iyi bir fırsat gibi görünüyor .

Göründüğü kadar basit, Android'in bunu yapmak için yerleşik bir iletişim kutusu yok (bildiğim kadarıyla). Neyse ki, standart bir AlertDialog oluşturmanın üstünde biraz ekstra bir çalışma var. Kullanıcının veri girmesi için bir EditText oluşturmanız ve bunu AlertDialog görünümü olarak ayarlamanız yeterlidir. Gerekirse setInputType kullanarak izin verilen girdi türünü özelleştirebilirsiniz .

Üye değişkeni kullanabiliyorsanız, değişkeni EditText değerine ayarlayabilirsiniz ve iletişim kutusu kapatıldıktan sonra değişecektir. Üye değişkeni kullanamıyorsanız, dize değerini doğru yere göndermek için bir dinleyici kullanmanız gerekebilir. (İhtiyacınız olan şey buysa daha fazla düzenleyebilir ve ayrıntılandırabilirim).

Sınıfınız içinde:

private String m_Text = "";

Düğmenizin OnClickListener'ında (veya oradan çağrılan bir işlevde):

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title");

// Set up the input
final EditText input = new EditText(this);
// Specify the type of input expected; this, for example, sets the input as a password, and will mask the text
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
builder.setView(input);

// Set up the buttons
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
    @Override
    public void onClick(DialogInterface dialog, int which) {
        m_Text = input.getText().toString();
    }
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
    }
});

builder.show();

1
Bir ekran nesnesini sürekli olarak güncelleyen ve işleyen bir iş parçacığım var ve ekran nesnesinin güncelleme yönteminde builder.show () yöntemini çağırıyorum.
Luke Taylor

1
Ah. Çalışan bir iş parçacığındaysanız, builder.show () öğesini koymayı deneyin; Bu örneğe benzer şekilde runOnUiThread ile çağırın: stackoverflow.com/a/3134720/1098302 Veya yukarıdaki tüm kodu (AlertDialog'u oluşturan) ayrı bir yöntemde koymak ve runOnUiThread içinden bu yöntemi çağırmak daha iyi olur.
Aaron

2
Teşekkür ederim. Bu iyi. Howerver, küçük bir sorun var. Bildirmek gerekiyor global Context, Context cont;ve daha sonra, alertdialog tarafından "bu" değiştirin tarafından cont. AlertDialog.Builder oluşturucu = yeni AlertDialog.Builder (devam); final EditText girişi = yeni EditText (devam);

8
Bağlam için genel bir değişken oluşturmak yerine, "MainActivity.this" gibi bir bağlam geçebilirsiniz ("MainActivity" metnini kullanmak istediğiniz etkinlik sınıfı adı ile değiştirmeniz gerekir).
kunal18

3
Çoğu Android kullanıcı arayüzü gibi, bunların tümüyle eşzamansız olduğunu belirtmek gerekir ... yani, bir sonraki adıma giden kapıyı yapan bir şey olmadıkça kullanıcının Tamam'a
dokunmasını beklemeyecektir

102

@ Aaron'un cevabına , iletişim kutusunu daha iyi bir şekilde şekillendirme fırsatı veren bir yaklaşımla ekleyeceğim . Düzeltilmiş bir örnek:

AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("Title");
// I'm using fragment here so I'm using getView() to provide ViewGroup
// but you can provide here any other instance of ViewGroup from your Fragment / Activity
View viewInflated = LayoutInflater.from(getContext()).inflate(R.layout.text_inpu_password, (ViewGroup) getView(), false);
// Set up the input
final EditText input = (EditText) viewInflated.findViewById(R.id.input);
// Specify the type of input expected; this, for example, sets the input as a password, and will mask the text
builder.setView(viewInflated);

// Set up the buttons
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.dismiss();
        m_Text = input.getText().toString();
    }   
}); 
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
    }   
}); 

builder.show();

EditText iletişim kutusunu oluşturmak için kullanılan örnek düzen şunlardır:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="@dimen/content_padding_normal">

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <AutoCompleteTextView
            android:id="@+id/input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/hint_password"
            android:imeOptions="actionDone"
            android:inputType="textPassword" />

    </android.support.design.widget.TextInputLayout>
</FrameLayout>

Nihai sonuç:

Metin Düzenle İletişim Kutusu örneği


10
Mükemmel çözüm! Sadece değiştirilir getView()ile findViewById(android.R.id.content)ve tüm cazibe gibi çalıştı. Paylaştığınız için çok teşekkürler :)
Atul

Bu findViewById ile yayınlamayı unutmayın (ViewGroup)!
Martin Erlic

2
"Element AutoCompleteTextView burada izin verilmiyor ..."
Jaroslav Záruba

1
@JPerk: android.R.id.content size bir görünümün kök unsurunu verir. Lütfen buna bakın: stackoverflow.com/a/12887919/1911652
Atul

1
Sadece merak ediyorum, ama değeri ne @dimen/content_padding_normal?
Edric

62

Peki ya bu ÖRNEK ? Basit görünüyor.

final EditText txtUrl = new EditText(this);

// Set the default text to a link of the Queen
txtUrl.setHint("http://www.librarising.com/astrology/celebs/images2/QR/queenelizabethii.jpg");

new AlertDialog.Builder(this)
  .setTitle("Moustachify Link")
  .setMessage("Paste in the link of an image to moustachify!")
  .setView(txtUrl)
  .setPositiveButton("Moustachify", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
      String url = txtUrl.getText().toString();
      moustachify(null, url);
    }
  })
  .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
    }
  })
  .show(); 

3
Aaron'ınkiyle hemen hemen aynı, ancak inşaatçıyı zincirler. Her ikisi de iyi çalıştığı için kişisel tercih meselesi.
Scott Biggs

12

En biraz boşluk istiyorsanız leftve rightbir inputgörünümü, sen gibi bazı dolgu ekleyebilir

private fun showAlertWithTextInputLayout(context: Context) {
    val textInputLayout = TextInputLayout(context)
    textInputLayout.setPadding(
        resources.getDimensionPixelOffset(R.dimen.dp_19), // if you look at android alert_dialog.xml, you will see the message textview have margin 14dp and padding 5dp. This is the reason why I use 19 here
        0,
        resources.getDimensionPixelOffset(R.dimen.dp_19),
        0
    )
    val input = EditText(context)
    textInputLayout.hint = "Email"
    textInputLayout.addView(input)

    val alert = AlertDialog.Builder(context)
        .setTitle("Reset Password")
        .setView(textInputLayout)
        .setMessage("Please enter your email address")
        .setPositiveButton("Submit") { dialog, _ ->
            // do some thing with input.text
            dialog.cancel()
        }
        .setNegativeButton("Cancel") { dialog, _ ->
            dialog.cancel()
        }.create()

    alert.show()
}

dimens.xml

<dimen name="dp_19">19dp</dimen>

Umarım yardımcı olur


Nedir resources?
Sebastian Palma

5

AlertDialog.BuilderÖzel bir iletişim sınıfı oluşturmak için genişletmek daha temiz ve daha yeniden kullanılabilir buldum . Bu, kullanıcıdan bir telefon numarası girmesini isteyen bir iletişim kutusu içindir. Önceden ayarlanmış bir telefon numarası, aramadan setNumber()önce arayarak da sağlanabilir show().

InputSenderDialog.java

public class InputSenderDialog extends AlertDialog.Builder {

    public interface InputSenderDialogListener{
        public abstract void onOK(String number);
        public abstract void onCancel(String number);
    }

    private EditText mNumberEdit;

    public InputSenderDialog(Activity activity, final InputSenderDialogListener listener) {
        super( new ContextThemeWrapper(activity, R.style.AppTheme) );

        @SuppressLint("InflateParams") // It's OK to use NULL in an AlertDialog it seems...
        View dialogLayout = LayoutInflater.from(activity).inflate(R.layout.dialog_input_sender_number, null);
        setView(dialogLayout);

        mNumberEdit = dialogLayout.findViewById(R.id.numberEdit);

        setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                if( listener != null )
                    listener.onOK(String.valueOf(mNumberEdit.getText()));

            }
        });

        setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                if( listener != null )
                    listener.onCancel(String.valueOf(mNumberEdit.getText()));
            }
        });
    }

    public InputSenderDialog setNumber(String number){
        mNumberEdit.setText( number );
        return this;
    }

    @Override
    public AlertDialog show() {
        AlertDialog dialog = super.show();
        Window window = dialog.getWindow();
        if( window != null )
            window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        return dialog;
    }
}

dialog_input_sender_number.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:padding="10dp">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        android:paddingBottom="20dp"
        android:text="Input phone number"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <TextView
        android:id="@+id/numberLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/title"
        app:layout_constraintLeft_toLeftOf="parent"
        android:text="Phone number" />

    <EditText
        android:id="@+id/numberEdit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/numberLabel"
        app:layout_constraintLeft_toLeftOf="parent"
        android:inputType="phone" >
        <requestFocus />
    </EditText>

</android.support.constraint.ConstraintLayout>

Kullanımı:

new InputSenderDialog(getActivity(), new InputSenderDialog.InputSenderDialogListener() {
    @Override
    public void onOK(final String number) {
        Log.d(TAG, "The user tapped OK, number is "+number);
    }

    @Override
    public void onCancel(String number) {
        Log.d(TAG, "The user tapped Cancel, number is "+number);
    }
}).setNumber(someNumberVariable).show();

4

@LukeTaylor: Şu anda elimde aynı görev var (bir EditText içeren bir açılır pencere / iletişim kutusu oluşturma) ..
Şahsen, ben tamamen dinamik yol yaratıcılık açısından biraz sınırlayıcı buluyorum.

TAM ÖZEL DİYALOG DÜZENİ: İletişim kutusunu oluşturmak için tamamen Code'a

güvenmek yerine , tam olarak şu şekilde özelleştirebilirsiniz:

1) - Yeni bir Layout Resourcedosya oluşturun .. Bu, tam yaratıcı özgürlüğe izin vererek Diyalogunuz olarak hareket edecektir!
NOT: İşleri temiz ve yerinde tutmaya yardımcı olması için Malzeme Tasarımı yönergelerine başvurun.

2) - Tüm Viewöğelerinize kimlik verin .. Aşağıdaki örnek kodumda 1 EditTextve 2 var Buttons.

3) - BirActivity bir ileButton, test amacıyla .. İletişim Kutunuzu şişirip başlatacağız!

public void buttonClick_DialogTest(View view) {

    AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);

    //  Inflate the Layout Resource file you created in Step 1
    View mView = getLayoutInflater().inflate(R.layout.timer_dialog_layout, null);

    //  Get View elements from Layout file. Be sure to include inflated view name (mView)
    final EditText mTimerMinutes = (EditText) mView.findViewById(R.id.etTimerValue);
    Button mTimerOk = (Button) mView.findViewById(R.id.btnTimerOk);
    Button mTimerCancel = (Button) mView.findViewById(R.id.btnTimerCancel);

    //  Create the AlertDialog using everything we needed from above
    mBuilder.setView(mView);
    final AlertDialog timerDialog = mBuilder.create();

    //  Set Listener for the OK Button
    mTimerOk.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick (View view) {
            if (!mTimerMinutes.getText().toString().isEmpty()) {
                Toast.makeText(MainActivity.this, "You entered a Value!,", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(MainActivity.this, "Please enter a Value!", Toast.LENGTH_LONG).show();
            }
        }
    });

    //  Set Listener for the CANCEL Button
    mTimerCancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick (View view) {
            timerDialog.dismiss();
        }
    });

    //  Finally, SHOW your Dialog!
    timerDialog.show();


    //  END OF buttonClick_DialogTest
}


Kekin parçası! Tam yaratıcı özgürlük! Sadece Malzeme Kurallarına uyduğunuzdan emin olun;)

Umarım bu birine yardımcı olur! Bana ne düşündüğünü söyle!


2
Sadece (-1) inişini neden merak ettiniz? Sağladığım mantık tam olarak amaçlandığı ve tarif edildiği gibi çalışıyor .. Bu yazıya henüz bahsedilmemiş iyi bir ek olduğunu ve mükemmel bir alternatif çözüm olduğunu hissettim. Ancak , sağladığım bilgileri küçültmek için meşru bir nedeniniz varsa, neden yaptığınız için bir bağlam sunabilmeniz biraz daha yararlı olacaktır, böylece kendim ve diğerleri akıl yürütmeyi öğrenebilir ve anlayabilir .. Downvotes aslında çok olabilir öğrenme sürecinde yararlı ve yararlı - ancak nedeninin arkasında bağlam varsa.
Studio2bDesigns

4

Benim için iş

private void showForgotDialog(Context c) {
        final EditText taskEditText = new EditText(c);
        AlertDialog dialog = new AlertDialog.Builder(c)
                .setTitle("Forgot Password")
                .setMessage("Enter your mobile number?")
                .setView(taskEditText)
                .setPositiveButton("Reset", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        String task = String.valueOf(taskEditText.getText());
                    }
                })
                .setNegativeButton("Cancel", null)
                .create();
        dialog.show();
    }

Nasıl aranır? (Mevcut etkinlik adı)

showForgotDialog (current_activity_name.this);

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.