Eingabetextdialog Android

298

Wenn ein Benutzer Buttonin meiner App (die in a gedruckt ist) auf a klickt SurfaceView, möchte ich, dass ein Text Dialogangezeigt wird, und ich möchte das Ergebnis in a speichern String. Ich möchte, dass der Text Dialogden aktuellen Bildschirm überlagert. Wie kann ich das machen?

Luke Taylor
quelle

Antworten:

586

Klingt nach einer guten Gelegenheit, einen AlertDialog zu verwenden .

So einfach es scheint, Android hat keinen eingebauten Dialog, um dies zu tun (soweit ich weiß). Glücklicherweise ist es nur eine kleine zusätzliche Arbeit, zusätzlich zum Erstellen eines Standard-AlertDialogs. Sie müssen lediglich einen EditText erstellen, damit der Benutzer Daten eingeben kann, und ihn als Ansicht des AlertDialogs festlegen. Sie können den zulässigen Eingabetyp bei Bedarf mit setInputType anpassen .

Wenn Sie eine Mitgliedsvariable verwenden können, können Sie die Variable einfach auf den Wert des EditText setzen. Sie bleibt bestehen, nachdem das Dialogfeld geschlossen wurde. Wenn Sie keine Mitgliedsvariable verwenden können, müssen Sie möglicherweise einen Listener verwenden, um den Zeichenfolgenwert an die richtige Stelle zu senden. (Ich kann mehr bearbeiten und ausarbeiten, wenn Sie dies benötigen).

Innerhalb Ihrer Klasse:

private String m_Text = "";

Im OnClickListener Ihrer Schaltfläche (oder in einer von dort aufgerufenen Funktion):

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();
Aaron
quelle
1
Ich habe einen Thread, der ein Bildschirmobjekt ständig aktualisiert und rendert, und ich rufe die Methode builder.show () innerhalb der Aktualisierungsmethode des Bildschirmobjekts auf.
Luke Taylor
1
Oh. Wenn Sie sich in einem Arbeitsthread befinden, versuchen Sie, die Datei builder.show () einzufügen. Aufruf mit runOnUiThread, ähnlich wie in diesem Beispiel: stackoverflow.com/a/3134720/1098302 Oder es ist besser, den gesamten obigen Code (der den AlertDialog erstellt) in eine separate Methode zu setzen und diese Methode aus runOnUiThread heraus aufzurufen.
Aaron
2
Danke dir. Das ist gut. Es gibt jedoch ein kleines Problem. global Context, Context cont;Müssen deklarieren und dann "dies" in alertdialog durch ersetzen cont. Builder für AlertDialog.Builder = neuer AlertDialog.Builder (Forts.); letzte EditText-Eingabe = neuer EditText (Forts.);
8
Ich denke, anstatt eine globale Variable für den Kontext zu erstellen, können Sie den Kontext wie folgt übergeben: "MainActivity.this" (Sie müssen den Text "MainActivity" durch den Namen der Aktivitätsklasse ersetzen, die Sie verwenden möchten).
kunal18
3
Es könnte erwähnenswert sein, dass dies, wie bei den meisten Android-Benutzeroberflächen, alles asynchron ist. Dies bedeutet, dass der Benutzer nicht auf OK tippen muss, es sei denn, Sie haben etwas, das das Tor zum nächsten Schritt macht ...
ewall
101

Ich werde die Antwort von @ Aaron mit einem Ansatz ergänzen , der Ihnen die Möglichkeit gibt, das Dialogfeld besser zu gestalten. Hier ist ein angepasstes Beispiel:

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

Hier ist das Beispiellayout zum Erstellen des EditText-Dialogfelds:

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

Das Endergebnis:

Beispiel für den EditText-Dialog

