Fragment 和 DialogFragment 生命周期关系

Fragment and DialogFragment Lifecycle Relationship

我有 Fragment "A",其中我有一个 ImageButton。单击此按钮后,DialogFragment "B" 被调用到前台,其中 Fragment "A" 在后台部分可见。 DialogFragment "B" 向用户显示一个选项列表。单击特定选项后,DialogFragment "B" 将通过 Dismiss() 消失,并且 Fragment "A" 再次完全可见。

在此操作期间,我需要更新 Fragment "A" 上的 ImageButton 以表示用户在 DialogFragment "B" 上做出的选择(基本上是一个新的ImageButton 的图像)。

我认为在 OnResume 期间更新 Fragment "A" 上的 ImageButton 的正确位置是否正确?在显示 FragmentDialog "B" 时片段 "A" 是否进入 OnPause?因此,从 DialogFragment "B" 返回时,Fragment "A" 将触发它的 OnResume,这就是我应该对 ImageButton 进行更新更改的地方呈现给用户?

希望我的解释清楚。任何关于我应该在哪里以及如何更新 ImageButton 的详细帮助将不胜感激。

片段 A 不会进入 onPause,因此不会调用 onResume http://developer.android.com/guide/components/fragments.html

Resumed
The fragment is visible in the running activity.

Paused
Another activity is in the foreground and has focus, but the activity in which this fragment lives is still visible (the foreground activity is partially transparent or doesn't cover the entire screen).

我在尝试使用 Interface-Callback 方法时遇到了同样的问题,但是当 DialogFragment 被关闭时 FragmentOnResume 没有被触发,因为我们没有切换到其他 activity。

所以这里 Event Bus 让生活变得轻松。 Event Bus 是让 Activity 和 Fragment 之间进行通信的最简单和最好的方法,只需三步,你可以看到它 here

这只不过是 publish/subscribe 事件总线机制。您将获得适当的文档 here

将 EventBus 依赖项添加到您的 gradle 文件 -
compile 'org.greenrobot:eventbus:x.x.x'

compile 'org.greenrobot:eventbus:3.1.1'(特定版本)

对于上面的场景-

为用户事件创建一个自定义 POJO class -

public class UserEvent {
    public final int userId;

    public UserEvent(int userId) {
        this.userId = userId;
    }
}

订阅 Fragment A 中的事件,只要它是 DialogFragment 或其他地方的 posted/published -

@Subscribe(threadMode = ThreadMode.MAIN)
public void onUserEvent(UserEvent event) {
    // Do something with userId
    Toast.makeText(getActivity(), event.userId, Toast.LENGTH_SHORT).show();
}

从您的 Fragment A 的生命周期中注册或取消注册 您的 EventBus,尤其是分别在 onStartonStop 中 -

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

最后,在点击特定项目时,Publish/Post 您的活动来自 DialogFragment -

EventBus.getDefault().post(new MessageEvent(user.getId()));

随着 ViewModel 和 LiveData 的加入,解决这个问题变得更加容易。创建两个片段都引用的 viewModel。将下一行放在片段的 OnCreate 中。也可以在dialogfragment的onCreateDialog中。

myViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);

关闭对话框后,调用 myViewModel 上的方法,更新 LiveData 变量:

dialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            myViewModel.setButtonPressed(PositiveButtonPressed);
        }
    });
    dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialogInterface, int i) {
            myViewModel.setButtonPressed(NegativeButtonPressed)
        }
    });

在 viewModel 中,该方法将 MutuableLiveData 变量设置为要显示的图像。

void SetButtonPressed(int buttonPressed){
   if (buttonPressed==positiveButtonPressed){
       imageToBeShown.setValue(image A);
   }
   else{
      imageToBeShown.setValue(image B);
   }
}

在 onActivityCreated 中将观察者设置为 LiveData 变量:

myViewModel.imageToBeShown().observe(getViewLifecycleOwner(), new Observer<Image>() {
        @Override
        public void onChanged(@Nullable Image image) {
            button.setBackground(image);
            }
        }
    });

当然,您可以实现 getter 方法并将 MutuableLiveData 变量保密。然后观察者只观察 getter 方法。