我来自 ViewPager 和 FragmentPagerAdapter,它有一个非常直接的实现,就像这样。
public class FragmentAdapters extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public FragmentAdapters(@NonNull FragmentManager fm, int behavior) {
super(fm, behavior);
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
@NonNull
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
}
父片段
adapter = new FragmentAdapters(getChildFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
CoinsFragment coinsFragment = new AssetFragment();
NewsFragment newsFragment = new NewsFragment();
VideoFragment videoFragment = new VideoFragment();
adapter.addFragment(coinsFragment, getString(R.string.asset));
adapter.addFragment(newsFragment, getString(R.string.news));
adapter.addFragment(videoFragment, getString(R.string.videos));
mViewPager.setAdapter(adapter);
mViewPager.setOffscreenPageLimit(2);
Android 建议远离 ViewPager 并弃用心爱的 FragmentPagerAdapter,现在我正在尝试将 ViewPager2 与 FragmentStateAdapter 一起使用,但在其工作方式方面存在很多困惑和困难。
这是我的实现
class AppFragmentAdapter(private val fragmentList: MutableList<Pair<String, Fragment>>, fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) {
private val pageIds = fragmentList.map { fragmentList.hashCode().toLong() }
override fun getItemCount(): Int = fragmentList.size
override fun createFragment(position: Int): Fragment = when (position) {
0 -> {
Log.wtf("WTF", fragmentList[position].first + " " + position)
fragmentList[position].second
}
1 -> {
Log.wtf("WTF", fragmentList[position].first + " " + position)
fragmentList[position].second
}
2 -> {
Log.wtf("WTF", fragmentList[position].first + " " + position)
fragmentList[position].second
}
else -> throw IllegalStateException("Invalid adapter position")
}
fun getFragmentName(position: Int) = fragmentList[position].first
// fun addFragment(fragment: Pair<String, Fragment>) {
// fragmentList.add(fragment)
// notifyItemInserted(fragmentList.size)
// notifyItemRangeChanged(fragmentList.size, fragmentList.size)
// notifyDataSetChanged()
// }
//
// fun removeFragment(position: Int) {
// fragmentList.removeAt(position)
// notifyItemRemoved(position)
// notifyItemRangeChanged(fragmentList.size, fragmentList.size)
// notifyDataSetChanged()
// }
override fun getItemId(position: Int): Long {
return pageIds[position] // Make sure notifyDataSetChanged() works
}
override fun containsItem(itemId: Long): Boolean {
return pageIds.contains(itemId)
}
}
通常我们可以立即从createFragment
方法中的列表中返回片段,但是有一个巨大的混乱,所以我试图扩展它以查看发生了什么。令我感到惊讶的是,何时createFragment
被调用一 (1) 次,而不是有多少可用片段返回,getItemCount
因此只显示一个片段,并且更令人困惑,我所谓的第一个片段 (AssetFragment) 放在最后位置和前两个片段是空屏幕,我不知道这两个片段来自哪里。
父片段
val fragmentList : MutableList<Pair<String,Fragment>> = ArrayList()
fragmentList.add(Pair(getString(R.string.assets), AssetFragment.newInstance()))
fragmentList.add(Pair(getString(R.string.news), NewsFragment.newInstance()))
fragmentList.add(Pair(getString(R.string.videos), VideosFragment.newInstance()))
val adapter = AppFragmentAdapter(fragmentList, requireActivity())
viewPager.adapter = adapter
viewPager.offscreenPageLimit = 2
这就是我的 Fragment 的样子,基本上没什么特别的
class AssetFragment : BaseFragment() {
companion object {
fun newInstance() = AssetFragment()
}
private lateinit var viewModel: AssetViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.asset_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(AssetViewModel::class.java)
// TODO: Use the ViewModel
}
}
有人可以告诉我这种荒谬的行为是什么吗?PS我试图做一些日志,getItemCount
它被调用了23次只是为了一个3片段?