Masukkan dialog teks Android

298

Ketika seorang pengguna mengklik a Buttondi Aplikasi saya (yang dicetak dalam a SurfaceView), saya ingin teks Dialogmuncul dan saya ingin menyimpan hasilnya dalam a String. Saya ingin teks Dialoguntuk overlay layar saat ini. Bagaimana saya bisa melakukan ini?

Luke Taylor
sumber

Jawaban:

586

Kedengarannya seperti peluang bagus untuk menggunakan AlertDialog .

Sebagai dasar tampaknya, Android tidak memiliki dialog built-in untuk melakukan ini (sejauh yang saya tahu). Untungnya, ini hanya pekerjaan ekstra di atas untuk menciptakan AlertDialog standar. Anda hanya perlu membuat EditText agar pengguna dapat memasukkan data, dan mengaturnya sebagai tampilan AlertDialog. Anda dapat menyesuaikan jenis input yang diizinkan menggunakan setInputType , jika perlu.

Jika Anda dapat menggunakan variabel anggota, Anda cukup mengatur variabel ke nilai EditText, dan itu akan tetap ada setelah dialog telah diberhentikan. Jika Anda tidak dapat menggunakan variabel anggota, Anda mungkin perlu menggunakan pendengar untuk mengirim nilai string ke tempat yang tepat. (Saya dapat mengedit dan menguraikan lebih banyak jika ini yang Anda butuhkan).

Di dalam kelas Anda:

private String m_Text = "";

Di dalam OnClickListener tombol Anda (atau dalam fungsi yang dipanggil dari sana):

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();
Harun
sumber
1
Saya punya utas yang terus-menerus memperbarui dan merender objek layar, dan saya memanggil metode builder.show () dalam metode pembaruan objek layar.
Luke Taylor
1
Oh Jika Anda berada di utas pekerja, coba letakkan builder.show (); panggil dengan runOnUiThread, mirip dengan contoh ini: stackoverflow.com/a/3134720/1098302 Atau mungkin akan lebih baik untuk meletakkan semua kode di atas (yang membuat AlertDialog) dalam metode terpisah, dan panggil metode itu dari dalam runOnUiThread.
Aaron
2
Terima kasih. Itu bagus. Namun, ada sedikit masalah. Perlu mendeklarasikan global Context, Context cont;dan kemudian, ganti "ini" di alertdialog oleh cont. AlertDialog.Builder builder = new AlertDialog.Builder (lanjutan); input EditText akhir = EditText (lanjutan) baru;
8
Saya pikir alih-alih membuat variabel global untuk konteks, Anda dapat melewati konteks seperti: "MainActivity.this" (Anda perlu mengganti teks "MainActivity" dengan nama kelas aktivitas yang ingin Anda gunakan).
kunal18
3
Mungkin perlu dicatat bahwa, seperti kebanyakan Android UI, ini semua tidak sinkron ... artinya tidak akan menunggu pengguna untuk mengetuk OK kecuali Anda memiliki sesuatu yang membuat gerbang ke langkah berikutnya ...
ewall
101

Saya akan menambahkan jawaban @ Aaron dengan pendekatan yang memberi Anda kesempatan untuk mendesain kotak dialog dengan cara yang lebih baik. Berikut ini adalah contoh yang disesuaikan:

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();

Berikut ini contoh tata letak yang digunakan untuk membuat dialog EditText:

<?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>

Hasil akhir:

Contoh Dialog EditText

Michal
sumber
10
Solusi hebat! Saya baru saja diganti getView()dengan findViewById(android.R.id.content)dan itu semua bekerja seperti pesona. Terima kasih banyak untuk berbagi :)
Atul
Ingatlah untuk melemparkan findViewById itu dengan (ViewGroup)!
Martin Erlic
2
"Elemen AutoCompleteTextView tidak diizinkan di sini ..."
Jaroslav Záruba
1
@JPerk: android.R.id.content memberi Anda elemen root tampilan. Silakan lihat ini: stackoverflow.com/a/12887919/1911652
Atul
1
Hanya ingin tahu, tapi apa nilainya @dimen/content_padding_normal?
Edric
62

Bagaimana dengan CONTOH ini ? Tampaknya mudah.

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(); 
bhekman
sumber
3
Hampir sama dengan milik Harun, tetapi rantai pembangun. Soal preferensi pribadi karena keduanya berfungsi dengan baik.
Scott Biggs
12

Jika Anda ingin beberapa ruang di leftdan rightdari inputpandangan, Anda dapat menambahkan beberapa padding seperti

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>

Semoga ini bisa membantu

Phan Van Linh
sumber
Apa resources?
Sebastian Palma
5

Saya merasa lebih bersih dan lebih dapat digunakan kembali untuk memperluas AlertDialog.Builderuntuk membuat kelas dialog kustom. Ini untuk dialog yang meminta pengguna untuk memasukkan nomor telepon. Nomor telepon standar juga dapat diberikan dengan menelepon setNumber()sebelum menelepon 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>

Pemakaian:

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();
Magnus W
sumber
4

@LukeTaylor: Saat ini saya memiliki tugas yang sama (membuat popup / dialog yang berisi EditText) ..
Secara pribadi, saya menemukan rute yang sepenuhnya dinamis menjadi agak membatasi dalam hal kreativitas.

SEPENUHNYA LAYOUT DIALOG KUSTOM:

Daripada mengandalkan sepenuhnya pada Kode untuk membuat Dialog, Anda dapat sepenuhnya menyesuaikannya seperti:

1) - Buat Layout Resourcefile baru .. Ini akan bertindak sebagai Dialog Anda, memungkinkan kebebasan kreatif penuh!
CATATAN: Lihat pedoman Desain Bahan untuk membantu menjaga semuanya tetap bersih dan tepat sasaran.

2) - Berikan ID untuk semua Viewelemen Anda .. Dalam kode contoh saya di bawah ini, saya punya 1 EditText, dan 2 Buttons.

3) - Buat ActivitydenganButton, untuk tujuan pengujian .. Kami akan mengembang dan meluncurkan Dialog Anda!

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
}


Sepotong kue! Kebebasan kreatif penuh! Pastikan untuk mengikuti Pedoman Materi;)

Saya harap ini membantu seseorang! Biarkan aku tahu apa yang kalian pikirkan!

Studio2bDesain
sumber
2
Hanya ingin tahu mengapa (-1) downvote? Logika yang saya berikan bekerja persis seperti yang dimaksudkan dan seperti yang dijelaskan .. Saya merasa itu adalah tambahan yang bagus untuk posting ini yang belum disebutkan, dan merupakan solusi alternatif yang terdengar sempurna. Namun , jika Anda memiliki alasan yang sah untuk melakukan downvoting terhadap informasi yang saya berikan, akan sedikit lebih membantu jika Anda dapat memberikan beberapa konteks mengapa Anda melakukannya, sehingga saya dan orang lain dapat mempelajari dan memahami alasannya. Downvotes sebenarnya bisa sangat berguna dan bermanfaat dalam proses pembelajaran - tetapi hanya ketika ada konteks di balik alasannya.
Studio2bDesain
4

Ini bekerja untuk saya

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();
    }

Bagaimana cara menelepon? (Nama aktivitas saat ini)

showForgotDialog (current_activity_name.this);

Abdullah Pariyani
sumber