2013-05-06 17 views
7

Ich gehe durch Googles Android Developer Seite auf Dialoge, speziell this Abschnitt. Doch statt dem DialogFragment der Nachricht programmatisch zu schaffen, machte ich eine voreingestellte Layout layout_newpayperiod.xml mit den folgenden Elementen benannt:Abrufen von Wert von 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> 

Als ich die DialogFragment nenne es zeigt mich als normal, mit den Spinnern die richtigen Werte aufweisen. Ich füllte die Einträge aus und drückte auf "OK", aber wenn ich versuche, die Werte aus dem Spinner- und zwei EditText-Feldern abzurufen, wird die App mit einem NumberFormatException: Invalid double "" geschlossen. Ich habe das Gefühl, dass ich die Ansichten nicht richtig abrufe. Kann mir bitte jemand helfen? Vielen Dank!

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

}

In MainActivity.class, die Callback-Methode:

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

Antwort

18

Try this:

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

... etc. (Abrufen alle anderen Ansichten aus dem Dialog mit den dialogView in der gleichen Art und Weise abfragt.)

Ihr aufblasen Code "aufbläst" ein brandneues Version dieser Ansicht. Sie möchten auf den Dialog zugreifen, der im Dialog erstellt wurde.

+0

Ich habe es versucht, aber ich bekomme eine NullPointerException für die 'EditText payageEt = (EditText) dialogView.findViewById (R.id.edittext_payment); Ich vermute, dass der Aufruf von dialog.getView() nicht das tut, was wir erwarten ... – Argus9

+1

@ Argus9 Sie sind richtig. Das wäre die richtige Verwendung für ein normales Fragment, aber für ein DialogFragment müssen Sie getDialog() verwenden. Ich habe meine Antwort bearbeitet, um sie zu reflektieren. –

+0

Absolut geniale Antwort, danke Jay! – Argus9

1

Ich denke, dass diese Linie View transactionLayout = View.inflate(this, R.layout.layout_newpayperiod, null); alles vermasselt. Vielleicht ist es nicht verwirrend, aber Sie erhalten die Adresse des frisch erstellten Layouts und weisen es der transactionLayout Referenz zu. Dann erhalten Sie Ansichten von diesem Layout EditText paymentEt = (EditText) transactionLayout.findViewById(R.id.edittext_payment);, die sicherlich nicht initialisiert sind. Es hat einen Wert leerer String-Wert -> "";

Ich denke, Sie sollten findViewById verwenden, um Bezug auf Ihre EditText zu erhalten, wie Sie es mit Ihren TextViews machen. Aber wie Sie in Ihrem MainActivity sind, welches Layout wahrscheinlich keine Elternansicht zu Ihrem R.layout.layout_newpayperiod ist, müssen Sie einen Weg finden, das richtig zu tun.

Sie haben Ihre DialogFragment als Parameter in dieser onDialogPositiveClick Callback-Methode bekommen. So können Sie es erhalten View und das Layout, das Sie suchen - das enthält Ihre EditText

Entschuldigung für die Bearbeitung dieses Beitrags so oft.

+0

Ich denke, der einzige Grund, warum ich dies nicht getan habe, ist, weil bei der Verwendung von findViewById, wie ich mit den TextViews getan habe, ich eine NullPointerException. Es ist, als ob die Elemente in R.id existieren, aber die App kann sie zur Laufzeit nicht finden. Ich werde es nochmal versuchen und sehen, ob es hilft. – Argus9

+0

Oh, auch - die TextViews sind in der Layout-XML-Datei von MainActivity vorhanden, die in SetContentView() in der onCreate() -Methode der Aktivität aufgerufen wird. – Argus9

+0

Sie erhalten Nullreferenzen, da diese Ansichten nicht miteinander verwandt sind. Sehen Sie sich Jay Bobzin's Antwort an, die Ihr Problem lösen sollte: – Garet

Verwandte Themen