2012-06-05 21 views
191

Quando un utente fa clic su unnella mia app (che è stampato in un SurfaceView), desidero visualizzare un testo Dialog e vorrei memorizzare il risultato in un String. Vorrei il testo Dialog per sovrapporre la schermata corrente. Come posso fare questo?Finestra di dialogo testo di input Android

risposta

397

Sembra una buona opportunità per utilizzare un AlertDialog.

Come base, a quanto pare, Android non ha una finestra di dialogo integrata per farlo (per quanto ne so). Fortunatamente, è solo un piccolo lavoro in più per la creazione di un AlertDialog standard. È sufficiente creare un EditText per l'utente per inserire dati e impostarlo come vista di AlertDialog. È possibile personalizzare il tipo di input consentito utilizzando setInputType, se necessario.

Se si è in grado di utilizzare una variabile membro, è possibile semplicemente impostare la variabile sul valore di EditText e verrà mantenuta dopo la chiusura della finestra di dialogo. Se non è possibile utilizzare una variabile membro, potrebbe essere necessario utilizzare un listener per inviare il valore stringa nel posto giusto. (Posso modificare ed elaborare di più se questo è quello che ti serve).

All'interno della vostra classe:

private String m_Text = ""; 

All'interno del OnClickListener del pulsante (o in una funzione chiamata da lì):

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

L'app sembra bloccarsi quando chiamo "builder.show();". Viene visualizzato il seguente messaggio di errore: "Impossibile creare il gestore all'interno del thread che non ha chiamato Looper.prepare();". –

+1

Ho una discussione che aggiorna e rende costantemente un oggetto schermo, e chiamo il metodo builder.show() all'interno del metodo di aggiornamento dell'oggetto schermo. –

+1

Oh. Se ti trovi su un thread di lavoro, prova a inserire builder.show(); chiama con runOnUiThread, simile a questo esempio: http://stackoverflow.com/a/3134720/1098302 O forse sarebbe meglio mettere tutto il codice sopra (che crea AlertDialog) in un metodo separato, e chiamare quel metodo dall'interno di runOnUiThread. – Aaron

53

Che ne dici di questo EXAMPLE? Sembra semplice.

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

Praticamente lo stesso di Aaron, ma incatena il costruttore. La questione delle preferenze personali in quanto entrambe funzionano bene. –

51

vi aggiornerò aggiornamento @Aaron con un approccio che darà hai la possibilità di disegnare il dialogo in un modo migliore. Ecco ad esempio rettificato:

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

Ecco l'esempio di layout che è stato utilizzato per creare dialogo 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> 

Qui potete trovare il risultato:

EditText Dialog example

+6

Soluzione superba! Ho appena sostituito 'getView()' con 'findViewById (android.R.id.content)' e tutto ha funzionato come fascino. Grazie mille per la condivisione :) – Atul

+0

Ricorda di lanciare findViewById con '' (ViewGroup) ''! – santafebound

+0

Se si chiama Inflater con l'ultimo argomento false, perché utilizzare il secondo parametro? Se capisco se è giusto, questo è usato solo se impostato su true. –

Problemi correlati