ViewPager2 at installation offscreenPageLimit is misrepresenting elements
-
Got it.
ViewPager2
where the cards are displayed. Used as adapterRecyclerView.Adapter
♪ The adapter has a list of models that contain colour codes for the gradient of card background. ForViewPager2
installedoffscreenPageLimit
to see the next card. The problem is that the first offscreenPageLimit + 1 cards are equally coloured, although inViewHolder
There are different models with different colours. Similar situation in useRecyclerView
insteadViewPager2
♪ https://imgur.com/a/0QuxjzP ♪class MainActivity : AppCompatActivity() {
private val adapter: Adapter by lazy { Adapter() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val pager = findViewById<ViewPager2>(R.id.pager) val pageMarginPx = resources.getDimension(R.dimen.dim8).toInt() pager.offscreenPageLimit = 2 pager.setPageTransformer(MarginPageTransformer(pageMarginPx)) pager.adapter = adapter val items = listOf( Model("CARD 1","#000000", "#FFFFFF"), Model("CARD 2","#FFF0EB", "#FFC1AF"), Model("CARD 3","#BF559B", "#DE7ECB"), Model("CARD 4","#FFEEC2", "#F8C33D") ) adapter.setItems(items) } class Adapter : RecyclerView.Adapter<Adapter.ViewHolder>() { private var items: List<Model> = emptyList() fun setItems(items: List<Model>) { this.items = items notifyDataSetChanged() } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = ItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.bind(items[position]) } override fun getItemCount(): Int = items.size class ViewHolder(private val binding: ItemBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(item: Model) { Log.d("TAG", "$item") val background = itemView.context.getDrawable(R.drawable.gradient) as GradientDrawable val colorList = intArrayOf(Color.parseColor(item.start), Color.parseColor(item.end)) background.colors = colorList binding.container.background = background binding.txt.text = item.text } } }
}
-
Drawable may use a common so-called ConstantState to reuse different data. The change in one drawable may therefore affect several times.
So that all of this can be disconnected from this general state, we need to call a method.
mutate()
And then change the drawable. After the call.mutate()
:(background.mutate() as GradientDrawable).colors = colorList
https://android-developers.googleblog.com/2009/05/drawable-mutations.html