Я создаю приложение для фильма.В настоящее время я показываю все элементы фильма в 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()