Android 为什么onClick方法不';当我';我用的是viewmodel?
我有一个recyclerView,其中的每个元素都有一个分级栏。我尝试对每个元素进行用户评分 我使用的是MVVM架构 这是我现在的代码:Android 为什么onClick方法不';当我';我用的是viewmodel?,android,kotlin,mvvm,android-recyclerview,android-databinding,Android,Kotlin,Mvvm,Android Recyclerview,Android Databinding,我有一个recyclerView,其中的每个元素都有一个分级栏。我尝试对每个元素进行用户评分 我使用的是MVVM架构 这是我现在的代码: <RatingBar android:id="@+id/rating" android:layout_width="wrap_content" android:layout_height="wrap_conte
<RatingBar
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5"
android:stepSize="1"
android:onClick="@{(view) -> listener.rateMovie(view, model)}"
app:layout_constraintTop_toBottomOf="@id/movie_poster"
app:layout_constraintEnd_toEndOf="@id/movie_poster"
app:layout_constraintStart_toStartOf="@id/movie_poster"
/>
override fun rateMovie(
ratingBar: View,
pickedMovieItemViewModel: PickedMovieItemViewModel
) {
ratingBar as RatingBar
val stars: Int = ratingBar.numStars
pickedMovieItemViewModel.rating.set(stars)
}
娱乐电影(
比率栏:视图,
pickedMovieItemViewModel:pickedMovieItemViewModel
) {
额定杆作为额定杆
val stars:Int=ratingBar.numStars
pickedMovieItemViewModel.rating.set(星形)
}
这就是我初始化侦听器的地方:
@BindingAdapter("rated_movies", "listener")
@JvmStatic
fun setItems(
recyclerView: RecyclerView,
items: List<PickedMovieItemViewModel>?,
rateListener: RateListener?
) {
var adapter = recyclerView.adapter
if (adapter == null) {
adapter = RateMoviesAdapter()
recyclerView.adapter = adapter
val layoutManager: RecyclerView.LayoutManager =
LinearLayoutManager(recyclerView.context, LinearLayoutManager.HORIZONTAL, false)
recyclerView.layoutManager = layoutManager
}
if (items != null) {
adapter as RateMoviesAdapter
adapter.updateItems(items)
}
if (items != null && rateListener != null) {
adapter as RateMoviesAdapter
adapter.updateListener(rateListener)
}
}
@BindingAdapter(“分级电影”、“监听器”)
@JvmStatic
趣味套装(
回收视图:回收视图,
项目:列表?,
rateListener:rateListener?
) {
var adapter=recyclerView.adapter
if(适配器==null){
adapter=RateMoviesAdapter()
recyclerView.adapter=适配器
val layoutManager:RecyclerView.layoutManager=
LinearLayoutManager(recyclerView.context,LinearLayoutManager.HORIZONTAL,false)
recyclerView.layoutManager=layoutManager
}
如果(项!=null){
适配器作为速率MoviesAdapter
adapter.updateItems(项目)
}
if(items!=null&&rateListener!=null){
适配器作为速率MoviesAdapter
adapter.updateListener(rateListener)
}
}
这是回收器视图的适配器
class RateMoviesAdapter : RecyclerView.Adapter<RateMoviesAdapter.RateMoviesViewHolder>() {
private lateinit var movies: List<PickedMovieItemViewModel>
private lateinit var listener: RateListener
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RateMoviesViewHolder {
val binding: ItemMovieRatedBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.item_movie_rated,
parent,
false
)
return RateMoviesViewHolder(binding)
}
override fun onBindViewHolder(holder: RateMoviesViewHolder, position: Int) {
val item = movies[position]
holder.bind(item, listener)
}
override fun getItemCount(): Int {
return movies.size
}
fun update(
movies: List<PickedMovieItemViewModel>,
rateListener: RateListener
) {
this.movies = movies
this.listener = rateListener
notifyDataSetChanged()
}
class RateMoviesViewHolder(private val binding: ItemMovieRatedBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: PickedMovieItemViewModel, rateListener: RateListener) {
binding.model = item
binding.listener = rateListener
}
}
}
class RateMoviesAdapter:RecyclerView.Adapter(){
私有lateinit var电影:列表
私有lateinit变量侦听器:RateListener
覆盖视图保持器(
父对象:视图组,
视图类型:Int
):RateMoviesViewHolder{
val绑定:ItemMovieRatedBinding=DataBindingUtil.inflate(
LayoutFlater.from(父上下文),
R.layout.item\u movie\u额定值,
父母亲
假的
)
退货率MoviesViewHolder(绑定)
}
覆盖BindViewHolder(holder:RateMoviesViewHolder,位置:Int){
val项目=电影[位置]
holder.bind(项,侦听器)
}
重写getItemCount():Int{
返回电影大小
}
有趣的更新(
电影:列表,
rateListener:rateListener
) {
这是电影
this.listener=rateListener
notifyDataSetChanged()
}
类别RateMoviesViewHolder(专用val绑定:ItemMovieRatedBinding):
RecyclerView.ViewHolder(binding.root){
趣味绑定(项目:PickedMovieItemViewModel,rateListener:rateListener){
binding.model=项目
binding.listener=rateListener
}
}
}
这是显示回收器视图的布局
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="com.example.moviepicker.presentation.viewmodel.RateMoviesViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".presentation.activity.RateMoviesActivity">
<TextView
android:id="@+id/rate_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin"
android:gravity="center"
android:text="@string/please_give_us_a_review_for_movies_you_have_picked"
android:textColor="@color/red_dark"
android:textSize="@dimen/title_size"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_pickedMovies"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/top_margin"
app:listener="@{viewModel::rateMovie}"
app:rated_movies="@{viewModel.pickedMovies}"
android:foregroundGravity="center"
app:layout_constraintTop_toBottomOf="@id/rate_textView" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/top_margin"
android:layout_marginTop="@dimen/button_top_margin"
android:layout_marginEnd="@dimen/top_margin"
android:layout_marginBottom="@dimen/top_margin"
android:background="@drawable/ic_red_button"
android:onClick="@{() -> viewModel.goMainPage()}"
android:shadowColor="@color/black"
android:shadowDx="1.5"
android:shadowDy="1.3"
android:shadowRadius="10"
android:text="@string/next"
android:textAllCaps="false"
android:textColor="@color/white"
android:textSize="@dimen/text_size"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/rv_pickedMovies" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
从未调用rateMovie方法
我错在哪里?您在recycler的适配器中定义了不同的侦听器,您需要从片段/videmodel传递侦听器,该片段/videmodel在此处实现并重写
YourFragment : Fragment(), RateListener {
val yourAdapter = RateMoviesAdapter(this)
}
其中“this”表示实现的侦听器(接口),并在适配器中应用该侦听器。
然后应该可以工作,因为在RatingBar视图上没有触发OnClick事件,所以我使用了
setOnRatingBarChangeListener()
方法从RatingBar获取回调。并从ItemViewRateBinding
中删除android:onClick=“@{(视图)->listener.rateMovie(视图,模型)}”
。比如:
fun bind(item: PickedMovieItemViewModel, rateListener: RateListener) {
binding.model = item
//binding.listener = rateListener
// Click listener is not working on Rating Bar.
binding.rating.setOnRatingBarChangeListener { ratingBar, rating, fromUser ->
rateListener.rateMovie(ratingBar,item)
}
}
item_view_rate.xml
<layout>
<data>
<variable
name="model"
type="com.adhoc.testapplication.PickedMovieItemViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RatingBar
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5"
android:stepSize="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
请发布相关的回收器视图适配器类。侦听器是否已初始化?我现在已编辑。我认为这是正确的初始化。(我以前是这样使用它的,它是有效的)是的,代码似乎有效。我一行一行地复习,好吧,让我来修正。您还可以发布回收器视图吗?BindingAdapter与有什么关系?好像哪里都没有用过?我贴了。我不知道我做错了什么。谢谢你花这么多时间:D
<!--
android:onClick="@{(view) -> listener.rateMovie(view,model)}"
-->