ViewPager2 at installation offscreenPageLimit is misrepresenting elements



  • Got it. ViewPager2 where the cards are displayed. Used as adapter RecyclerView.Adapter♪ The adapter has a list of models that contain colour codes for the gradient of card background. For ViewPager2 installed offscreenPageLimitto see the next card. The problem is that the first offscreenPageLimit + 1 cards are equally coloured, although in ViewHolder There are different models with different colours. Similar situation in use RecyclerView instead ViewPager2♪ 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. https://1.bp.blogspot.com/_9l0GmPwgCzk/Sf0SgfbQcVI/AAAAAAAAAD8/xKcxTQCAxn0/s400/shared_states.png

    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



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2