对取向变化DialogFragment回调(DialogFragment callback on o

2019-08-01 07:32发布

我在我的迁移对话,目前使用Activity.showDialog(DIALOG_ID); ,使用DialogFragment系统如所讨论的机器人参考 。

有使用回调时提供一些事件回活动/片段打开的对话框我的发展过程中产生了一个问题:

这里有一个简单的对话框的一些示例代码:

public class DialogTest extends DialogFragment {

public interface DialogTestListener {
    public void onDialogPositiveClick(DialogFragment dialog);
}

// Use this instance of the interface to deliver action events
static DialogTestListener mListener;

public static DialogTest newInstance(Activity activity, int titleId, int messageId) {
    udateListener(activity);
    DialogTest frag = new DialogTest();
    Bundle args = new Bundle();
    args.putInt("titleId", titleId);
    args.putInt("messageId", messageId);
    frag.setArguments(args);
    return frag;
}

public static void udateListener(Activity activity) {
    try {
        // Instantiate the NoticeDialogListener so we can send events with it
        mListener = (DialogTestListener) activity;
    } catch (ClassCastException e) {
        // The activity doesn't implement the interface, throw exception
        throw new ClassCastException(activity.toString() + " must implement DialogTestListener");
    }
}


@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    int titleId = getArguments().getInt("titleId");
    int messageId = getArguments().getInt("messageId");

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // dialog title
    builder.setTitle(titleId);
    // dialog message
    builder.setMessage(messageId);

    // dialog negative button
    builder.setNegativeButton("No", new OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {}});
    // dialog positive button
    builder.setPositiveButton("Yes", new OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            mListener.onDialogPositiveClick(DialogTest.this);
        }});

    // create the Dialog object and return it
    return builder.create();
}}

下面是一些活动代码调用它:

public class SomeActivity extends FragmentActivity implements DialogTestListener {
private EditText mUserName;
@Override
public void onCreate(Bundle savedInstanceState) {
    // setup ui
    super.onCreate(savedInstanceState);
    setContentView(R.layout.ui_user_edit);
    // name input
    mUserName = (EditText) findViewById(R.id.userEdit_editTextName);
}

@Override
public void onDialogPositiveClick(DialogFragment dialog) {
    Log.d(TAG, this.toString());
    mUserName.setText(mUserName.getText() + "1");
}

private void showDialog() {
    DialogTest test = DialogTest.newInstance(SomeActivity.this, R.string.someTitleText, R.string.someMessageText);
    test.show(getSupportFragmentManager(), "testDialog");
}}

该代码是几乎你所看到的参考。 问题是,一旦你做了改变方向的时候会出现一个对话框,它停止工作正常 - >由于活动的生命周期,两者的活动和对话的重建,以及对话框现在没有合适的参照新的重建活动。

我下面的代码添加到我的activitys的onResume方法:

    @Override
protected void onResume() {
    super.onResume();
    DialogTest.udateListener(this);
}

这样做,我得到预期的行为,并在对话框发送事件回新改建活动时的方向发生变化。

我的问题是:什么是“最佳实践”来处理这是由FragmentActivity的方向变化时打开DialogFragment的回调?

最好的祝福

Answer 1:

是啊,这是我在所有的时间下降我是一个常见的陷阱。 首先让我说,你打电话的解决方案DialogTest.udateListener()onResume()似乎是完全适当的给我。

另一种方法是使用一个ResultReceiver可序列化作为Parcelable

public class DialogTest extends DialogFragment {

public static DialogTest newInstance(ResultReceiver receiver, int titleId, int messageId) {
    DialogTest frag = new DialogTest();
    Bundle args = new Bundle();
    args.putParcelable("receiver", receiver);
    args.putInt("titleId", titleId);
    args.putInt("messageId", messageId);
    frag.setArguments(args);
    return frag;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    int titleId = getArguments().getInt("titleId");
    int messageId = getArguments().getInt("messageId");
    ResultReceiver receiver = getArguments().getParcelable("receiver");

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // dialog title
    builder.setTitle(titleId);
    // dialog message
    builder.setMessage(messageId);

    // dialog negative button
    builder.setNegativeButton("No", new OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            receiver.sendResult(Activity.RESULT_CANCEL, null);
        }});
    // dialog positive button
    builder.setPositiveButton("Yes", new OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            receiver.sendResult(Activity.RESULT_OK, null);
        }});

    // create the Dialog object and return it
    return builder.create();
}}

然后你就可以处理这样的接收器的一切:

protected void onReceiveResult(int resultCode, Bundle resultData) {
    if (getActivity() != null){
        // Handle result
    }
}

退房ResultReceiver不survire到屏幕旋转的更多细节。 所以,最后你可能还需要重新布线ResultReceiver你的Activity 。 唯一的区别是,你去耦ActivityDialogFragment



Answer 2:

有更好的解决办法,而不是使用静态方法和变量,因为它会工作,你的对话框只有来回一个实例。 这是更好地回调存储非静态成员

private DialogTestListener mListener;
public void setListener (DialogTestListener listener){
  mListener = listener;
}

那么你应该使用TAG这样显示你的对话框mDialogFragment.show(getSupportFragmentManager(), DIALOG_TAG);

然后onResume您的活动的方法,你可以重新设置你的听众

protected void onResume() {
   super.onResume();
   mDialogFragment = (CMFilterDialogFrg) getSupportFragmentManager().findFragmentByTag(DIALOG_TAG);
   if(mDialogFragment  != null){
       mDialogFragment.setListener(yourListener)
   }
}


Answer 3:

虽然安德烈的解决方案有效,更好的解决方案是在获得更新的活动onAttach()在你的Fragment

private DialogTestListener mListener;

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    mListener = (DialogTestListener) activity;
}

有了这个解决方案,你会不会需要传递ActivitynewInstance()了。 你只需要确保Activity拥有您的FragmentDialogTestListener 。 你也不需要保存的状态就像在ResultReceiver解决方案。



Answer 4:

首先,调用setTargetFragmentFragmentParent开始dialogFragment 。 在dialogFragment使用getTargetFragment回调片段和返回数据。 所有的数据结果将在EXCUTE onactivityresultFragmentParent

请点击此链接: 从DialogFragment接收结果



Answer 5:

另一种方法是,你可以停止活动得到重建。 你要告诉的Android,你会处理的方向改变自己和android不会重新创建活动。 您需要为您的活动添加到您的清单文件:

android:configChanges="keyboardHidden|orientation"

如果不是这样,那么你可以使用标准onSaveInstanceState()保存您的状态,并恢复使用savedInstanceState所推荐的谷歌。

下面是谷歌的这官方指南: http://developer.android.com/guide/components/activities.html#Lifecycle

通过它去,如果你还没有准备好。 它真的会帮助你在Android开发。



文章来源: DialogFragment callback on orientation change