Michal
quelle
10
Hervorragende Lösung! Ich habe gerade ersetzt getView()mit findViewById(android.R.id.content)und es ist alles wie Charme gearbeitet. Vielen Dank für das Teilen :)
Atul
Denken Sie daran, diese findViewById mit zu besetzen (ViewGroup)!
Martin Erlic
2
"Element AutoCompleteTextView ist hier nicht erlaubt ..."
Jaroslav Záruba
1
@JPerk: android.R.id.content gibt Ihnen das Stammelement einer Ansicht. Siehe dies bitte: stackoverflow.com/a/12887919/1911652
Atul
1
Ich frage mich nur, aber was ist der Wert von @dimen/content_padding_normal?
Edric
62

Wie wäre es mit diesem BEISPIEL ? Es scheint unkompliziert.

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
quelle
3
Ziemlich genau wie bei Aaron, aber kettet den Baumeister an. Eine Frage der persönlichen Präferenz, da beide gut funktionieren.
Scott Biggs
12

Wenn Sie etwas Platz in leftund rightvon der inputAnsicht wünschen , können Sie einige Polster wie hinzufügen

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

dimension.xml

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

Hoffe es hilft

Phan Van Linh
quelle
Was ist resources?
Sebastian Palma
5

Ich fand es sauberer und wiederverwendbarer AlertDialog.Builder, eine benutzerdefinierte Dialogklasse zu erstellen. Dies ist ein Dialogfeld, in dem der Benutzer aufgefordert wird, eine Telefonnummer einzugeben. Eine voreingestellte Telefonnummer kann auch durch Anrufen setNumber()vor dem Anruf angegeben werden 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>

Verwendungszweck:

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.
quelle
4

@LukeTaylor: Ich habe derzeit die gleiche Aufgabe zur Hand (Erstellen eines Popups / Dialogfelds, das einen EditText enthält).
Persönlich finde ich die volldynamische Route in Bezug auf Kreativität etwas einschränkend.

VOLLSTÄNDIG BENUTZERDEFINIERTES DIALOG-LAYOUT:

Anstatt sich beim Erstellen des Dialogs vollständig auf Code zu verlassen, können Sie ihn wie folgt vollständig anpassen:

1) - Erstellen Sie eine neue Layout ResourceDatei. Dies fungiert als Dialog und ermöglicht volle kreative Freiheit!
HINWEIS: Beachten Sie die Richtlinien für das Materialdesign, um die Dinge sauber und auf dem neuesten Stand zu halten.

2) - Geben Sie allen Ihren ViewElementen IDs . In meinem Beispielcode unten habe ich 1 EditTextund 2 Buttons.

3) - Erstellen Sie eine Activitymit aButton, zu Testzwecken .. Wir lassen es aufblasen und starten Ihren Dialog!

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
}


Stück Kuchen! Volle kreative Freiheit! Befolgen Sie unbedingt die Materialrichtlinien;)

Ich hoffe, dies hilft jemandem! Lass mich wissen, was ihr denkt!

Studio2bDesigns
quelle
2
Nur neugierig, warum die (-1) Downvote? Die von mir bereitgestellte Logik funktioniert genau wie beabsichtigt und wie beschrieben. Ich war der Meinung, dass dies eine gute Ergänzung zu diesem Beitrag ist, der noch nicht erwähnt wurde, und eine absolut solide alternative Lösung darstellt. Allerdings , wenn Sie einen berechtigten Grund für die Downvoting Informationen , die ich zur Verfügung gestellt haben, wäre es etwas mehr hilfreich sein , wenn Sie etwas Kontext bitte könnte geben , warum Sie taten, so mich und andere können die Argumentation lernen und verstehen .. downvotes kann tatsächlich sehr sein nützlich und hilfreich im Lernprozess - aber nur, wenn hinter dem Warum ein Kontext steckt.
Studio2bDesigns
4

Es ist Arbeit für mich

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

Wie rufe ich an? (Aktueller Aktivitätsname)

showForgotDialog (aktueller_Aktivitätsname.dies);

Abdullah Pariyani
quelle