如何在适配器中做最新的喷气背包"View binding",绑定视图?



如何在适配器中执行最新的jetpack"视图绑定",以自动绑定视图。我没有使用findVeiwById、Butterknife或Kotlin合成???我已经使用了新的视图绑定,并且对于Activity和Fragment运行良好。在build.gradle文件中启用viewBinding后,我可以看到ActivityHomeBinding和FragmentHomeBinding文件。此外,我看到了所使用的项xml的类ItemListBinding,即item_list.xml

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
}

基本适配器:希望在此处使用视图绑定。我可以看到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()
}
}

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

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)
}
}

找到另一个来解决

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)

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

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)
}
}
}
}

我在RecyclerView Adapter类中找到了使用视图绑定的最简单方法

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) {
}
}

我发现这是最简单的:

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!"
}
}    
}

我使用的这个模板也与点击事件集成:


class BannerAdapter(private val listener: OnCategoryClickListener) :
ListAdapter<Banner, BannerAdapter.BannerViewHolder>(DiffCallBack()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BannerViewHolder {
val binding = ItemRecyclerviewCategoriesSearchBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return BannerViewHolder(binding)
}
override fun onBindViewHolder(holder: BannerViewHolder, position: Int) {
val currentItem = getItem(position)
holder.bind(currentItem)
}
inner class BannerViewHolder(private val binding: ItemRecyclerviewCategoriesSearchBinding) :
RecyclerView.ViewHolder(binding.root) {
init {
binding.root.setOnClickListener {
val position = absoluteAdapterPosition
if (position != RecyclerView.NO_POSITION){
val banner = getItem(position)
listener.onCategoryClick(banner.link_type, banner.link)
}
}
}
fun bind(banner: Banner) {
binding.apply {
Glide.with(itemView.context)
.load(banner.media.url)
.centerCrop()
.transition(DrawableTransitionOptions.withCrossFade())
.error(R.drawable.ic_broken_image)
.into(imageCategory)
}
}
}
interface OnCategoryClickListener {
fun onCategoryClick(type: String, link: String)
}
private class DiffCallBack : DiffUtil.ItemCallback<Banner>() {
override fun areItemsTheSame(oldItem: Banner, newItem: Banner) =
oldItem == newItem
override fun areContentsTheSame(oldItem: Banner, newItem: Banner) =
oldItem.media == newItem.media
}
}

最新更新