android - 使用MVVM在RecyclerView的网格和线性之间切换的更好方法是什么?

标签 android kotlin mvvm android-recyclerview

我在片段中有一个RecyclerView和一个FAB。
FAB在GRID和LINEAR之间切换RecyclerView的布局。

我在ViewModel中有一个枚举类。

enum class LAYOUT { GRID, LINEAR }

private val _layout = MutableLiveData<LAYOUT>()
val layout: LiveData<LAYOUT>
     get() = _layout

并且该片段在ViewModel中观察布局值的MutableLiveData。

现在,我有了2个ListAdapter,一个用于Grid,一个用于Linear,从而使其工作。
下面是我的片段代码。
        val gridAdapter = MovieGridAdapter()

        viewModel.layout.observe(viewLifecycleOwner, Observer {
            if (it == GRID) {
                binding.recyclerViewMovie.adapter = gridAdapter
                binding.recyclerViewMovie.layoutManager = GridLayoutManager(context, 3)
            } else {
                binding.recyclerViewMovie.adapter = linearAdapter
                binding.recyclerViewMovie.layoutManager = LinearLayoutManager(context)
            }
        })

        viewModel.trendingMovies.observe(viewLifecycleOwner, Observer {
            it?.let {
                gridAdapter.submitList(it)
                linearAdapter.submitList(it)
            }
        })

我觉得这不是最好的方法,因为我现在在片段中有2个适配器,并且我需要为两个适配器都提交SubmitList。

如果有更好的方法,请告诉我,谢谢!

最佳答案

您无需使用两个适配器,一个适配器即可完成工作

class ProductListAdapter(
private val listener: OnProductListener) : PagedListAdapter<Product, ProductViewHolder>( PRODUCT_COMPARATOR ) {

var layoutId: Int = R.layout.list_item_product

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

    val product = getItem(position)

    with(holder) {
        bindTo(product,true)
        product.let { product ->
            itemView.setOnClickListener {
                product.product_id?.let { it1 -> listener.onProductSelected(it1) }
            }
        }
    }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder {
    val view =
        LayoutInflater.from(parent.context)
            .inflate(layoutId, parent, false)

    return ProductViewHolder(view)
}

override fun getItemViewType(position: Int): Int {
    return position
}

fun setLayoutResourceId(layoutId: Int) {
    this.layoutId = layoutId
}


companion object {

    private val PRODUCT_COMPARATOR = object : DiffUtil.ItemCallback<Product>() {
        override fun areItemsTheSame(oldItem: Product, newItem: Product): Boolean =
            TextUtils.equals(
                oldItem.product_id,
                newItem.product_id
            ) 

        override fun areContentsTheSame(
            oldItem: Product,
            newItem: Product
        ): Boolean =
            oldItem == newItem

    }

 }

}

在片段中定义适配器
private var productsAdapter: ProductListAdapter = ProductListAdapter(this)

viewModel.trendingMovies.observe(viewLifecycleOwner, Observer {
        it?.let {
            productsAdapter.submitList(it)

        }
    })

showList
  private fun showList() {
    rv_products.layoutManager = LinearLayoutManager(activity, RecyclerView.VERTICAL, false)
    productsAdapter.setLayoutResourceId(R.layout.list_item_list_product)
    rv_products.adapter = productsAdapter

}

showGrid
private fun showGrid() {
    rv_products.layoutManager = GridLayoutManager(activity, 3)
    productsAdapter.setLayoutResourceId(R.layout.list_item_grid_product)
    rv_products.adapter = productsAdapter
}

关于android - 使用MVVM在RecyclerView的网格和线性之间切换的更好方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61999705/

相关文章:

c# - WPF MVVM中组合框的默认值

c# - 将 ObservableCollection 绑定(bind)到 ListBox 的选定项

c# - 当没有当前项时,如何禁用绑定(bind)到当前项的 ICommand 的按钮?

java - 格式化 google api 客户端 DateTime 时出现 "Cannot format given Object as a Date"错误

java - 找不到给定名称的文件

kotlin - 如何在 GitHub Actions 上运行 Kotlin 脚本?

android - Android Gradle插件仅支持Kotlin Gradle插件1.3.10及更高版本

java - 从一个 Activity 传递一个长类型变量并在另一个 Activity 中接收它并将其显示在 TextView 中

android - 就像来自Android应用的youtube视频

java - 为什么在 Kotlin 类中实现 Cloneable 接口(interface)会导致 "error: no interface expected here"?