как добавить представления в onBindViewHolder?

#android #kotlin #android-recyclerview #view

#Android #kotlin #android-recyclerview #Вид

Вопрос:

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

Я знаю, что viewholder должен быть статичным, но как мне добиться дизайна ячейки, который зависит от свойств элемента?

Уменьшенный пример, который дает мне странные результаты:

 class CustomAdapter internal constructor() :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    private var dataSet = emptyList()

    inner class ViewHolder(v: View) : RecyclerView.ViewHolder(v) {
        val title: TextView
        val linearLayout: LinearLayout

        init {
            title = v.findViewById(R.id.textView)
            linearLayout = v.findViewById(R.id.linearLayout)
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        val v = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.cardview, viewGroup, false)

        return ViewHolder(v)
    }

    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

        viewHolder.title.text = dataSet[position].name
        
        for (i in 0 until 5) {
           viewHolder.linearLayout.addView(ImageView())
        }
    }


    internal fun setItems(items: List<T>) {
        this.dataSet = items
        notifyDataSetChanged()
    }
}
  
 <androidx.cardview.widget.CardView 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical">

            <TextView
                android:id="@ id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginStart="22dp"
                android:layout_marginEnd="12dp"
                android:text="Title"
                android:textSize="18sp"
                android:textStyle="bold" />

        <LinearLayout
            android:id="@ id/linearLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

        </LinearLayout>

</androidx.cardview.widget.CardView>

  

Комментарии:

1. Не могли бы вы добавить информацию о макете ViewHolder

2. добавлено больше кода

Ответ №1:

Вы не можете добавить ImageView напрямую, как показано в вашем примере. Попробуй это:

 override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
 
 viewHolder.title.text = dataSet[position].name

 for (i in 0 until 5) {
  val holder = viewHolder
  val context = holder.itemView.context
  val imagebyCode = ImageView(context)
  imagebyCode.setImageResource(R.drawable.exampleImage)

  val params : LinearLayout.LayoutParams = LinearLayout.LayoutParams(
  LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
  imagebyCode.layoutParams = params
  val myLayout : LinearLayout = holder.itemView.findViewById(R.id.linearLayout)
  myLayout.addView(imagebyCode)
 }
}
  

Ответ №2:

Вы можете добавить представления в XML для строки представления recycler и сохранить видимость скрытой. В onBindViewHolder вы можете проверить условие и сделать представление видимым.

 override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

    viewHolder.title.text = dataSet[position].name
    
    for (i in 0 until 5) {
       viewHolder.linearLayout.view.visibility = View.VISIBLE //Set visibility here

    }
}
  

Комментарии:

1. это не сработает, если OP хочет динамическое количество просмотров в своих макетах

2. и ваш цикл на самом деле ничего не делает, он просто установит одно представление на видимое X раз