启动对话框以获取结果以将值返回给主要活动

Posted

技术标签:

【中文标题】启动对话框以获取结果以将值返回给主要活动【英文标题】: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;

    

【问题讨论】:

【参考方案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

【讨论】:

这不是答案。

以上是关于启动对话框以获取结果以将值返回给主要活动的主要内容,如果未能解决你的问题,请参考以下文章

从带有结果的对话框或活动中返回

在主线程上启动对话框等待工作线程的结果

Android 你能从链接的 startActivityForResult 中获取活动结果吗

需要帮助以获取访问表单以将值插入查询

js+div 实现弹出搜索对话框,并将选择结果返回给处理方

为啥我在实现委托以将值从子 swift 类传递给父目标 C 类时出错?