关于V_Layout的使用总结

VLayout在处理RecyclerView多布局时使用了分块Adapter,也就是一个RecyclerView存在多个Adapter。最后通过一个总的Adapter整合了所有。

核心类

VirtualLayoutManager

重写了RecyclerView的原生LinearLayoutManager,来间接管理各个Adapter,所以使用VLayout必然要配置VirtualLayoutManager。

VirtualLayoutManager virtualLayoutManager = new VirtualLayoutManager(this);

   VirtualLayoutManager virtualLayoutManager = new VirtualLayoutManager(this);
   recyclerView.setLayoutManager(virtualLayoutManager);

LayoutHelper

如果VirtualLayoutManager是间接管理各个Adapter,那么 LayoutHelper就是负责管理自己所属的Adapter。VLayout的多样化也正是体现在了LayoutHelper子类的多样化。

  • LinearLayoutHelper(线性布局)
  • GridLayoutHelper(网格布局)
  • FixLayoutHelper(固定布局)
  • ScrollFixLayoutHelper(可选的固定布局)
  • FloatLayoutHelper(浮动布局)
  • ColumnLayoutHelper(格栅布局)
  • SingleLayoutHelper(通栏布局)
  • OnePlusNLayoutHelper(一拖N布局)
  • StickyLayoutHelper(吸边布局)
  • StaggeredGridLayoutHelper(瀑布流布局)

VLayout提供了这10种布局效果,基本上已经可以应付我们碰到的各种需求。

创建一种布局Adapter

public class LinearAdapter extends DelegateAdapter.Adapter<LinearAdapter.MyHolder> {


    List<String> data;


    public LinearAdapter(List<String> data) {
        this.data = data;
    }


    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {


        TextView textView = new TextView(parent.getContext());

        textView.setBackgroundColor(Color.WHITE);

        textView.setLayoutParams(new ViewGroup.LayoutParams(-1, 100));

        return new MyHolder(textView);
    }

    @Override
    public void onBindViewHolder(MyHolder holder, int position) {

        holder.textView.setText(data.get(position));


    }

    @Override
    public int getItemCount() {
        return data.size();
    }


    @Override
    public int getItemViewType(int position) {
        return 0;
    }


    @Override
    public LayoutHelper onCreateLayoutHelper() {

        LinearLayoutHelper l = new LinearLayoutHelper();

        return l;

    }
    
   //View被回收时调用
    @Override
    public void onViewRecycled(@NonNull MyHolder holder) {
        super.onViewRecycled(holder);
    }

	//由于VLayout将整个布局分割开每个Item之间已经没有了关联,所以VLayout提供了这个方法 offsetTotal反应了总的position
    @Override
    protected void onBindViewHolderWithOffset(MyHolder holder, int position, int offsetTotal) {
        super.onBindViewHolderWithOffset(holder, position, offsetTotal);
    }

    public static class MyHolder extends RecyclerView.ViewHolder {


        TextView textView;

        public MyHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView;
        }

    }

}

继承于DelegateAdapter.Adapter用法与RecyclerView.Adapter相同,这里多了个硬性重写方法onCreateLayoutHelper() 返回一个layoutHelper,也就是指定当前Adapter需要使用哪种类型。 我们指定一个线性的。

组装各个Adapter

        VirtualLayoutManager virtualLayoutManager = new VirtualLayoutManager(this);
        recyclerView.setLayoutManager(virtualLayoutManager);

        DelegateAdapter delegateAdapter = new DelegateAdapter(virtualLayoutManager, true);

        delegateAdapter.addAdapter(new LinearAdapter(getData()));
        delegateAdapter.addAdapter(new FixAdapter());
 
        recyclerView.setAdapter(delegateAdapter);

        RecyclerView.RecycledViewPool pool = new RecyclerView.RecycledViewPool();
        pool.setMaxRecycledViews(0, 20);

        recyclerView.setRecycledViewPool(pool);

通过DelegateAdapter将各个DelegateAdapter.Adapter包装起来实现了RecyclerView的多样化。如果一屏内相同类型的 View 个数比较多,需要设置一个合适的大小,防止来回滚动时重新创建 View使用自定义的复用池。

LayoutHelper属性详情

公共属性
    layoutHelper.setItemCount(4);// 设置布局里Item个数
    layoutHelper.setPadding(10,10,10,10);// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离
    layoutHelper.setMargin(10,10,10,10);// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离
    layoutHelper.setBgColor(Color.GRAY);// 设置背景颜色
    layoutHelper.setAspectRatio(6);// 设置设置布局内每行布局的宽与高的比
私有属性
 	 linearLayoutHelper.setDividerHeight(1); // 设置每行Item的距离   

    gridLayoutHelper.setWeights(new float[]{40, 30, 30});//设置每行中 每个网格宽度 占 每行总宽度 的比例
    gridLayoutHelper.setVGap(20);// 控制子元素之间的垂直间距
    gridLayoutHelper.setHGap(20);// 控制子元素之间的水平间距
    gridLayoutHelper.setAutoExpand(false);//是否自动填充空白区域
    gridLayoutHelper.setSpanCount(3);// 设置每行多少个网格
    // 通过自定义SpanSizeLookup来控制某个Item的占网格个数
    gridLayoutHelper.setSpanSizeLookup(new GridLayoutHelper.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            if (position > 7 ) {
                return 3;
                // 第7个位置后,每个Item占3个网格
            }else {
                return 2;
                // 第7个位置前,每个Item占2个网格
            }
        }
    });		

	fixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);// 设置吸边时的基准位置(alignType)
	fixLayoutHelper.setX(30);// 设置基准位置的横向偏移量X
	fixLayoutHelper.setY(50);// 设置基准位置的纵向偏移量Y

	scrollFixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);// 设置吸边时的基准位置(alignType)
	scrollFixLayoutHelper.setX(30);// 设置基准位置的横向偏移量X
	scrollFixLayoutHelper.setY(50);// 设置基准位置的纵向偏移量Y
	scrollFixLayoutHelper.setShowType(ScrollFixLayoutHelper.SHOW_ON_ENTER);// 设置Item的显示模式 

	SHOW_ALWAYS:永远显示(即效果同固定布局)
	SHOW_ON_ENTER:默认不显示视图,当页面滚动到该视图位置时才显示;
	SHOW_ON_LEAVE:默认不显示视图,当页面滚出该视图位置时才显示

	floatLayoutHelper.setDefaultLocation(300,300);// 设置布局里Item的初始位置

 	columnLayoutHelper.setWeights(new float[]{30, 40, 30});// 设置该行每个Item占该行总宽度的比例

	stickyLayoutHelper.setStickyStart(true);
	// true = 组件吸在顶部
	// false = 组件吸在底部
	
	stickyLayoutHelper.setOffset(100);// 设置吸边位置的偏移量

	staggeredGridLayoutHelper.setLane(3);// 设置控制瀑布流每行的Item数
	staggeredGridLayoutHelper.setHGap(20);// 设置子元素之间的水平间距
	staggeredGridLayoutHelper.setVGap(15);// 设置子元素之间的垂直间距

参照

Android开源库V - Layout:淘宝、天猫都在用的UI框架,赶紧用起来吧!

原创文章 30 获赞 10 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_36043263/article/details/88758133