Ruu*_*kis 7 android dialog android-fragments android-dialogfragment
场景如下,我有一个包含片段的ViewPager,这些片段中的每一个都有一些需要确认的动作.
我继续创建一个DialogFragment,目标是知道如何处理结果的片段,但是在用户确认或拒绝对话之前可能会重新创建片段.
我可以将一个lambda或其他形式的监听器传递给对话框,然后在用户确认对话框时调用它,但问题是如果设备随后被旋转,则lambda会丢失,因为它不能持久化捆绑......
我能想到的唯一方法是将一些UUID分配给对话框,并将应用程序中的UUID连接到lambda,lambda保存在应用程序内的Map上,但这似乎是非常草率的解决方案..
我尝试在线搜索现有的解决方案,例如材料对话框库样本,但大多数情况似乎都忽略了旋转对话框,但这似乎也是一个草率的解决方案,因为对话框可能是较长流程的一部分,例如如
请求购买 - >取消 - >显示带有解释的对话框 - >如果用户想要再次购买
如果我们简单地忽略旋转对话框,那么流动状态将会丢失
如果您传递匿名 lambda/Listener,您将在旋转后丢失它,但如果您让您的活动实现您的侦听器并在onAttach(context)片段方法中分配它,它将在活动重新创建后重新分配。
interface FlowStepListener {
fun onFirstStepPassed()
fun onSecondStepPassed()
fun onThirdStepPassed()
}
Run Code Online (Sandbox Code Playgroud)
class ParentActivity: Activity(), FlowStepListener {
override fun onFirstStepPassed() {
//control your fragments here
}
override fun onSecondStepPassed() {
//control your fragments here
}
override fun onThirdStepPassed() {
//control your fragments here
}
}
Run Code Online (Sandbox Code Playgroud)
open class BaseDialogFragment : DialogFragment() {
var listener: FlowStepListener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is FlowStepListener) {
listener = context
} else {
throw RuntimeException("$context must implement FlowStepListener")
}
}
override fun onDetach() {
super.onDetach()
listener = null
}
}
Run Code Online (Sandbox Code Playgroud)
不要使用回调来捕获对目标对象的引用,而是尝试LocalBroadcastManager(文档)。
这种方法的主要优点是:
support-v4您的项目没有额外的依赖项,因为 LocalBroadcastManager 是和/或 AndroidX 的一部分legacy-support-v4,您很可能已经拥有了。
无需保留任何类型的参考。
简而言之:
Intent通过LocalBroadcastManager和发送带有消息的消息BroadcastReceiver来侦听来自的消息LocalBroadcastManager。对于从 DialogFragment 内发送:
public static final String MY_ACTION = "DO SOMETHING";
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
final Button button = view.findViewById(R.id.accept);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent broadcastIntent = new Intent(MY_ACTION);
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(broadcastIntent);
dismiss();
}
});
}
Run Code Online (Sandbox Code Playgroud)
并监听目标片段中的消息:
private final BroadcastReceiver localReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Do whatever you need to do here
}
};
@Override
protected void onStart() {
super.onStart();
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(MyDialogFragment.MY_ACTION);
LocalBroadcastManager.getInstance(getContext())
.registerReceiver(localReceiver, intentFilter);
}
@Override
protected void onStop() {
super.onStop();
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(localReceiver);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
336 次 |
| 最近记录: |