从 DialogFragment 获取值

22
我希望DialogFragment在关闭时将输入到editQuantity的值返回给我。但是我没有找到方法使其起作用。我可以通过通过intent传递该值来完成此操作,但这会破坏当前活动的进程。是否有其他方式可以返回值,而不是通过intent传递?
package com.example.myprojectname;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.text.InputType;
import android.util.Log;
import android.widget.EditText;

public class QuantityDialogFragment extends DialogFragment implements OnClickListener { 


    private EditText editQuantity;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        editQuantity = new EditText(getActivity());
        editQuantity.setInputType(InputType.TYPE_CLASS_NUMBER);

        return new AlertDialog.Builder(getActivity())
        .setTitle(R.string.app_name)
        .setMessage("Please Enter Quantity")
        .setPositiveButton("OK", this)
        .setNegativeButton("CANCEL", null)
        .setView(editQuantity)
        .create();

    }

    @Override
    public void onClick(DialogInterface dialog, int position) {
        String value = editQuantity.getText().toString();
        Log.d("Quantity: ", value);
        dialog.dismiss();       
    }
}

你想将输入的值传递给你的活动吗? - Anis BEN NSIR
2个回答

50

假设你想要将结果转发给调用Activity:)尝试使用这段代码片段:

public class QuantityDialogFragment extends DialogFragment implements OnClickListener {

    private EditText editQuantity;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        editQuantity = new EditText(getActivity());
        editQuantity.setInputType(InputType.TYPE_CLASS_NUMBER);

        return new AlertDialog.Builder(getActivity()).setTitle(R.string.app_name).setMessage("Please Enter Quantity")
                .setPositiveButton("OK", this).setNegativeButton("CANCEL", null).setView(editQuantity).create();

    }

    @Override
    public void onClick(DialogInterface dialog, int position) {
        String value = editQuantity.getText().toString();
        Log.d("Quantity: ", value);
        MainActivity callingActivity = (MainActivity) getActivity();
        callingActivity.onUserSelectValue(value);
        dialog.dismiss();
    }
}

并且在您的活动中添加:

public class MainActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        QuantityDialogFragment dialog = new QuantityDialogFragment();
        dialog.show(getSupportFragmentManager(), "Dialog");
    }

    /**
     * callback method from QuantityDialogFragment, returning the value of user
     * input.
     * 
     * @param selectedValue
     */
    public void onUserSelectValue(String selectedValue) {
        // TODO add your implementation.
    }
}

1
这只是一个例子,取决于您需要同步/异步的活动响应,对于异步,您可以使用本地广播接收器。 对于同步实现,我认为这是最好的选择。 这可以通过一个公共接口进行优化... - Anis BEN NSIR
1
我在将getActivity()的结果转换为适当的活动时并没有太大的成功。如果我想要将对话框重用于多个活动,我可以通过实现简单的setListener(接口名称)方法来避免出现ClassCastException。 - Someone Somewhere
1
@SomeoneSomewhere,是的,你可以添加Listener,就像我之前的评论中提到的那样。你必须确保在Dialog类中将Listener移除并将其设置为null,以避免由于循环引用而导致的内存泄漏问题。 - Anis BEN NSIR
1
@reegan29,这个解决方案很好用啊,你有什么问题吗?从答案中我看不到任何setText或getText!!! - Anis BEN NSIR
1
@reegan29 在安卓上我们从来不会实例化Activity,所以也永远不会见到new MainActivity()!!! 很抱歉我不能提供定制支持。谢谢。 - Anis BEN NSIR
显示剩余9条评论

4

进一步实现这个想法,我在对话框中创建了一个监听器接口,并在主活动中实现了它。

public interface OnDialogResultListener {
    public abstract void onPositiveResult(String value);
    public abstract void onNegativeResult();
}

public void setOnDialogResultListener(OnDialogResultListener listener) {
    this.onDialogResultListener = listener;
}

在覆盖的onCancel(DialogInterface)onPositiveResult(String)中调用onNegativeResult(),在您想要对话框返回值的位置。

注意:在调用onPositiveResult()后不要忘记dismiss()对话框,否则对话框窗口将保持打开状态。

然后,在您的主活动中,您可以创建一个对话框监听器,如下所示:

QuantityDialogFragment dialog = new QuantityDialogFragment();
dialog.setOnDialogResultListener(new QuantityDialogFragment.OnDialogResultListener() {
        @Override
        public void onPositiveResult(String value) {
            //Do something...
        }

        @Override
        public void onNegativeResult() {
            //Do something...
        }
    });

这将会使你的对话框更易于以后重复使用。

9
这种方法并非总是有效的 - 如果屏幕旋转,活动和对话框片段都将被重新创建。但是它们之间不再连接,因为“显示对话框”代码没有重新执行以设置监听器... - Scott Stanchfield
是的,这是真的,有人能提供一个带有回调到主活动的DialogFragment的示例吗? - mparkes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接