2013-05-06 3 views
7

Sto passando attraverso la pagina degli sviluppatori Android di Google su Dialogs, in particolare la sezione this. Tuttavia, invece di creare il messaggio del DialogFragment a livello di codice, ho fatto un layout pre-impostato di nome layout_newpayperiod.xml con i seguenti elementi:Recupero del valore da EditText in DialogFragment

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 

<Spinner 
    android:id="@+id/spinner_payperiod" 
    android:layout_width="fill_parent" 
    android:layout_height="48dp" 
    android:padding="8dp" 
    android:entries="@array/pay_periods" 
    /> 

<EditText 
    android:id="@+id/edittext_savepercent" 
    android:layout_width="fill_parent" 
    android:layout_height="48dp" 
    android:padding="8dp" 
    android:inputType="number" 
    android:hint="Percent to Save" 
    /> 

<EditText 
    android:id="@+id/edittext_payment" 
    android:layout_width="fill_parent" 
    android:layout_height="48dp" 
    android:padding="8dp" 
    android:inputType="numberDecimal" 
    android:hint="Total Payment" 
    /> 

</LinearLayout> 

Quando chiamo il DialogFragment si presenta come di consueto, con la Spinner avere i valori corretti. Ho compilato le voci e ho premuto "OK", ma quando provo a recuperare i valori dallo Spinner e due campi EditText, l'applicazione si chiude con uno NumberFormatException: Invalid double "". Ho la sensazione che non sto recuperando le viste correttamente. Qualcuno può aiutarmi a capirlo per favore? Grazie!

public class StartPayperiodDialogFragment extends DialogFragment { 

/* The activity that creates an instance of this dialog fragment must 
* implement this interface in order to receive event callbacks. 
* Each method passees the DialogFragment in case the host needs to query it. 
*/ 
public interface StartPayperiodDialogListener{ 
    public void onDialogPositiveClick(DialogFragment dialog); 
    public void onDialogNegativeClick(DialogFragment dialog); 
} 

// Use this instance of the interface to deliver action events 
StartPayperiodDialogListener listener; 

// Override the Fragment.onAttach() method to instantiate the StartPayperiodDialogListener 
@Override 
public void onAttach(Activity activity){ 
    super.onAttach(activity); 
    // Verify that the host activity implements the callback interface 
    try{ 
     // Instantiate the NoticeDialogListener so we can send events to the host 
     listener = (StartPayperiodDialogListener) activity; 
    }catch(ClassCastException e){ 
     // The activity doesn't implement the interface, throw exception 
     throw new ClassCastException(activity.toString() + " must implement StartPayperiodDialogListener"); 
    } 
} 

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState){ 
    // Use the Builder class for convenient dialog construction 
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
    View transactionLayout = View.inflate(getActivity(), R.layout.layout_newpayperiod, null); 
    builder.setView(transactionLayout) 
    .setPositiveButton("OK", new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      // Send the positive button event back to the calling activity 
      listener.onDialogPositiveClick(StartPayperiodDialogFragment.this); 
     } 
    }) 
    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      // Send the negative button event back to the calling activity 
      listener.onDialogNegativeClick(StartPayperiodDialogFragment.this); 
     } 
    }); 
    return builder.create(); 
} 

}

Nel MainActivity.class, il metodo di callback:

