0

这是我想做的事情:

1)在Activity一个对话框中显示。我使用DialogFragmentandFragmentManager为此,通过调用:

dialogFragment.show(fragmentManager, "edit_task_list");

2)在里面Dialog我有一个自定义的布局Button。我想在单击按钮时执行一些操作,然后关闭对话框。

我应该如何连接一切?我看到两个选项:

1)onclick中的属性Button和中的方法Actvity。那是我最初的计划,但我不知道如何从中获得Dialog解雇Activity它。即使这不是正确的方法,又怎么能做到呢?我想了解这是如何工作的。

Dialog2)在创建时在按钮上设置单击侦听器DialogFragment。这将需要我将一些上下文从 传递ActivityDialogFragment,所以我想避免它(并保持DialogFragment尽可能简单)。

我应该采取哪些选项?

4

4 回答 4

0

2 号不需要你传递任何上下文(你不应该)。您定义一个接口,该接口可以充当片段和活动之间的契约,并使您的活动实现它。

从您的对话框和 button.onClick() 中,您可以执行以下操作(未经测试的代码):

if ( getActivity() != null 
      && !getActivity().finishing() 
      && getActivity() instanceOf YourInterface) {
   ((YourInterface)getActivity()).onSomeNiceMethod();
   dismiss(); // close the dialog (if this is what you want).
}

界面如下:

public interface YourInterface {
     void onSomeNiceMethod();
}

还有你的活动……</p>

public class YourActivity implements YourInterface {
     void onSomeNiceMethod() {
         // Hey! The Button In The Dialog Has Been Pressed!
     }
}
于 2013-11-02T05:16:47.353 回答
0

1)Button中的onclick属性和Actvity中的方法。那是我最初的计划,但我不知道如何从 Activity 中获取 Dialog 以将其关闭。即使这不是正确的方法,又怎么能做到呢?我想了解这是如何工作的。

基本上,您的 Activity 必须记住/知道当前哪个对话框处于活动状态curDialog=dialogFragment;,然后在处理按钮 onclick 操作时,您将知道要关闭哪个对话框。但这确实不是一个好主意,因为基本上按钮视图会从您的 DialogFragment “泄漏”到您的 Activity,这会破坏对象封装。

2)在DialogFragment中创建Dialog时在按钮上设置点击监听器。这将需要我将一些上下文从 Activity 传递给 DialogFragment,所以我想避免它(并使 DialogFragment 尽可能简单)。

正如前面提到的答案,您不需要将任何 Context 传递给它,特别是因为您可以通过调用getActivity().

解决方案取决于此对话框是否会被多个活动使用:

  1. 由单个活动使用:@Martin 的解决方案可以正常工作
  2. 由多个 Activity 使用:可以使用抽象,以便仅将用户的决定传递给侦听器。这是我针对相同问题提出的(修改后的)解决方案:

    public class BaseDialogFragment extends DialogFragment {
        protected TextView dialogEn;
        protected Button dialogYes;
        private Button dialogNo;
        protected OnSelectListener listener;
    
    public interface OnSelectListener {
        public void onSelect(int type, boolean yes);
    }
    
    public void setOnSelectListener(OnSelectListener listener) {
        this.listener = listener;
    }
    
    public BaseDialogFragment() {
        super();
    }
    
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.dialog_confirm, container, false);
    dialogYes = (Button) v.findViewById(R.id.yes);
    dialogNo = (Button) v.findViewById(R.id.no);
    
    dialogEn = (TextView) view.findViewById(R.id.dialog_en);
    dialogEn.setText(getArguments().getString("text_en"));
    dialogYes.setOnClickListener(this);
    dialogNo.setOnClickListener(this);
    return v;
    }
    
    public void onClick(View v) {
        if (listener != null) {
            listener.onSelect(getArguments().getInt("type"),
                    v == dialogYes ? true : false);
        }
        getDialog().dismiss();
    }
    }
    

要使用它,需要提供一些附加信息:

    Bundle bundle = new Bundle();
    bundle.putInt("type", type); //type: an unique integer value that helps differentiate result from different dialogs
    bundle.putString("text_en", en); //en: String to be displayed
    dialog.setArguments(bundle);
    dialog.setOnSelectListener(this);

因此,如果type上面的值设置为 115,则dialogYes单击按钮将触发public void onSelect(int type, boolean yes)方法以115true作为第一个和第二个参数调用。

于 2013-11-02T10:17:29.537 回答
0

所有 Activity 和 Fragment 类都有一个内置的回调方法供您在启动另一个 Activity、Fragment、Dialog 或 DialogFragment 时使用。

 void onActivityResult(int requestCode, int resultCode, Intent data)

由于要从 Activity 启动 Dialog,因此使用 Dialog 类优于 DialogFragment 类。后者更适合从 Fragment 开始对话,因为它有两种方法可以与 Fragment ( get/set TargetFragment())进行通信

Dialog 类有getOwnerActivity()方法。这是您在使用其构造函数之一创建 Dialog 时使用的 Activity。

您在 Dialog 类中的按钮上设置了 onClickListener。要将结果传递回活动:

getOwnerActivity().onActivityResult(intIdentifyingme, Activity.RESULT_OK,
                    intent);
dismiss();  // close the dialog

您将要发送的其他信息放入 Intent 中。

于 2013-11-02T05:56:49.883 回答
0

应该避免关于 xml 中 onClick 属性的第一点。因为如果您尊重屏幕旋转或具有多个对话框的设置等事件,那么以这种方式处理对话框可能会非常痛苦。这在大多数情况下会导致泄漏的窗口错误,并且需要不必要的代码开销来避免这种情况。因为您必须跟踪实际显示的对话框。为了能够以这种方式关闭对话框,您可以使用您在调用时设置的标签dialogFragment.show(fragmentManager, "edit_task_list");

DialogFragment frag = (DialogFragment)getFragmentManager().findFragmentByTag("edit_task_list");
if(frag != null)
    frag.dismiss();

正确的解决方案是使用接口作为 DialogFragment 和 Activity 之间通信的回调。这使 Dialog 模块化和代码简单。这是文档中的一个示例。为此,您不需要上下文。您只需将接口传递给onAttach()回调中的对话框。它有一个 Activity 的引用作为参数,称为 Dialog。

// Example interface for the communication
public interface OnArticleSelectedListener {
    public void onButtonClicked(/*any Parameters*/);
}

public static class FragmentA extends DialogFragment {
    OnArticleSelectedListener mListener;
    ...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnArticleSelectedListener) activity; // get the interface of the Activity
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() 
                    + " must implement OnArticleSelectedListener");
        }
    }
    ...
}

处理对话框中的按钮单击并在其中调用dismiss(),对话框可以自行关闭。看看这个问题为什么要使用dismiss()而不是getDialog().dismiss()。

yourButton.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v){
        if(mListener != null) // check if the listener is still valid
            mListener.onButtonClicked(...); // calls the Activity implementation of this callback
        dismiss(); // dismiss the Dialog
    }
});

onPause()Dialog 中将接口的引用设置为 null。这样您就可以确保只有在显示对话框时才会使用回调。

您的 Activity 看起来像这样能够处理回调:

public class MyActivity extends Activity implements OnArticleSelectedListener{
    ...
    @Override
    public void onButtonClicked(...){
        // your implementation here
    }
}

我不知道您的整体设置,但是如果您要使用 AlertDialog,则单击按钮会在方法返回时自动关闭对话框。

于 2013-11-02T10:54:05.250 回答