8

我正在浏览 Google 的关于 Dialogs 的 Android 开发者页面,特别是节。layout_newpayperiod.xml但是,我没有以编程方式创建 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>

当我调用 DialogFragment 时,它会正常显示,并且 Spinner 具有正确的值。我填写了条目并点击“确定”,但是当我尝试从 Spinner 和两个 EditText 字段中检索值时,应用程序会强制以NumberFormatException: Invalid double "". 我觉得我没有正确检索视图。任何人都可以帮我解决这个问题吗?谢谢!

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

}

在 MainActivity.class 中,回调方法:

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

2 回答 2

19

尝试这个:

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

...等(通过以相同方式查询 dialogView 从对话框中检索任何其他视图。)

您的膨胀代码“膨胀”了该视图的全新版本。您想访问在对话框中创建的那个。

于 2013-05-06T22:02:50.977 回答
1

我认为这条线View transactionLayout = View.inflate(this, R.layout.layout_newpayperiod, null); 搞砸了一切。也许它不是乱七八糟的,但是您正在获取新创建的布局的地址并将其分配给transactionLayout参考。然后,您将从该布局EditText paymentEt = (EditText) transactionLayout.findViewById(R.id.edittext_payment);中获得肯定未初始化的视图。它有值空字符串值->“”;

我认为您应该使用 findViewById 来引用您的 EditText,就像使用 TextView 一样。但是由于您处于MainActivitywhich layout 可能不是您的 父视图R.layout.layout_newpayperiod,因此您必须找到一种方法来正确地做到这一点。

你在这个回调方法中有你的DialogFragmentas 参数。onDialogPositiveClick所以你可以获得它View和你正在寻找的布局 - 包含你的 EditText

很抱歉多次编辑这篇文章。

于 2013-05-06T21:45:52.517 回答