@Override 
public void onDialogPositiveClick(DialogFragment dialog) { 
    // User pressed OK, so we need to grab the values from the 
    // dialog's fields and apply them to the Views in the Main 
    // Activity 

    View transactionLayout = View.inflate(this, R.layout.layout_newpayperiod, null); 

    // Start with the payment amount 
    EditText paymentEt = (EditText) transactionLayout.findViewById(R.id.edittext_payment); 
    TextView paymentTv = (TextView) findViewById(R.id.text_paycheck); 
    paymentTv.setText(moneyFormat.format(Double.parseDouble(paymentEt.getText().toString()))); 

    // Next, the percent to save 
    EditText savingsEt = (EditText) transactionLayout.findViewById(R.id.edittext_savepercent); 
    TextView savingsTv = (TextView) findViewById(R.id.text_savings); 
    savingsTv.setText(savingsEt.getText().toString() + "%"); 

    // Then, the pay period 
    Spinner periodSp = (Spinner) transactionLayout.findViewById(R.id.spinner_payperiod); 
    TextView periodTv = (TextView) findViewById(R.id.text_payperiod); 
    periodTv.setText(periodSp.getSelectedItem().toString()); 

    // Finally, let's update the daily allowance amount and clear 
    // the adapter 
    adapter.clear(); 
    adapter.notifyDataSetChanged(); 
    TextView allowanceTv = (TextView) findViewById(R.id.text_allowance); 
    Double allowanceValue; 
    switch(periodSp.getSelectedItemPosition()){ 
     case(0): // Daily 
      allowanceValue = Double.parseDouble(paymentTv.getText().toString()); 
      break; 
     case(1): // Weekly 
      allowanceValue = Double.parseDouble(paymentTv.getText().toString())/7; 
      break; 
     case(2): // 2 Weeks 
      allowanceValue = Double.parseDouble(paymentTv.getText().toString())/14; 
      break; 
     case(3): // 30 Days 
      allowanceValue = Double.parseDouble(paymentTv.getText().toString())/30; 
      break; 
     default: // Debugging purposes only 
      allowanceValue = 42.0; 
      break; 
    } 
    allowanceTv.setText(Double.toString(allowanceValue)); 
} 

risposta

18

Prova questo:

@Override 
public void onDialogPositiveClick(DialogFragment dialog) { 
    // User pressed OK, so we need to grab the values from the 
    // dialog's fields and apply them to the Views in the Main 
    // Activity 

    // Start with the payment amount 
    Dialog dialogView = dialog.getDialog(); 
    EditText paymentEt = (EditText) dialogView.findViewById(R.id.edittext_payment); 

... ecc (richiamare nessun altro vista dalla finestra di dialogo interrogando la dialogView nello stesso modo.)

Il codice gonfiare "gonfia" un nuovo marchio versione di quella vista. Si desidera accedere a quello che è stato creato nella finestra di dialogo.

+0

Ho dato un colpo, ma sto ricevendo un NullPointerException sulla finestra di dialogo EditText paymentEt = (EditText) View.findViewById (R.id.edittext_payment); Sospetto che la chiamata a dialog.getView() non stia facendo quello che ci aspettiamo ... – Argus9

+1

@ Argus9 sei corretto. Quello sarebbe l'uso corretto per un normale frammento, ma per un DialogFragment, devi usare getDialog(). Ho modificato la mia risposta per riflettere. –

+0

Risposta geniale assoluta, grazie Jay! – Argus9

1

Penso che questa linea View transactionLayout = View.inflate(this, R.layout.layout_newpayperiod, null); scombina tutto. Forse non è un problema, ma stai ricevendo l'indirizzo del layout appena creato e assegnalo al riferimento transactionLayout. Quindi stai ricevendo Views da quel layout EditText paymentEt = (EditText) transactionLayout.findViewById(R.id.edittext_payment); che sono certamente non inizializzate. Ha valore valore stringa vuoto -> "";

Penso che dovresti usare findViewById per ottenere riferimenti ai tuoi EditText come con i tuoi TextView. Ma dal momento che ci si trova nel proprio MainActivity, quale layout non è probabilmente una vista genitore sul proprio R.layout.layout_newpayperiod, è necessario trovare un modo per farlo correttamente.

Hai il tuo DialogFragment come parametro in questo metodo di richiamata onDialogPositiveClick. Quindi puoi ottenerlo dal View e dal layout che stai cercando - che contiene il tuo EditText's

Ci scusiamo per aver modificato questo post tante volte.

+0

Penso che l'unica ragione per cui ho scelto di non farlo è che quando si utilizza findViewById come ho fatto con TextView, ho ottenuto NullPointerException. È come se gli elementi esistessero in R.id, ma l'applicazione non può trovarli in fase di runtime. Ci proverò di nuovo e vedrò se è d'aiuto. – Argus9

+0

Oh, anche - le TextViews sono presenti nel file XML di layout di MainActivity, chiamato in SetContentView() nel metodo onCreate() di Activity. – Argus9

+0

Ottieni riferimenti Null perché queste viste non sono correlate l'una con l'altra. Controlla la risposta di Jay Bobzin che dovrebbe risolvere il tuo problema – Garet