android-fragments 有没有办法在一个RecyclerView中使用多个带有MergeAdapter的布局管理器?

nszi6y05  于 2022-11-14  发布在  Android
关注(0)|答案(3)|浏览(158)

我正在使用合并适配器(也称为ConcatAdapter)
https://medium.com/androiddevelopers/merge-adapters-sequentially-with-mergeadapter-294d2942127a
但是我需要做的是第一个适配器应该显示网格布局,第二个显示线性布局,所以,如果我这样做

val headerAdapter = HeaderAdapter(requireContext(), Header("TestHeader"))
        val dividerViewAdapter = DividerViewAdapter(requireContext())
        val animalAdapter = DividerViewAdapter(requireContext(),DataSource.animalList) // -> this should be shown as a GridLayout
        val mergeAdapter = MergeAdapter(headerAdapter,dividerViewAdapter,animalAdapter)
        test_rv.layoutManager = LinearLayoutManager(requireContext())
        test_rv.adapter = mergeAdapter

现在,这段代码运行良好,但由于它有一个linearlayoutmanager,所有内容都将显示为LinearLayout,在其中,我的animalAdapter将不会按照我想要的方式显示。
有没有办法为不同的适配器设置不同的布局管理器,以我想要的方式显示数据?

mccptt67

mccptt671#

事实上,我是这样解决的:

class HorizontalContainerAdapter(private val lifecycleOwner: LifecycleOwner, val adapter : ListAdapter<*, *>) :
ListAdapter<String, HorizontalContainerAdapter.Holder>(diffCallback) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
    val inflater = LayoutInflater.from(parent.context)
    return Holder(DataBindingUtil.inflate(inflater, R.layout.item_horizontal_container, parent, false), adapter)
}

override fun onBindViewHolder(holder: Holder, position: Int) {
    holder.binding.lifecycleOwner = lifecycleOwner
}

override fun getItemViewType(position: Int): Int {
    return R.layout.item_horizontal_container
}

override fun getItemCount(): Int {
     return 1
}

class Holder(val binding: ItemHorizontalContainerBinding, adapter: ListAdapter<*, *>) : RecyclerView.ViewHolder(binding.root) {

    init {
        binding.recyclerView.layoutManager = LinearLayoutManager(binding.recyclerView.context, LinearLayoutManager.HORIZONTAL, false)
        binding.recyclerView.adapter = adapter
    }
}

companion object {
    val diffCallback by lazy {
        object :
            DiffUtil.ItemCallback<String>() {

            override fun areItemsTheSame(oldItem: String, newItem: String): Boolean {
                return oldItem == newItem
            }

            override fun areContentsTheSame(oldItem: String, newItem: String): Boolean {
                return oldItem == newItem
            }
        }
    }
}

Mergeadapter / ConcatAdapter with Horizontal and Vertical Layouts
祝你好运

2w2cym1i

2w2cym1i2#

不,没有办法让多个LayoutManager与一个RecyclerView关联。LayoutManager是针对整个RecyclerView的,而不是与Adapter关联。换句话说:适配器没有布局管理器;取而代之的是,X1 M5 N1 X具有布局管理器,并且它还具有适配器。
如果不是这种情况,那么如果在一行的中间从GridLayoutManager切换到LinearLayoutManager,行为就会变得非常奇怪。
对于您的特定方案,线性布局中的行(对于垂直列表)或列(对于水平列表)与跨度数等于跨度数的网格中的项目相同,因此,如果正确设置了跨度数,则只需对整个RecyclerView使用GridLayoutManager即可。

pdsfdshx

pdsfdshx3#

GridLayoutManager.setSpanSizeLookup对于类似的情况非常有用。您可以使用GridLayoutManager,而不是使用多个布局管理器。
例如,当我依次添加1个垂直对象、3个水平对象和4个垂直对象时,代码将如下所示:

ConcatAdapter concatAdapter = new ConcatAdapter(
        verticalItemAdapter, // contains  1 vertical item
        horizontalItemAdapter, // contains 3 horizontal items
        verticalItemAdapter, // contains 4 vertical items
);
int verticalSpanCount = 1;
int horizontalSpanCount = 3;

GridLayoutManager layoutManager = new GridLayoutManager(context, horizontalSpanCount);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        return concatAdapter.getWrappedAdapterAndPosition(position).first instanceof HorizontalItemAdapter
                ? verticalSpanCount 
                : horizontalSpanCount;
    }
});
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(concatAdapter);

相关问题