vlayout icon indicating copy to clipboard operation
vlayout copied to clipboard

关于VLayout不支持横向线性布局的个人解决方案,有需要的进来看看

Open XXQAQ opened this issue 6 years ago • 44 comments

我觉得横向线性布局在开发中还是一个很常见的需求,VLayout官方不提供这个功能导致要做很多处理,如果处理地不好的话好会导致这部分Adapter不能复用,这对于我这种代码洁癖的人来说还是很苦恼的。 经过再三考虑,我使用了装饰者模式封装了一个横向布局Adapter,外界只需要传入真实的Adapter即可实现横向布局,以下为代码 ` public class VLayoutHorizontalAdapter extends DelegateAdapter.Adapter{

private RecyclerView.Adapter adapter;
private int spanCount = 1;  //横向的列,填1相当于横向线性布局,根据自己的需求更改这个值
private RecyclerView.ItemDecoration decoration;

public VLayoutHorizontalAdapter(RecyclerView.Adapter adapter) {
    this.adapter = adapter;
}

public VLayoutHorizontalAdapter(RecyclerView.Adapter adapter, int spanCount) {
    this.adapter = adapter;
    this.spanCount = spanCount;
}

public VLayoutHorizontalAdapter(RecyclerView.Adapter adapter, int spanCount, RecyclerView.ItemDecoration decoration) {
    this.adapter = adapter;
    this.spanCount = spanCount;
    this.decoration = decoration;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
    RecyclerView rv = new RecyclerView(viewGroup.getContext());
    rv.setLayoutManager(new GridLayoutManager(viewGroup.getContext(),spanCount,RecyclerView.HORIZONTAL,false));
    if (decoration != null) rv.addItemDecoration(decoration);
    rv.setAdapter(adapter);
    return new BaseViewHolder(rv,viewType);
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    adapter.notifyDataSetChanged();
}

@Override
public int getItemCount() {
    return 1;
}

@Override
public LayoutHelper onCreateLayoutHelper() {
    return new LinearLayoutHelper();
}

} `

使用时只需要如下调用 delegateAdapter.addAdapter(new VLayoutHorizontalAdapter(new ReallyAdapter()));

PS:外界不需要持有ReallyAdapter引用,因为VLayoutHorizontalAdapter已经做了处理,更新VLayoutHorizontalAdapter即可更新ReallyAdapter。还有一点就是DelegateAdapter.Adapter继承于RecyclerView.Adapter,具体好处自己体会

XXQAQ avatar May 23 '19 02:05 XXQAQ

难道不会卡顿么,这样添加横向布局

MrZzhouWorld avatar Jun 03 '19 03:06 MrZzhouWorld

难道不会卡顿么,这样添加横向布局

官方Demo中就是这样添加的,只是官方是直接嵌套使用,这样会导致Adapter的复用性太差,我才做了一层封装。日后如果官方出了横向Adapter,可以直接修改继承的父类,切换起来也方便

XXQAQ avatar Jun 03 '19 03:06 XXQAQ

你这里面的BaseViewHolder那里来的?

oksimple avatar Aug 20 '19 07:08 oksimple

你这里面的BaseViewHolder那里来的?

你自己BaseViewHolder 或者 直接使用RecyclerView.ViewHolder

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

大佬 我折腾一下午了,用你这个 recyclerview 死活不显示 会是什么情况呢? 换成什么textview 之类的就没问题

oksimple avatar Aug 20 '19 09:08 oksimple

大佬 我折腾一下午了,用你这个 recyclerview 死活不显示 会是什么情况呢? 换成什么textview 之类的就没问题

你有没有通知VLayoutHorizontalAdapter 更新?

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

只要能 notifyDataSetChanged 的地方 我都调用了

oksimple avatar Aug 20 '19 09:08 oksimple

只要能 notifyDataSetChanged 的地方 我都调用了

贴一下代码,看看你是通知的哪个Adapter更新

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

 //横向的adapter
                            HomeHorizontalAdapter homeHorizontalAdapter = new HomeHorizontalAdapter(list);
                            //
                            VLayoutHorizontalAdapter vLayoutHorizontalAdapter = new VLayoutHorizontalAdapter(homeHorizontalAdapter);
                            
                            adapter.addAdapter(vLayoutHorizontalAdapter);
                        }
                        
                        //这个adapter是DelegateAdapter
                        adapter.notifyDataSetChanged();

oksimple avatar Aug 20 '19 09:08 oksimple

我的 VLayoutHorizontalAdapter 是再for循环中动态new的应为有N组不固定的数据

oksimple avatar Aug 20 '19 09:08 oksimple

//横向的adapter HomeHorizontalAdapter homeHorizontalAdapter = new HomeHorizontalAdapter(list); // VLayoutHorizontalAdapter vLayoutHorizontalAdapter = new VLayoutHorizontalAdapter(homeHorizontalAdapter);

                        adapter.addAdapter(vLayoutHorizontalAdapter);
                    }
                    
                    //这个adapter是DelegateAdapter
                    adapter.notifyDataSetChanged();

`//横向的adapter HomeHorizontalAdapter homeHorizontalAdapter = new HomeHorizontalAdapter(list); // VLayoutHorizontalAdapter vLayoutHorizontalAdapter = new VLayoutHorizontalAdapter(homeHorizontalAdapter); adapter.addAdapter(vLayoutHorizontalAdapter); }

                //更新的时候不可以使用DelegateAdapter,要使用具体的子Adapter
                vLayoutHorizontalAdapter .notifyDataSetChanged();`

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

