2012-06-05 26 views
191

Wenn ein Benutzer eine Button in meiner App klickt (die in einem SurfaceView gedruckt wird), würde ich einen Text wie Dialog zu erscheinen, und ich möchte das Ergebnis in einem String speichern. Ich möchte, dass der Text Dialog den aktuellen Bildschirm überlagert. Wie kann ich das machen?Texteingabe-Dialog Android

Antwort

397

Klingt wie eine gute Gelegenheit, eine AlertDialog zu verwenden.

So einfach wie es scheint, Android hat keinen eingebauten Dialog, um dies zu tun (soweit ich weiß). Zum Glück ist es nur ein kleiner zusätzlicher Aufwand, um einen Standard-AlertDialog zu erstellen. Sie müssen lediglich einen EditText erstellen, damit der Benutzer Daten eingeben kann, und ihn als Ansicht des AlertDialogs festlegen. Sie können den Typ der zulässigen Eingabe anpassen, indem Sie setInputType verwenden, wenn Sie benötigen.

Wenn Sie eine Elementvariable verwenden können, können Sie die Variable einfach auf den Wert des EditText setzen, und sie wird beibehalten, nachdem das Dialogfeld geschlossen wurde. Wenn Sie eine Elementvariable nicht 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 weiter entwickeln, wenn Sie das brauchen).

Innerhalb Ihrer Klasse:

private String m_Text = ""; 

Im OnClickListener Ihrer Taste (oder in Abhängigkeit von dort genannt):

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

Die App scheint abstürzen, wenn ich "builder.show();" aufrufen. Ich erhalte die folgende Fehlermeldung: "Kann den Handler innerhalb des Threads nicht erstellen, der Looper.prepare() nicht aufgerufen hat;". –

+1

Ich habe einen Thread, der ein Bildschirmobjekt ständig aktualisiert und rendert, und ich rufe die Methode builder.show() innerhalb der Update-Methode des Bildschirmobjekts auf. –

+1

Oh. Wenn Sie sich in einem Worker-Thread befinden, versuchen Sie, die Datei builder.show(); Rufen Sie mit runOnUiThread auf, ähnlich wie in diesem Beispiel: http://StackOverflow.com/a/3134720/1098302 Oder vielleicht wäre es besser, den gesamten obigen Code (der den AlertDialog erstellt) in eine separate Methode zu schreiben und diese Methode aufzurufen aus runOnUiThread. – Aaron

53

Wie wäre es mit EXAMPLE? Es scheint einfach zu sein.

+3

Pretty much das gleiche wie Aarons, aber kettet den Baumeister. Angelegenheit der persönlichen Vorliebe, da beide gut funktionieren. –

51

I @Aaron Update mit einem Ansatz aktualisieren wird das gibt Sie haben die Möglichkeit, den Dialog besser zu gestalten. Hier ist das Adjusted 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 wird das Beispiel des Layouts, der verwendet wurde EditText Dialog zu erstellen:

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

Hier können Sie das Ergebnis finden:

EditText Dialog example

+6

Hervorragende Lösung! Ich habe 'getView()' nur durch 'findViewById (android.R.id.content)' ersetzt und alles hat wie Charme funktioniert. Vielen Dank für das Teilen :) – Atul

+0

Denken Sie daran, dass findViewById mit '' (ViewGroup) ''! – santafebound

+0

Wenn Sie den Inflater mit dem letzten Argument false aufrufen, warum den zweiten Parameter verwenden? Wenn ich richtig verstehe, wird dies nur verwendet, wenn es auf "True" gesetzt ist. –

Verwandte Themen