Діалогове вікно введення тексту Android


298

Коли користувач натискає на Buttonмоє додаток (яке надруковано в SurfaceView), я хотів би, щоб текст Dialogз’явився, і я хотів би зберегти результат у String. Я хотів би, щоб текст Dialogнаклав поточний екран. Як я можу це зробити?

Відповіді:


585

Здається, гарна можливість використовувати AlertDialog .

Настільки ж базовим, як здається, Android не має вбудованого діалогу для цього (наскільки я знаю). На щастя, це лише трохи додаткової роботи над створенням стандартного AlertDialog. Вам просто потрібно створити EditText для користувача для введення даних та встановити його як перегляд AlertDialog. Ви можете налаштувати тип вводу, дозволений за допомогою setInputType , якщо вам потрібно.

Якщо ви можете використовувати змінну члена, ви можете просто встановити цю змінну значення EditText, і вона збережеться після відключення діалогу. Якщо ви не можете використовувати змінну члена, вам може знадобитися використати слухач, щоб надіслати значення рядка в потрібне місце. (Я можу відредагувати та розробити більше, якщо це те, що вам потрібно).

В межах вашого класу:

private String m_Text = "";

У OnClickListener вашої кнопки (або у функції, викликаної звідти):

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
У мене є потік, який постійно оновлює і рендерує екранний об’єкт, і я викликаю метод builder.show () в методі оновлення об’єкта екрана.
Люк Тейлор

1
Ой. Якщо у вас є робоча нитка, спробуйте помістити builder.show (); зателефонуйте за допомогою runOnUiThread, схожий на цей приклад: stackoverflow.com/a/3134720/1098302 Або, можливо, було б краще поставити весь код вище (що створює AlertDialog) в окремий метод, а цей метод викликати з runOnUiThread.
Аарон

2
Дякую. Добре. Ховервер, є невелика проблема. Потрібно оголосити, global Context, Context cont;а потім замінити "це" в alerdialog на cont. AlertDialog.Builder builder = новий AlertDialog.Builder (продовження); остаточний вхід EditText = новий EditText (продовження);

8
Я думаю, що замість створення глобальної змінної для контексту, ви можете передавати контекст на зразок: "MainActivity.this" (вам потрібно замінити текст "MainActivity" на ім'я класу діяльності, яке ви хочете використовувати).
kunal18

3
Можливо, варто зауважити, що, як і більшість інтерфейсів Android, це все асинхронно ... це означає, що користувач не чекатиме, коли користувач
натисне кнопку

101

Я додам до відповіді @ Аарона з підходом, який дає вам можливість краще стилізувати діалогове вікно. Ось налагоджений приклад:

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:

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

Кінцевий результат:

Приклад діалогового вікна EditText


10
Чудове рішення! Я просто замінити getView()з , findViewById(android.R.id.content)і це все працювало як шарм. Дякую за те, що поділилися :)
Atul

Не забудьте віддати цей findViewById (ViewGroup)!
Мартін Ерлік

2
"Element AutoCompleteTextView тут не дозволений ..."
Ярослав Заруба,

1
@JPerk: android.R.id.content дає вам кореневий елемент подання. Посилайтеся на це, будь ласка: stackoverflow.com/a/12887919/1911652
Atul

1
Просто цікаво, але в чому цінність @dimen/content_padding_normal?
Едрік

62

Як щодо цього ПРИКЛАДУ ? Це здається прямолінійним.

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
Приблизно те саме, що і Аарона, але прикував будівельника. Питання особистих уподобань, оскільки обидва працюють добре.
Скотт Біггс

12

Якщо ви хочете трохи місця leftі rightдля inputперегляду, ви можете додати трохи накладок

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>

Сподіваюся, це допоможе



5

Я вважаю більш чистим і багаторазовим використання розширення AlertDialog.Builderдля створення спеціального діалогового класу. Це діалогове вікно, в якому користувач просить ввести номер телефону. Заздалегідь заданий номер телефону також можна надати, зателефонувавши setNumber()перед дзвінками 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>

Використання:

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: На даний момент у мене є те саме завдання (створення спливаючого вікна / діалогового вікна, що містить EditText).
Особисто я вважаю, що повністю динамічний маршрут дещо обмежує з точки зору творчості.

ПОЛЬНО МИТНИЙ ДІАЛОГ РОЗВИТКУ:

Замість того, щоб повністю покластись на код для створення діалогового вікна, ви можете повністю його налаштувати так:

1) - Створіть новий Layout Resourceфайл .. Це буде діяти як ваш діалог, дозволяючи отримати повну творчу свободу!
ПРИМІТКА. Дотримуйтесь інструкцій з дизайну матеріалів, щоб допомогти зберегти чистоту та стан справ.

2) - Дайте ідентифікатор усім своїм Viewелементам. У моєму прикладі коду нижче, у мене є 1 EditTextі 2 Buttons.

3) - СтворітьActivity допомогою аButton, для цілей тестування. Ми будемо надувати і запускати ваш діалог!

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
}


Шматок торту! Повна творча свобода! Просто не забудьте дотримуватися Матеріальних вказівок;)

Я сподіваюся, що це комусь допоможе! Дайте мені знати, що ви думаєте, хлопці!


2
Тільки цікаво, чому (-1) потік? Логіка, яку я надав, працює точно так, як задумано і як описано. Я вважав, що це гарне доповнення до цієї публікації, про яке ще не було сказано, і є ідеально здоровим альтернативним рішенням. Однак якщо у вас є законні причини відмови від наданої мною інформації, було б трохи корисніше, якщо ви можете, будь ласка, надати певний контекст, чому ви це зробили, щоб я та інші могли вивчити та зрозуміти міркування. корисний і корисний у процесі навчання - але лише тоді, коли є контекст, за яким.
Studio2bDesigns

4

Це для мене робота

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

Як зателефонувати? (Поточна назва діяльності)

showForgotDialog (current_activity_name.this);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.