for (int x = 0; x < 20; i++) { for (int j = 0; j < 10; j++) { list.add("xxxxx"); } //横向的adapter HomeHorizontalAdapter homeHorizontalAdapter = new HomeHorizontalAdapter(list); // VLayoutHorizontalAdapter vLayoutHorizontalAdapter = new VLayoutHorizontalAdapter(homeHorizontalAdapter); adapter.addAdapter(vLayoutHorizontalAdapter); } //这个adapter是DelegateAdapter adapter.notifyDataSetChanged();

oksimple avatar Aug 20 '19 09:08 oksimple

更新 子 adapter 也无效,但是把recyclerview 换成其他控件 就没问题

oksimple avatar Aug 20 '19 09:08 oksimple

//横向的adapter HomeHorizontalAdapter homeHorizontalAdapter = new HomeHorizontalAdapter(list); // VLayoutHorizontalAdapter vLayoutHorizontalAdapter = new VLayoutHorizontalAdapter(homeHorizontalAdapter); adapter.addAdapter(vLayoutHorizontalAdapter); }

                //这个adapter是DelegateAdapter
                adapter.notifyDataSetChanged();
            //更新的时候不可以使用DelegateAdapter,要使用具体的子Adapter
            vLayoutHorizontalAdapter .notifyDataSetChanged();`

//横向的adapter HomeHorizontalAdapter homeHorizontalAdapter = new HomeHorizontalAdapter(list); // VLayoutHorizontalAdapter vLayoutHorizontalAdapter = new VLayoutHorizontalAdapter(homeHorizontalAdapter); adapter.addAdapter(vLayoutHorizontalAdapter); }

                //这个adapter是DelegateAdapter
                adapter.notifyDataSetChanged();

//横向的adapter HomeHorizontalAdapter homeHorizontalAdapter = new HomeHorizontalAdapter(list); // VLayoutHorizontalAdapter vLayoutHorizontalAdapter = new VLayoutHorizontalAdapter(homeHorizontalAdapter); adapter.addAdapter(vLayoutHorizontalAdapter); } //更新的时候不可以使用DelegateAdapter,要使用具体的子Adapter vLayoutHorizontalAdapter .notifyDataSetChanged();

``

更新 子 adapter 也无效,但是把recyclerview 换成其他控件 就没问题

最外层的RecyclerView是不是MatchParent

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

是 match_parent

oksimple avatar Aug 20 '19 09:08 oksimple

你先试试 不用VLayoutHorizontalAdapter ,先用VLayout自带的GridLayoutHelper,看看能不能显示

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

我再添加横向recyclerview 之前还添加了其他 layouthelp SingleLayoutHelper 都能正常显示 但是到了 添加 横向的这里 就显示不了 GridLayoutHelper我用过 没问题。

oksimple avatar Aug 20 '19 09:08 oksimple

把 onCreateViewHolder 中的 recyclerview 替换成 其他控件 也没问题。

oksimple avatar Aug 20 '19 09:08 oksimple

public class VLayoutHorizontalAdapter extends DelegateAdapter.Adapter {

private RecyclerView.Adapter adapter;
private RecyclerView.ItemDecoration decoration;

public VLayoutHorizontalAdapter(RecyclerView.Adapter adapter) {
    this.adapter = adapter;
}

public VLayoutHorizontalAdapter(RecyclerView.Adapter adapter,RecyclerView.ItemDecoration decoration) {
    this.adapter = adapter;
    this.decoration = decoration;
}

@Override
public LayoutHelper onCreateLayoutHelper() {
    return new LinearLayoutHelper();
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    RecyclerView rv = new RecyclerView(parent.getContext());
    rv.setLayoutManager(new GridLayoutManager(parent.getContext(),1,RecyclerView.HORIZONTAL,false));
    if (decoration != null) rv.addItemDecoration(decoration);
    rv.setAdapter(adapter);
    return new RecyclerView.ViewHolder(rv){};
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    adapter.notifyDataSetChanged();
}

@Override
public int getItemCount() {
    return 1;
}

}

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

把 onCreateViewHolder 中的 recyclerview 替换成 其他控件 也没问题。

看看试试我楼上的评论

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

把 onCreateViewHolder 中的 recyclerview 替换成 其他控件 也没问题。

你把你的HomeHorizontalAdapter 拿出来我再看看

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

public class HomeHorizontalAdapter extends BaseQuickAdapter<String, BaseViewHolder> {

public HomeHorizontalAdapter(List<String> data) {
    super(R.layout.adapter_popular_item, data);
}

@Override
protected void convert(BaseViewHolder helper, String s) {
    helper.setText(R.id.name_tv, s);
}

}

oksimple avatar Aug 20 '19 09:08 oksimple

这个 HomeHorizontalAdapter 我换成没有封装过的 adapter 也不行。

oksimple avatar Aug 20 '19 09:08 oksimple

你上面的代码 我试了 还是不行

oksimple avatar Aug 20 '19 09:08 oksimple

都是 match_parent

oksimple avatar Aug 20 '19 09:08 oksimple

你上面的代码 我试了 还是不行

R.layout.adapter_popular_item的 根布局 的Width是多少

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

都是 match_parent

你先用wrap 试试

XXQAQ avatar Aug 20 '19 09:08 XXQAQ

wrap_content 或者 固定值 都不行

oksimple avatar Aug 20 '19 09:08 oksimple

我开始怀疑是动态高度引起的,结果 我换成了 ScrollView 就没问题

oksimple avatar Aug 20 '19 09:08 oksimple

你的意思是,把RecyclerVIew换成ScrollView ?就没问题

XXQAQ avatar Aug 20 '19 10:08 XXQAQ