[英]How to use Generics or Reflection to show/hide fragments? Kotlin Android
I have a fragment manager to show/hide fragments in my app. 我有一个片段管理器来显示/隐藏我的应用程序中的片段。 Right now when I want to show a fragment from any activity or fragment I call this method from the manager 现在,当我想显示任何活动或片段的片段时,请从管理器中调用此方法
fun show(manager: FragmentManager, fragmentTag: String, container: Int, data: Any?): Companion {
var fragment = manager.findFragmentByTag(fragmentTag)
if (fragment != null) {
manager.popBackStack(fragmentTag, 0)
} else {
addFragment(manager, getFragment(fragmentTag, manager, data)!!, container, fragmentTag)
}
return this
}
private fun getFragment(fragmentTag: String, manager: FragmentManager, data: Any?): Fragment? {
when (fragmentTag) {
MenuFragment.TAG -> return getMenuFragment(manager)
TagsFragment.TAG -> return getTagsFragment(manager)
...
}
return null
}
with return a fragment with a specific class 与返回具有特定类的片段
private fun getMenuFragment(manager: FragmentManager): Fragment {
var fragment = manager.findFragmentByTag(MenuFragment.TAG) as MenuFragment?
if (fragment == null) {
fragment = MenuFragment.newInstance()
}
return fragment
}
I would like to have an strategy to avoid create one method every time I need to implement a new fragment, so I was thinking about generics or maybe reflection wich I have never used before. 我想有一个策略来避免每次需要实现一个新片段时都创建一个方法,所以我在考虑泛型或也许从未使用过的反射。
Is there any way to do this using reflection? 有什么办法可以使用反射来做到这一点? or another better strategy? 还是另一个更好的策略?
Thanks for any help. 谢谢你的帮助。
Edit 编辑
As I have one Activity and many fragments I finally extended FragmentManager to use it in every fragment. 由于我有一个Activity和许多片段,因此我最终扩展了FragmentManager以在每个片段中使用它。
inline fun <reified T : Fragment> FragmentManager.showFragment(tag: String, container: Int, args: Bundle? = null) {
val clazz = T::class.java
var fragment = findFragmentByTag(clazz.name)
if (fragment != null) {
this.popBackStack(tag, 0)
} else {
fragment = (clazz.getConstructor().newInstance() as T).apply {
args?.let {
it.classLoader = javaClass.classLoader
arguments = args
}
}
val transaction = this.beginTransaction()
transaction.add(container, fragment as Fragment, tag)
transaction.addToBackStack(tag)
transaction.commit()
}
}
call: 呼叫:
activity!!.supportFragmentManager.showFragment<MenuFragment>(MenuFragment.TAG, R.id.container)
With Reflection provided that the fragment tag is the fully qualified name of the class provided using MenuFragment::class.java.name
通过Reflection提供的条件是,fragment标签是使用MenuFragment::class.java.name
提供的类的完全限定名称。
private fun getFragment(fragmentTag: String, manager: FragmentManager, data: Any?): Fragment? {
return manager.findFragmentByTag(fragmentTag) ?: getFragment(fragmentTag)
}
private fun getFragment(fragmentTag: String): Fragment? {
val c = Class.forName(fragmentTag)
return c.getMethod("newInstance").invoke(null) as Fragment?
}
Without Reflection 没有反思
private fun getFragment(fragmentTag: String, manager: FragmentManager, data: Any?): Fragment? {
return manager.findFragmentByTag(fragmentTag) ?: when (fragmentTag) {
MenuFragment.TAG -> MenuFragment.newInstance()
TagsFragment.TAG -> TagsFragment.newInstance()
else -> null
}
}
if I correctly understood a question, you can write extension function for FragmentManager like this 如果我正确理解了一个问题,可以像这样为FragmentManager编写扩展功能
inline fun <reified T : Fragment> FragmentManager.getFragment(args: Bundle? = null): Fragment {
val clazz = T::class.java
return findFragmentByTag(clazz.name) ?: return (clazz.getConstructor().newInstance() as T).apply {
args?.let {
it.classLoader = javaClass.classLoader
arguments = args
}
}
}
end then use it, eg in activity 然后在活动中使用它
val frag = supportFragmentManager.getFragment<MyFragment>()
where MyFragment - is your fragment class MyFragment-是您的片段类
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.