如何使用Data Binding将ID为recycler_view的RecyclerView与Activity绑定
1. 前置配置(未开启DataBinding需先配置)
在模块级build.gradle的android代码块中添加配置启用DataBinding:
buildFeatures { dataBinding true }
2. 改造MainActivity实现RecyclerView绑定
替换原有setContentView和findViewById逻辑,直接通过DataBinding生成的绑定实例访问RecyclerView:
class MainActivity : AppCompatActivity() { // 声明Activity布局的绑定实例 lateinit var binding: ActivityMainBinding lateinit var movieadapter: MovieItemAdapter lateinit var api: Api lateinit var repository: MovieRepository lateinit var movieViewModel: MovieViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 初始化DataBinding实例,替代原有setContentView binding = DataBindingUtil.setContentView(this, R.layout.activity_main) // 绑定生命周期所有者,后续配合LiveData使用时必需 binding.lifecycleOwner = this // 直接通过binding实例访问recycler_view,无需findViewById binding.recyclerView.layoutManager = LinearLayoutManager(this) movieadapter = MovieItemAdapter() binding.recyclerView.adapter = movieadapter api = Api.getInstance() repository = MovieRepository(api) movieViewModel = ViewModelProvider(this, MovieFactory(repository)) .get(MovieViewModel::class.java) movieViewModel.makeApiCall() movieViewModel.listMovie.observe(this, Observer { movieadapter.setMovieItem(it) }) } }
3. 修复适配器缺失逻辑
原有onBindViewHolder为空实现,补全绑定逻辑:
override fun onBindViewHolder(holder: MovieViewHolder, position: Int) { holder.bind(listMovie[position]) // 立即执行绑定,避免列表滑动时数据展示错乱 holder.binding.executePendingBindings() }
4. 补充图片绑定逻辑(可选,需显示电影封面时添加)
如果需要加载imageUrl对应的封面图,添加自定义BindingAdapter实现图片加载,以Glide为例:
首先创建绑定适配器类:
object ImageBindingAdapter { @BindingAdapter("imageUrl") @JvmStatic fun loadImage(imageView: ImageView, url: String?) { if (!url.isNullOrEmpty()) { Glide.with(imageView.context) .load(url) .into(imageView) } } }
之后在movie_item.xml的ImageView控件中添加绑定属性:
<ImageView android:layout_width="70dp" android:layout_height="70dp" android:id="@+id/img_view" app:imageUrl="@{model.imageUrl}" />
5. 协程逻辑优化(可选,避免内存泄漏)
ViewModel中直接使用官方提供的viewModelScope管理协程,无需自行创建CoroutineScope和管理Job:
class MovieViewModel(private val repository: MovieRepository):ViewModel() { var listMovie = MutableLiveData<List<MovieItem>>() fun makeApiCall(){ viewModelScope.launch(Dispatchers.IO) { val response = repository.getAllMovies() if (response != null){ listMovie.postValue(response.body()) } } } }
内容的提问来源于stack exchange,提问作者Aditya Sinha
相关产品推荐
相关产品推荐

