Как использовать FragmentPagerAdapter с уникальными несвязанными фрагментами? - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь выполнить простое перелистывание между тремя основными экранами моего приложения (канал, форум и профиль).Я искал руководства онлайн, но все они, похоже, используют один и тот же подход и показывают, как реализовать адаптер, используя фрагменты, которые являются простыми экземплярами базового класса, который, например, просто раздувает заголовок и число на экране.

В моем случае фрагменты не все экземпляры одного и того же класса и совершенно разные.

M проблема лежит в FragmentPagerAdapter.Я не уверен, как вернуть каждый фрагмент в методе getItem.

Я пробовал следующее, но это не так, как допустимый оператор возврата, и все еще ожидает его:

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 голосов
/ 04 марта 2019

Не видя весь ваш код, я не могу быть уверен, но одна вещь, на которую стоит обратить внимание, это то, что вы должны вернуть экземпляр вашего фрагмента, а не ссылку на класс.Пример: 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()
    }
}
0 голосов
/ 04 марта 2019

К сожалению, не существует элегантного решения для этого случая.Вы можете сохранить созданный фрагмент в массиве, а затем использовать этот массив, когда вам нужен доступ к связанному экземпляру фрагмента.

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
    }
...