Android Fragment 在Dialog中的使用

本文探讨了Android中将Fragment放入Dialog时遇到的生命周期问题,当同一个Fragment被多次加载导致错误。详细分析了错误原因,并通过代码实例展示了如何避免这种错误。在Fragment的onStart和onResume方法中,可以看到其生命周期与包含它的Activity同步。通过理解这些,可以有效地管理和感知Dialog的生命周期。

先看这样一个报错:

Caused by: android.view.InflateException: Binary XML file line #13 in com.example.kotlindemo:layout/layout_dialog_simple: Error inflating class fragment
Caused by: java.lang.IllegalArgumentException: Binary XML file line #13: Duplicate id 0x7f080152, tag null, or parent id 0xffffffff with another fragment for com.example.kotlindemo.ui.fragment.SimpleFragment

错位很明显:不能重复加载同一个id或者tag的fragment。这就意味着:重复new 含有同一个Fragment的dialog就会报错。

接下来看这样一个实例:

fun showSimpleDialog(view: View) {
    if(!this::simpleDialog.isInitialized){
        simpleDialog = SimpleDialog(this).apply {
            setContentView(LayoutInflater.from(activity).inflate(R.layout.layout_dialog_simple, null))
        }
    }
    simpleDialog.show()
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">

    <fragment
        android:id="@+id/simpleFragment"
android:name="com.example.kotlindemo.ui.fragment.SimpleFragment"
        android:layout_width="match_parent"
        android:layout_height="200dp" />
</LinearLayout>

fragment放进dialog中show:第一次

SimpleFragment: onAttach:
SimpleFragment: onCreate:
SimpleFragment: onStart:
SimpleFragment: onResume:
SimpleDialog: onCreate:

dimiss时:无日志
第二次show:无日志

因为此时一直处于onResume的状态。
所以,fragment放进dialog中则无法正常使用生命周期回调方法了。但是在Activity其它生命周期发生变化的时候,此时的fragment的生命周期发生了对应的同步变化。

也就是说:fragment放进dialog,其生命周期是与Activity同步的。(即便是fragment直接放进Activity的布局页面方式,其show和hide也是不会触发生命周期变化的)

这一点从源码也可以验证:

/**
 * Called when the Fragment is visible to the user.  This is generally
 * tied to {@link Activity#onStart() Activity.onStart} of the containing
 * Activity's lifecycle.
 */
@CallSuper
public void onStart() {
    mCalled = true;
}

/**
 * Called when the fragment is visible to the user and actively running.
 * This is generally
 * tied to {@link Activity#onResume() Activity.onResume} of the containing
 * Activity's lifecycle.
 */
@CallSuper
public void onResume() {
    mCalled = true;
}

借助这种方式,可以实现dialog生命周期的感知。(当然dialog使用lifecycle也是可以做到的)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ganshenml

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值