实例化Fragment并调用其方法

一个关于获取Fragment实例的扩展函数。可用于获取Fragment和调用实例Fragment中的方法传值
新建FragmentManget.kt :



import androidx.annotation.IdRes
import androidx.annotation.Size
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction

inline fun <reified F> FragmentManager.forEachFragmentWithChildByType(noinline block: (F) -> Unit) {
    forEachFragmentWithChildByType(F::class.java, block)
}

@Suppress("UNCHECKED_CAST")
fun <F> FragmentManager.forEachFragmentWithChildByType(clazz: Class<F>, block: (F) -> Unit) {
    fragments.forEach {
        if (clazz.isInstance(it)) {
            block(it as F)
        }
        it.childFragmentManager.forEachFragmentWithChildByType(clazz, block)
    }
}

inline fun <reified F> FragmentManager.findFragmentByType(): F? {
    return fragments.find { it is F } as? F
}

inline fun <reified F> FragmentManager.findFragmentWithChildByType(): F? {
    fragments.forEach {
        val findWithChildByType = it.findFragmentWithChildByType(F::class.java)
        if (findWithChildByType != null) {
            return findWithChildByType
        }
    }
    return null
}

/**
 * 向自身和子类遍历并查找实现了制定类或接口的实例
 */
@Suppress("UNCHECKED_CAST")
fun <F> Fragment.findFragmentWithChildByType(clazz: Class<F>): F? {
    if (clazz.isInstance(this)) {
        return this as F
    } else {
        childFragmentManager.fragments.forEach {
            val findWithChildByType = it.findFragmentWithChildByType(clazz)
            if (findWithChildByType != null) {
                return findWithChildByType
            }
        }
        return null
    }
}

inline fun <reified F : Fragment> FragmentManager.findOrAddChild(
    @Size(min = 1) tag: String, commitNow: Boolean = false, noinline creator: () -> F
): F {
    return findOrAddChild(tag, F::class.java, commitNow, creator)
}

inline fun <reified F : Fragment> FragmentManager.findOrAddChild(
    @IdRes id: Int,
    @Size(min = 1) tag: String,
    commitNow: Boolean = false,
    noinline creator: () -> F
): F {
    return findOrAddChild(id, tag, F::class.java, commitNow, creator)
}

/**
 * 查找fragment或创建并加入fragment中
 */
fun <F : Fragment> FragmentManager.findOrAddChild(
    @IdRes id: Int,
    @Size(min = 1) tag: String,
    clazz: Class<F>,
    commitNow: Boolean = false,
    creator: () -> F
): F {
    return findOrOptionChild(tag, clazz, commitNow, creator) {
        add(id, it, tag)
    }
}

/**
 * 查找fragment或创建并加入fragment中(不显示其)
 */
fun <F : Fragment> FragmentManager.findOrAddChild(
    @Size(min = 1) tag: String, clazz: Class<F>, commitNow: Boolean = false, creator: () -> F
): F {
    return findOrOptionChild(tag, clazz, commitNow, creator) {
        add(it, tag)
    }
}

inline fun <reified F : Fragment> FragmentManager.findOrReplaceChild(
    @IdRes containerViewId: Int,
    @Size(min = 1) tag: String,
    commitNow: Boolean = false,
    noinline creator: () -> F
): F {
    return findOrReplaceChild(containerViewId, tag, F::class.java, commitNow, creator)
}

/**
 * 查找fragment或创建并替换到view中
 */
fun <F : Fragment> FragmentManager.findOrReplaceChild(
    @IdRes containerViewId: Int,
    @Size(min = 1) tag: String,
    clazz: Class<F>,
    commitNow: Boolean = false,
    creator: () -> F
): F {
    return findOrOptionChild(tag, clazz, commitNow, creator) {
        replace(containerViewId, it, tag)
    }
}

/**
 * 从已加载的fragment中找,如未找到对应的fragment,创建一个并对其进行操作以使其加入
 */
inline fun <F : Fragment> FragmentManager.findOrOptionChild(
    @Size(min = 1) tag: String,
    clazz: Class<F>,
    commitNow: Boolean = false,
    creator: () -> F,
    option: FragmentTransaction.(F) -> FragmentTransaction
): F {
    // 先获取fragment是否已经加入host
    val fragment = findFragmentByTag(tag)
    // fragment不为空但不是该类实例,移除它
    if (fragment != null && !clazz.isInstance(fragment)) {
        beginTransaction()
            .remove(fragment)
            .commitNowAllowingStateLoss()
    }
    // 检查获取到的fragment
    return if (clazz.isInstance(fragment)) {
        clazz.cast(fragment)!!
    } else {
        // 如果不是该类实例,创建新的并加入host
        creator().also { f ->
            option(beginTransaction(), f).run {
                if (commitNow) {
                    commitNowAllowingStateLoss()
                } else {
                    commitAllowingStateLoss()
                }
            }
        }
    }
}

使用方法:

//FragmentItemConvention为要获取实例的Fragment
 childFragmentManager.findFragmentByType<FragmentItemConvention>()?.let { ft ->
                ft.getImgData(it)
            }

END

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值