Проблемы с элементами в ViewPager внутри другого ViewPager - PullRequest
1 голос
/ 26 апреля 2019

Я создаю приложение для фильма.В настоящее время я показываю все элементы фильма в RecyclerView в пределах Fragment.Когда пользователь нажимает на определенный элемент фильма, ListFragment заменяется на DetailsFragment.Я могу провести к следующему пункту от DetailsFragment, поэтому я использовал ViewPager там.В DetailsFragment у меня есть ImageView и TextView.ImageView содержит изображение фильма.Я использую Glide для загрузки изображения.В качестве элемента фильма может содержаться несколько изображений фильма.Я использовал другой ViewPager для переключения между изображениями.Я сделал все это без проблем.Тем не менее, проблема начинается, когда я хотел изменить размер изображения фильма с их исходным соотношением сторон.Изображения не меняются так, как должны.При перелистывании во вложенном ViewPager размеры изображений часто меняются с указанием размера следующего элемента или предыдущего элемента.

Всякий раз, когда пользователь нажимает на элемент в ListFragment, я заполняю Первый ViewPagerсо всеми элементами фильма из элемента Activity и setCurrent для выбранного элемента.Затем я беру все изображения этого фильма в массив, извлекаю их bitmap, вычисляю новые ширину и высоту в соответствии с размером устройства и изменяю размер bitmap.Затем я отправляю эти изображения на вложенный ViewPager.Но, скажем, у меня есть три изображения для фильма, а второе изображение изменяется с соотношением сторон первого или третьего изображения.

В «MainActivity» я создаю некоторые элементы фильма и прикрепляюListFragment:

movieList = mutableListOf()

        val movie = setMovie(
            "1",
            "Fight Club",
            "A movie worth watching",
            "https://m.media-amazon.com/images/M/MV5BMjJmYTNkNmItYjYyZC00MGUxLWJhNWMtZDY4Nzc1MDAwMzU5XkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_SY1000_CR0,0,676,1000_AL_.jpg",
            "https://www.rollingstone.com/wp-content/uploads/2018/06/rs-19014-fightclub-1800-1406035542.jpg?crop=900:600&width=1440",
            "https://cdn-static.denofgeek.com/sites/denofgeek/files/styles/main_wide/public/2017/02/fight-club_main.jpg?itok=rdIIiUuT"
        )

        val movie1 = setMovie(
            "2",
            "The Shawshank Redemption",
            "A movie worth watching",
            "https://files.kstatecollegian.com/2015/06/c4728ae2-cf07-4ae6-af7e-34cf3cb38dbe-696x1044.jpg",
            "https://i0.wp.com/www.moviehousememories.com/wp-content/uploads/2014/03/The-Shawshank-Redemption-2.jpg?w=1278&ssl=1",
            "https://static1.squarespace.com/static/51b3dc8ee4b051b96ceb10de/t/5b3e33e270a6ad4a13a68537/1530803174357/?format=1500w"
        )

        val movie2 = setMovie(
            "3",
            "Titanic",
            "A movie worth watching",
            "https://m.media-amazon.com/images/M/MV5BMTg4MzQxMjIyNV5BMl5BanBnXkFtZTcwOTA3NTk1Nw@@._V1_SY1000_CR0,0,1380,1000_AL_.jpg",
            "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fd/RMS_Titanic_3.jpg/800px-RMS_Titanic_3.jpg",
            "https://imgix.bustle.com/uploads/image/2017/6/23/23e8ab61-7603-4bf3-bbed-00818829afd1-titanic.png?w=970&h=546&fit=crop&crop=faces&auto=format&q=70"
        )

        movieList.add(movie)
        movieList.add(movie1)
        movieList.add(movie2)

        val fragment = FirstFragment()
        supportFragmentManager.beginTransaction().replace(R.id.frame_layout, fragment).commit()

Класс модели Movie:

    var id: String? = ""
    var name: String? = ""
    var desc: String? = ""
    var image1: String? = ""
    var image2: String? = ""
    var image3: String? = ""

ListFragment aka FirstFragment: `

    recyclerView.setHasFixedSize(true)

    val layoutManager = LinearLayoutManager(context)
    recyclerView.layoutManager = layoutManager

    adapter = CustomAdapter(activity!!, (activity as MainActivity).movieList)
    recyclerView.adapter = adapter

`

Адаптер FirstFragment aka ListFragment:

override fun onBindViewHolder(p0: ViewHolder, p1: Int) {
        p0.textView.text = movieList[p1].name

        p0.itemView.setOnClickListener {
            val fragment = SecondFragment()
            val bundle = Bundle()
            bundle.putInt("pos", p1)
            fragment.arguments = bundle
            val transaction = (activity as FragmentActivity).supportFragmentManager.beginTransaction()
            transaction.addToBackStack(null)
            transaction.replace(R.id.frame_layout, fragment)
            transaction.commit()
        }
    }

