在下面的图片中,您可以看到所需的布局:
因此,ViewPager具有三个页面,左右页面静态地填充有两个片段(片段1和片段2),并且位于中心的页面的布局应具有顶部的工具栏,底部的工具栏和底部的工具栏。两者之间可以动态更改。
据我所知,有两种方法可以做到这一点。
在同时具有两个工具栏和动态设置Fragment0的中心页面上做一些魔术
每个应转到中心页面的片段都应具有这些工具栏,并具有处理它们中事件的相同方式,即AbstractCenterFragment
上的子类,其中包含实现此布局和行为所需的所有内容。
即使实施解决方案2会更容易,出于很多原因,我也不喜欢它。我不会在这里处理,但是如果您坚持,我可以提供。
对于解决方案1,您可以建议从活动级别解决此问题,因为活动及其所有组件(视图模型等)都应处理此布局?
如果我将FragmentPagerAdapter
用于ViewPager
,并在包含工具栏,底部工具栏和Fragment0的中心页面中创建父片段,这将如何影响性能?
您是否还有其他建议使用其他类型的PagerAdapter
来处理给定布局的行为?
谢谢!
如果对此问题的评分为-1,请保持礼貌,以解释您为什么给出它。
答案 0 :(得分:0)
好的,我在给定布局的 PRIMARY_ID
12345
23456
2 rows selected.
和FragmentViewPagerAdapter
的常规实现之间做出了混合解决方案。
这里是:
ViewPagerAdapter
在Activity中实现此适配器时,我创建了以下类:
abstract class NoMiddleFragmentPagerAdapter(private val mFragmentManager: FragmentManager) : PagerAdapter() {
private var mCurTransaction: FragmentTransaction? = null
private var mCurrentPrimaryItem: Fragment? = null
abstract fun getLeftItem(): Fragment
abstract fun getRightItem(): Fragment
@Throws(IllegalStateException::class)
override fun startUpdate(container: ViewGroup) {
if (container.id == View.NO_ID) {
throw IllegalStateException( "ViewPager with adapter $this requires a view id.")
}
}
override fun instantiateItem(container: ViewGroup, position: Int): Any = if (position == MIDDLE) instantiateCentralArea(container, position) else instantiateFragment(container, position)
private fun instantiateFragment(container: ViewGroup, position: Int) : Fragment {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction()
}
val itemId = getItemId(position)
// Do we already have this fragment?
val name = makeFragmentName(container.id, itemId)
var fragment = mFragmentManager.findFragmentByTag(name)
if (fragment != null) {
mCurTransaction!!.attach(fragment)
} else {
fragment = if (position == LEFT) getLeftItem() else getRightItem()
mCurTransaction!!.add(
container.id, fragment,
makeFragmentName(container.id, itemId)
)
}
if (fragment !== mCurrentPrimaryItem) {
fragment.setMenuVisibility(false)
fragment.userVisibleHint = false
}
return fragment
}
abstract fun instantiateCentralArea(container: ViewGroup, position: Int): Any
override fun getCount(): Int = 3
override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) = if (position == MIDDLE) destroyMiddlePart(container, `object`) else destroyFragment(container, position, `object`)
private fun destroyFragment(container: ViewGroup, position: Int, any: Any) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction()
}
mCurTransaction!!.detach(any as Fragment)
}
private fun destroyMiddlePart(container: ViewGroup, `object`: Any) = container.removeView(`object` as View)
override fun setPrimaryItem(container: ViewGroup, position: Int, o: Any) {
if (o !is Fragment) {
super.setPrimaryItem(container, position, o)
return
}
if (o !== mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem!!.setMenuVisibility(false)
mCurrentPrimaryItem!!.userVisibleHint = false
}
o.setMenuVisibility(true)
o.userVisibleHint = true
mCurrentPrimaryItem = o
}
}
override fun finishUpdate(container: ViewGroup) {
if (mCurTransaction != null) {
mCurTransaction!!.commitNowAllowingStateLoss()
mCurTransaction = null
}
}
override fun isViewFromObject(view: View, any: Any): Boolean {
return when (any) {
is Fragment -> any.view == view
is View -> view === any
else -> false
}
}
override fun saveState(): Parcelable? {
return null
}
override fun restoreState(state: Parcelable?, loader: ClassLoader?) {}
fun getItemId(position: Int): Long {
return position.toLong()
}
companion object {
private const val LEFT = 0
private const val MIDDLE = 1
private const val RIGHT = 2
private fun makeFragmentName(viewId: Int, id: Long): String {
return "android:switcher:$viewId:$id"
}
}
}