以下是我想做的事情:
1)在Activity
内部显示一个对话框。我通过调用:
DialogFragment
和FragmentManager
dialogFragment.show(fragmentManager, "edit_task_list");
2)Dialog
内部我有自定义Button
的布局。我想在单击按钮后执行某些操作,然后关闭对话框。
我应该如何连接所有东西?我看到两个选择:
1)onclick
中的Button
属性和Actvity
内的方法。这是我最初的计划,但我不知道如何从Dialog
获取Activity
来解雇它。即使这不是正确的方法,怎么办呢?我想了解这是如何运作的。
2)在Dialog
中创建DialogFragment
时,在按钮上设置点击监听器。这需要我将一些上下文从Activity
传递到DialogFragment
,因此我希望避免它(并尽可能简化DialogFragment
)。
我应该选择哪些选项?
答案 0 :(得分:0)
Number 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();
}
你的活动......
public class YourActivity implements YourInterface {
void onSomeNiceMethod() {
// Hey! The Button In The Dialog Has Been Pressed!
}
}
答案 1 :(得分: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。将结果传递回Activity:
getOwnerActivity().onActivityResult(intIdentifyingme, Activity.RESULT_OK,
intent);
dismiss(); // close the dialog
您要在意图中添加要发送的其他信息。
答案 2 :(得分:0)
1)按钮中的onclick属性和Actvity内的方法。 这是我最初的计划,但我不知道如何从中获取Dialog 解雇它的活动。即使这不是正确的方法,怎么可能 这样做了吗?我想了解这是如何运作的。
基本上,您的活动必须记住/知道当前哪个对话框处于活动状态curDialog=dialogFragment;
,然后在处理按钮onclick操作时,您将知道要关闭哪个对话框。但这确实不是一个好主意,因为基本上Button View会从您的DialogFragment“泄漏”到您的Activity,这会破坏对象封装。
2)在创建对话框时设置按钮上的单击侦听器 DialogFragment。这将要求我传递一些上下文 对DialogFragment的活动,所以我想避免它(并保持 DialogFragment尽可能简单。)
如上所述,您不需要向其传递任何上下文,特别是因为您可以通过调用getActivity()
来获取活动。
解决方案取决于多个活动是否会使用此对话框:
由多个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)
方法,115
和true
作为第一&第二个参数。
答案 3 :(得分:0)
应该避免关于xml中的onClick属性的第一点。因为如果您尊重屏幕旋转或具有多个对话框的设置等事件,那么以这种方式处理Dialog可能会非常痛苦。这在大多数情况下导致泄露的窗口错误,并且需要不必要的代码开销来避免这种情况。因为您必须跟踪实际显示的对话框。
为了能够以这种方式关闭对话框,您可以使用您在调用时设置的标记dialogFragment.show(fragmentManager, "edit_task_list");
DialogFragment frag = (DialogFragment)getFragmentManager().findFragmentByTag("edit_task_list");
if(frag != null)
frag.dismiss();
正确的解决方案是使用接口作为DialogFragment和Activity之间通信的回调。这使得Dialog模块化和代码变得容易。以下是docs的示例。为此,您不需要上下文。您只需将界面传递给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");
}
}
...
}
在Dialog中单击Button按钮并调用其中的dismiss(),Dialog可以自行解除。看看这个question为什么要使用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
}
});
在Dialog的onPause()
中,将接口的引用设置为null。这样,您可以确保仅在显示对话框时才使用回调。
您的活动看起来像这样能够处理回调:
public class MyActivity extends Activity implements OnArticleSelectedListener{
...
@Override
public void onButtonClicked(...){
// your implementation here
}
}
我不知道您的整体设置,但如果您使用AlertDialog,则单击按钮会在方法返回时自动关闭对话框。