我有一个fragment
,它有一个垂直的类别选择器(基本上是带有复选框的水平recycleview
),用户可以一次选择一个类别。 fragment
viewmodel
扩展了ViewModel
。
在通过数据绑定实现recycleview adapter
的同时,我注意到我需要使用两种方式的databinding
来保存所选checkbox
(类别)的状态。
我添加了BaseObservable
,它将设置并保存checkbox
的状态,而该状态应能正常工作。现在,我很难说出一次只能检查一个checkbox
的逻辑。
GenreObservable
class GenreObservable : BaseObservable()
{
lateinit var data : Genre
var index : Int=0
var prevIndex : Int = 0
fun bindGenre(index : Int,data : Genre)
{
this.index = index
this.data = data
}
@Bindable
fun getGenreChecked(): Boolean {
return data.selectedGenre
}
fun setGenreChecked(isChecked: Boolean) {
data.selectedGenre = isChecked
if(isChecked)
{
}
notifyPropertyChanged(BR.viewModel)
}
@Bindable
fun getGenreName() : String
{
return data.name!!
}
@Bindable
fun getGenreId() : Int
{
return data.id
}
}
GenreRecycleAdapter
class GenreRecycleAdapter : RecyclerView.Adapter<GenreRecycleAdapter.GenreHolder>(){
private lateinit var data: List<Genre>
private var selectedGenreIndex = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GenreHolder {
val binding: GenreItemBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.genre_item,
parent,
false
)
return GenreRecycleAdapter.GenreHolder(binding)
}
override fun getItemCount(): Int {
return if(::data.isInitialized) data.size else 0
}
override fun onBindViewHolder(holder: GenreHolder, position: Int) {
holder.bind(position,data[position])
}
fun setData(data : List<Genre>)
{
this.data = data
notifyDataSetChanged()
}
fun setCheckedState(index : Int, state : Boolean)
{
data[index].selectedGenre = state
}
class GenreHolder(private val binding: GenreItemBinding) :
RecyclerView.ViewHolder(binding.root) {
private val viewModel = GenreObservable()
fun bind(index : Int, data: Genre) {
viewModel.bindGenre(index,data)
binding.viewModel = viewModel
}
}
}
TopSeriesViewModel
class TopSeriesViewModel : BaseViewModel()
{
val genreName : MutableLiveData<String> = MutableLiveData()
val genreIndex : MutableLiveData<Int> = MutableLiveData()
val genreState : MutableLiveData<Boolean> = MutableLiveData()
val gAdapter : GenreRecycleAdapter = GenreRecycleAdapter()
@Inject
lateinit var topSeriesApi : TopSeriesApi
private var selectedGenreIndex : Int = 0
init {
loadGenres()
}
private fun loadGenres()
{
subscription = topSeriesApi.getGenres(API_KEY_V3,LANG)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe { onRetrievePostListStart() }
.doOnTerminate { onRetrievePostListFinish() }
.subscribe(
{ result->onRetrievePostListSuccess(result) },
{ onRetrievePostListError() }
)
}
fun bindGenre(index : Int,gen : Genre)
{
genreName.value = gen.name
genreIndex.value = index
genreState.value = gen.selectedGenre
}
private fun onRetrievePostListFinish() {
}
private fun onRetrievePostListError() {
Log.d("anton","onRetrievePostListError")
}
private fun onRetrievePostListStart() {
}
private fun onRetrievePostListSuccess(result: GenreList) {
val data = result.genres!!
// val all = Genre(-1,"All",true)///"All" using context
// data.add
data[0].selectedGenre = true
gAdapter.setData(data)
}
val checkedChangeListener = CompoundButton.OnCheckedChangeListener { buttonView, isChecked ->
val checkedIndex : Int = buttonView.tag as Int
// if(selectedGenreIndex!=0)
// {
// gAdapter.setCheckedState(selectedGenreIndex,false)
// }
selectedGenreIndex = checkedIndex
gAdapter.setCheckedState(selectedGenreIndex,isChecked)
// if(!isChecked)
// {
// selectedGenreIndex = 0
// gAdapter.setCheckedState(0,true)
//
// }
// gAdapter.notifyDataSetChanged()
}
}
genre_item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type=".GenreObservable" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<CheckBox
android:id="@+id/mdc_on_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/category_selector"
android:button="@null"
android:checked="@={viewModel.genreChecked}"
android:gravity="center"
android:padding="10dp"
android:tag="@{viewModel.genreId}"
android:text="@{viewModel.genreName}"
android:textColor="@color/category_selected_text_color"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
尽管我已经实现了两种方法OnCheckedChangeListener
,但是我仍需要在viewmodel
中添加databinding
吗?如果没有,我应该在哪里实现逻辑?