【问题标题】:Start Dialog for result to return value to main activity启动对话框以获取结果以将值返回给主要活动
【发布时间】:2013-10-18 06:25:12
【问题描述】:

几个小时以来,我一直在努力解决这个问题。

我有一个主要的 Fragment 类,然后从我从该类中的 ImageView 设置的 onClick 开始,我使用简单的“是”或“取消”选项启动一个对话框片段。

我将如何做到这一点,以便当用户单击“确定”时,它会将结果代码发送回我的主片段,告诉它运行一些代码(在我的情况下,我正在设置墙纸)。

这听起来很简单,但似乎无法弄清楚。提前致谢。

Onclick 我想以某种方式将结果返回到:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    final View v = inflater.inflate(R.layout.image_detail_fragment,
            container, false);

    mImageView = (RecyclingImageView) v.findViewById(R.id.imageView);
    mImageView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            MyDialogFragment dialog = new MyDialogFragment();
            dialog.show(getActivity().getFragmentManager(),
                    "MyDialogFragment");

        }

        public void onDialogOKPressed() {

    ((ImageDetailFragment) (DialogFragment.this.getParentFragment()))
                    .onDialogOKPressed();
            dismiss();

        }
    });

    return v;
}

对话框类:

class MyDialogFragment extends DialogFragment {
    private Button ButtonOk;
    private Button ButtonCancel;

    public MyDialogFragment() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.prompt, container);
        ButtonOk = (Button) view.findViewById(R.id.button1);
        ButtonCancel = (Button) view.findViewById(R.id.button2);
        getDialog().setTitle("Set Wallpaper?");

        ButtonOk.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                                                ((MyDialogFragment)(DialogFragment.this.getActivity())).onDialogOKPressed();
                dismiss();


            }

        });

        ButtonCancel.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                MyDialogFragment.this.dismiss();

            }
        });

        return view;

    }
}

【问题讨论】:

    标签: android dialog fragment


    【解决方案1】:

    在您的活动中,添加一个响应按下的确定按钮的方法,例如public void onDialogOKPressed()。然后,在 DialogFragment 中 OK 按钮的 onClickListener 中,执行以下操作:

    public void onClick(View v){
        ((MyActivity)(DialogFragment.this.getActivity())).onDialogOKPressed();
        dismiss();
    }
    

    或将新方法放入主片段并执行以下操作:

    public void onClick(View v){
        ((MyMainFragment)(DialogFragment.this.getParentFragment())).onDialogOKPressed();
        dismiss();
    }
    

    【讨论】:

    • 那么我将如何获取结果以便主要活动知道是否执行我的代码?那是我的问题:)
    • 这只是在你的活动中调用你的新方法。所以从这个新方法执行你的代码。如果没有按下 OK 按钮,它将不会被调用。使用结果代码摆脱 if/else 块。看来您打算设置墙纸,所以在新方法中设置墙纸。
    • 或者,您可以将新方法放入您的片段中,并将((MyActivity)getActivity()) 替换为((MyFragment)getParentFragment())
    • 我将用什么替换“MyActivty”?
    • 托管片段的活动名称是什么。但实际上,像我上面评论的那样使用你的主要片段类可能更容易,因为这可能是你的大部分壁纸代码所在的地方。所以请使用((MyFragment)getParentFragment()),将 MyFragment 替换为您的主要片段类的名称。
    【解决方案2】:

    我知道这是一个老问题,但接受的答案似乎很可疑;尤其是第一种方法。使用这种方法会在MyDialogFragmentMyActivity 之间引入紧密耦合,基本上违背了使用Fragment 的目的。 Fragment 应该只知道它附加到 Activity,而不知道它是什么类型的 Activity

    虽然第二种方法不如不好,但考虑到您的Activity 已经知道它将使用哪种Fragment,我仍然认为使用interface 有更好的方法:

    public class MyDialogFragment extends DialogFragment {
    
        public interface OnOkButtonClickListener {
            void onOkButtonClick();
        }
    
        private OnOkButtonClickListener mOnOkButtonClickListener;
    
        private Button mOkButton;
        private Button mCancelButton;
    
        public static MyDialogFragment newInstance() {
            return new MyDialogFragment();
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
    
            if(context instanceof OnOkButtonClickListener) {
                mOnOkButtonClickListener = (OnOkButtonClickListener) context;
            }
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.prompt, container, false);
            getDialog().setTitle("Set Wallpaper?");
    
            mOkButton = (Button) view.findViewById(R.id.button1);
            mCancelButton = (Button) view.findViewById(R.id.button2);
    
            mOkButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(mOnOkButtonClickListener != null) {
                        mOnOkButtonClickListener.onOkButtonClick();
                    }
                }
            };
    
            mCancelButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    MyDialogFragment.this.dismiss();
                }
            };
        }
    
    }
    

    然后你可以在任何Activity中实现interface

    public class MyActivity extends AppCompatActivity
            implements MyDialogFragment.OnOkButtonClickListener {
    
    
        @Override
        public void onOkButtonClick() {
            // TODO: handle dialog click
        }
    
        // ...
    
    }
    

    这也是与developer training site 上的Fragment 通信的推荐方法。

    【讨论】:

      【解决方案3】:

      您可以尝试使用 Otto(或 EventBus)通过“事件”从对话框向 MainActivity 发送事件 奥托:http://square.github.io/otto/ 事件总线:https://github.com/greenrobot/EventBus

      【讨论】:

      • 这不是答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      相关资源
      最近更新 更多