31

如何在适配器中进行最新的jetpack“视图绑定”,以自动绑定视图。我没有使用 findVeiwById 或 Butterknife 或 Kotlin 合成?我已经使用了新的视图绑定,并且对于 Activity 和 Fragment 都可以正常工作。在 build.gradle 文件中启用 viewBinding 后,我可以看到 ActivityHomeBinding 和 FragmentHomeBinding 文件。此外,我看到使用的项目 xml 的类 ItemListBinding 即 item_list.xml。但是如何在recyclerview的适配器中使用这个文件

viewBinding {
        enabled = true
}

家庭活动文件

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityHomeBinding.inflate(layoutInflater)
        setContentView(binding.root)
}

分段

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = FragmentHomeBinding.inflate(inflater, container, false)
        val view = binding.root
        return view
}

Base Adapter:想在这里使用视图绑定。我可以看到 ItemListBinding,但不知道如何使用它。

class BaseAdapter @Inject constructor(
    private val context: Context,
    private val picasso: Picasso
) :
    RecyclerView.Adapter<BaseAdapter.ViewHolder>() {

    private var data = ArrayList<Data>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(context).inflate(R.layout.item_list, parent, false)
        )
    }

    override fun getItemCount() = data.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        with(holder) {
              // TODO
        }
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

        @BindView(R.id.tvMovieName)
        lateinit var nameTV: TextView

        @BindView(R.id.imageView)
        lateinit var bannerImage: ImageView

        init {
            ButterKnife.bind(this@ViewHolder, view)
        }
    }

    fun setData(serverData: ArrayList<Data>) {
        data = serverData
        notifyDataSetChanged()
    }
}
4

5 回答 5

53

您可以使用bindViewBinding 的静态方法从现有布局创建绑定。将其作为属性添加到 viewholder:

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
   val binding = ItemListBinding.bind(view)
}

然后您可以通过该字段访问所有视图binding,例如:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    with(holder) {
          // TODO
          binding.tvMovieName.text = data[position].title
          binding.imageView.setDrawableImage(data[position].image)
    }
}
于 2020-03-02T15:42:59.330 回答
28

找到另一个解决它

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val binding = ItemListBinding.inflate(LayoutInflater.from(context), parent, false)
        return MovieViewHolder(binding)
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        with(holder) {

            with(moviesData[position]) {
                binding.tvMovieName.text = title
            }
        }
    }
}

class MovieViewHolder(val binding: ItemMovieBinding) : RecyclerView.ViewHolder(binding.root)
于 2020-03-02T15:48:41.193 回答
17

与您通常的做法相比,没有什么真正改变。

class DataAdapter(
    private val context: Context,
    private val picasso: Picasso
) : RecyclerView.Adapter<DataAdapter.ViewHolder>() {
    private var dataList: List<Data> = Collections.emptyList()

    override fun getItemCount() = dataList.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(
        LayoutInflater.from(context).inflate(R.layout.item_list, parent, false)
    )

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(dataList[position])
    }

    fun setData(dataList: List<Data>) {
        this.dataList = dataList
        notifyDataSetChanged()
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        private val binding = ItemListBinding.bind(view)   

        fun bind(data: Data) {
            with(binding) {
                // TODO
                nameTV.text = data.name
                bannerImage.loadWithPicasso(picasso, data.imageUrl)
            }
        }
    }
}
于 2020-03-02T15:55:17.863 回答
4

我在RecyclerView Adapter 类中找到了使用View Binding的最简单方法

class MediaRecyclerViewAdapter: RecyclerView.Adapter<MediaRecyclerViewAdapter.MediaViewHolder>() {


lateinit var list: List<String>

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MediaViewHolder {
    val binding = CardviewItemsRecyclerviewBinding.inflate(LayoutInflater.from(parent.context),parent,false)
    return MediaViewHolder(binding)
}

override fun onBindViewHolder(holder: MediaViewHolder, position: Int) {

    holder.binding.mediaHeadingTextView.text = "Hello"

}

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

class MediaViewHolder(val binding: CardviewItemsRecyclerviewBinding) : RecyclerView.ViewHolder(binding.root) {

   }

}
于 2021-03-22T07:28:45.723 回答
0

我发现这是最简单的:

class RvAdapter() :
    RecyclerView.Adapter<RvAdapter.RvViewHolder>() {
        
    inner class RvViewHolder(val binding: OtherRvItemBinding) :
    RecyclerView.ViewHolder(binding.root)
        
    // Initialise view binding here.
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RvViewHolder {
        val binding =
            OtherRvItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return RvViewHolder(binding)
    }
    
    override fun getItemCount(): Int {
        // TODO: Implement logic to return list size.
        return 0
    }
    
    // Bind view holder.
    override fun onBindViewHolder(holder: RvViewHolder, position: Int) {
        holder.binding.apply {
                // Reference your views from here.
                awesomeTv.text = "Hello World!"
        }
    }    
}
于 2021-09-11T19:26:18.397 回答