Теперь SecondFragment, который содержит первое ViewPager:

val adapter = ItemAdapter(childFragmentManager, (activity as MainActivity).movieList)
        viewPager.adapter = adapter

        val bundle = arguments
        if (bundle != null) {
            position = bundle.getInt("pos")
            viewPager.setCurrentItem(position, true)
        }

NowАдаптер First ViewPager:

class ItemAdapter(
    fm: FragmentManager?,
    val movieList: MutableList<Movie>
) : FragmentStatePagerAdapter(fm) {
    override fun getItem(p0: Int): Fragment {
        val fragment = ThirdFragment()
        val bundle = Bundle()
        bundle.putParcelable("movie", movieList[p0])
        fragment.arguments = bundle
        return fragment
    }

    override fun getCount(): Int {
        return movieList.size
    }
}

Теперь DetailsFragment aka ThirdFragment (содержит вложенные ViewPager):

images = mutableListOf()
        allItems = mutableListOf()

        val bundle = arguments
        if (bundle != null) {
            val movie = bundle.getParcelable("movie") as Movie

            images.add(movie.image1!!)
            images.add(movie.image2!!)
            images.add(movie.image3!!)

            for (i in 0 until images.size) {
                val fetchData = FetchData()
                fetchData.asyncResponse = this
                fetchData.execute(images[i])
            }

            tvName.text = movie.name
        }

        adapter = AnotherAdapter(childFragmentManager, allItems)
        viewPager.adapter = adapter

        return view
    }

    override fun processFinish(imageProperty: ImageProperty) {
        val width = imageProperty.bitmap!!.width
        val height = imageProperty.bitmap!!.height
        val originalRatio: Double = width.toDouble() / height.toDouble()

        val deviceWidth = viewPager.measuredWidth
        val scaledHeight = deviceWidth.toDouble() / originalRatio

        imageProperty.width = deviceWidth
        imageProperty.height = scaledHeight.toInt()

        Methods().showLog("Link: ${imageProperty.link!!}")
        Methods().showLog("Width: ${imageProperty.width}")
        Methods().showLog("Height: ${imageProperty.height}")

        allItems.add(imageProperty)
        adapter = AnotherAdapter(childFragmentManager, allItems)
        viewPager.adapter = adapter
    }

    class FetchData : AsyncTask<String, Void, ImageProperty>() {
        var asyncResponse: ImageResponse? = null
        override fun doInBackground(vararg params: String?): ImageProperty {
            return try {
                val url = URL(params[0])

                val connection = url
                    .openConnection() as HttpURLConnection
                connection.doInput = true
                connection.connect()
                val input = connection.inputStream
                val imageProperty = ImageProperty()
                imageProperty.link = params[0]
                imageProperty.bitmap = BitmapFactory.decodeStream(input)
                imageProperty
            } catch (e: IOException) {
                e.printStackTrace()
                val imageProperty = ImageProperty()
                imageProperty.bitmap = BitmapFactory.decodeStream(null)
                imageProperty
            }
        }

        override fun onPostExecute(result: ImageProperty?) {
            super.onPostExecute(result)
            asyncResponse?.processFinish(result!!)
        }
    }

Моделькласс ImageProperty:

class ImageProperty() : Parcelable {
    var link: String? = ""
    var width: Int = 0
    var height: Int = 0
    var bitmap: Bitmap? = null

Адаптер для вложенных ViewPager:

class AnotherAdapter(fm: FragmentManager?, private val list: MutableList<ImageProperty>) : FragmentStatePagerAdapter(fm) {
    override fun getItem(p0: Int): Fragment {
        val fragment = FourthFragment()
        val bundle = Bundle()
        bundle.putParcelable("image", list[p0])
        fragment.arguments = bundle
        return fragment
    }

    override fun getCount(): Int {
        return list.size
    }
}

И, наконец, последний фрагмент для отображения изображения (В настоящее время я не использую ImageView, но TextView, чтобы проверить, правильно ли изменен размер моего изображения. Они корректно изменяются. Но если вы проверите ViewPager, он не будет изменен с размером в TextView, скорее, ониили со следующим элементом или с предыдущим):

val bundle = arguments
        val imageProperty = bundle!!.getParcelable("image") as ImageProperty

        val textView2 = view.findViewById<TextView>(R.id.textView2)
        val textView3 = view.findViewById<TextView>(R.id.textView3)
        val textView4 = view.findViewById<TextView>(R.id.textView4)

        textView2.text = imageProperty.link
        textView3.text = imageProperty.width.toString()
        textView4.text = imageProperty.height.toString()

        (parentFragment as ThirdFragment).viewPager.layoutParams.width = imageProperty.width
        (parentFragment as ThirdFragment).viewPager.layoutParams.height = imageProperty.height
        (parentFragment as ThirdFragment).viewPager.requestLayout()
...