如何将FragmentPagerAdapter与唯一不相关的片段一起使用?

时间:2019-03-04 20:11:56

标签: android arrays kotlin android-viewpager fragmentpageradapter

我正在尝试在应用的三个主屏幕(提要,论坛和个人资料)之间执行简单的滑动操作。 我一直在网上寻找指南,但是它们似乎都采用相同的方法,并展示了如何使用片段来实现适配器,这些片段是基本类的简单实例,例如,仅在屏幕上增加标题和数字。

就我而言,这些片段并非都是同一类的所有实例,而是完全不同的。

M问题在于FragmentPagerAdapter。我不确定如何在getItem方法中返回每个片段。

我已经尝试了以下方法,但是除了将其作为有效的return语句外,它一直都在等待:

class PagesPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {


    override fun getItem(p0: Int): Fragment? {

        return when (p0){

            0 -> FeedFragment.newInstance()
            1 -> BoardFragment.newInstance()
            2 -> ProfileFragment.newInstance()
            else -> FeedFragment.newInstance()
        }

    }



    override fun getCount(): Int {
        return 3
    }
}

这是我的片段之一的示例:

class FeedFragment : Fragment() {

    val galleryAdapter = GroupAdapter<ViewHolder>()


    private fun setUpGalleryAdapter() {

        feed_gallary.adapter = galleryAdapter
        val galleryLayoutManager = GridLayoutManager(this.context, 3)
        feed_gallary.layoutManager = galleryLayoutManager

        val dummyUri =
            "https://firebasestorage.googleapis.com/v0/b/dere-3d530.appspot.com/o/20150923_100950.jpg?alt=media&token=97f4b02c-75d9-4d5d-bc86-a3ffaa3a0011"

        val imageUri = Uri.parse(dummyUri)
        if (imageUri != null) {
            galleryAdapter.add(FeedImage(imageUri))
            galleryAdapter.add(FeedImage(imageUri))
            galleryAdapter.add(FeedImage(imageUri))
            galleryAdapter.add(FeedImage(imageUri))
            galleryAdapter.add(FeedImage(imageUri))


        }
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        setUpGalleryAdapter()

    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
        inflater.inflate(R.layout.fragment_feed, container, false)


    companion object {
        fun newInstance(): FeedFragment = FeedFragment()
    }

}

这是我的主要活动:

class MainActivity : AppCompatActivity() {


    private lateinit var viewPager: ViewPager
    private lateinit var pagerAdapter: PagesPagerAdapter


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewPager = findViewById<ViewPager>(R.id.view_pager)

        pagerAdapter = PagesPagerAdapter(supportFragmentManager)
        viewPager.adapter = pagerAdapter

    }
}

我还尝试定义了一个变量currentFragment,为每个when语句重新分配了它,并将其作为返回值,但是由于我所有的片段都是唯一的,因此在尝试将它们全部分配给它们时我遇到类型不匹配的情况一个变量。

我可以在其中存储一些片段,然后返回数组位置吗?

我觉得这里可能有一个简单而优雅的通用解决方案。

2 个答案:

答案 0 :(得分:0)

不幸的是,这种情况下没有优雅的解决方案。您可以将创建的片段存储在数组中,然后在需要访问相关片段实例时使用此数组。

class PagesPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {
    private val fragments = SparseArray<WeakReference<Fragment>>()

    override fun getCount() = 3

    override fun getItem(position: Int): Fragment? {
        val fragmentReference = fragments[position]
        return if (fragmentReference?.get() != null) {
            fragmentReference.get()
        } else {
            return when (position) {
                0 -> FeedFragment.newInstance()
                1 -> BoardFragment.newInstance()
                2 -> ProfileFragment.newInstance()
                else -> error("Incorrect position: $position")
            }
        }
    }

    override fun instantiateItem(container: ViewGroup, position: Int): Any {
        val fragment = super.instantiateItem(container, position) as Fragment
        fragments.put(position, WeakReference(fragment))
        return fragment
    }

答案 1 :(得分:0)

我不能确定没有看到所有代码,但是要注意的一件事是,您必须返回片段的一个实例,而不是对该类的引用。例如:FeedFragment()而不是FeedFragment

此外,您的when语句没有默认情况,导致getItem方法的编译错误,因为您的代码路径未返回任何内容。为getItem

尝试以下代码
override fun getItem(p0: Int): Fragment {

    when(p0){
        0 -> return FeedFragment.newInstance()
        1 -> return BoardFragment.newInstance()
        else -> return ProfileFragment.newInstance()
    }
}