最近在学习vlayout,虽然该框架已经没有在维护了,但是在我们的项目中还是在使用的,但是发现在博客上关于vlayout介绍的文章也比较少,刚接触的时候我也是无从下手,因此在看了官网的例子和属性介绍之后,打算写一篇文章来讲一下vlayout的简单使用。(本文是仿官网demo来进行的,但是官网的不是很好理解,有兴趣的同学也可以直接看官网)
vlayout简介
VirtualLayout 是一个针对 RecyclerView 的 LayoutManager 扩展,主要提供一整套布局方案和布局间的组件复用的问题。怎么说呢,就是可以通过一个RecyclerView来实现一个复杂的布局。如下图所示,就比如淘宝的首页可以滑动的区域就是通过vlayout来实现的。

准备工作
在build.gradle文件中导入依赖,这里的版本号可以去官网找最新的。vlayout官网
implementation 'com.alibaba.android:vlayout:1.3.0@aar'在gradle.properties文件中加上
android.enableJetifier=true
然后准备好布局文件 activity_main.xml。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/main_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#aaaaaa"
android:clipToPadding="true"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:requiresFadingEdge="none"
android:scrollbars="vertical"/>
</androidx.constraintlayout.widget.ConstraintLayout>vlayout的使用
首先先创建一个简单的viewHolder和adapter:
SubAdapter.java:
public class SubAdapter extends DelegateAdapter.Adapter<SubViewHolder> {
private LayoutHelper layoutHelper;
private int itemCount;
public SubAdapter(LayoutHelper layoutHelper, int itemCount) {
this.layoutHelper = layoutHelper;
this.itemCount = itemCount;
}
@Override
public LayoutHelper onCreateLayoutHelper() {
return layoutHelper;
}
@NonNull
@Override
public SubViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
return new SubViewHolder(layoutInflater.inflate(R.layout.item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull SubViewHolder holder, int position) {
}
@Override
protected void onBindViewHolderWithOffset(SubViewHolder holder, int position, int offsetTotal) {
super.onBindViewHolderWithOffset(holder, position, offsetTotal);
holder.setText(String.valueOf(offsetTotal));
VirtualLayoutManager.LayoutParams layoutParams = new VirtualLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
holder.itemView.setLayoutParams(new ViewGroup.LayoutParams(layoutParams));
}
@Override
public int getItemCount() {
return itemCount;
}
}SubViewHolder.java:
public class SubViewHolder extends RecyclerView.ViewHolder {
public static volatile int existing = 0;
public static int createdTimes = 0;
public SubViewHolder(@NonNull View itemView) {
super(itemView);
createdTimes++;
existing++;
}
public void setText(String title) {
((TextView) itemView.findViewById(R.id.title)).setText(title);
}
@Override
protected void finalize() throws Throwable {
existing--;
super.finalize();
}
}以及他们的布局文件item.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:background="#CCCCCC"
android:textColor="#999999"
android:textSize="22sp"
android:textStyle="bold"/>
</FrameLayout>这个ViewHolder和Adapter的样式可以自定义,这里的话用的是官方demo中的样式。
然后就是activity中进行处理,以下是MainActivity的代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.main_view);
//1.首先创建一个VirtualLayoutManager
VirtualLayoutManager virtualLayoutManager = new VirtualLayoutManager(this);
//2.再创建一个DelegateAdapter
DelegateAdapter delegateAdapter = new DelegateAdapter(virtualLayoutManager);
//3.创建一个adapterList
List<DelegateAdapter.Adapter> adapterList = new ArrayList<>();
//4.创建对应的layoutHelper并存放在adapterList中,这里创建了一个LinearLayoutHelper,构造函数中的参数为每个子项的间距
LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper(20);
//SubAdapter中的参数第一个是对应的layoutHelper,第二个是子item个数
adapterList.add(new SubAdapter(linearLayoutHelper, 10));
//5.将adapterList作为参数传入delegateAdapter
delegateAdapter.addAdapters(adapterList);
recyclerView.setLayoutManager(virtualLayoutManager);
recyclerView.setAdapter(delegateAdapter);
}
}这样的话我们就搭建好了一个拥有LinearLayoutHelper的容器了。这个时候运行起来:

就可以得到一个有10个item的一个界面了。
如果我们再在adapterList中添加一个拥有5个item并且间距为40的LinearLayoutHelper会是怎样呢?
//该代码要在delegateAdapter.addAdapters(adapterList);这句之前
LinearLayoutHelper linearLayoutHelper2 = new LinearLayoutHelper(40);
adapterList.add(new SubAdapter(linearLayoutHelper2, 5));结果如下图:

可以看到又创建了5个item,其中序号第10项到序号第14项之间的间距就为40了 。
小结
那么以上呢就是vlayout的基本使用方式,但是呢,可以看到第9项和第10项之间的是挨在一起的,这个可以通过改变每个helper的属性来进行布局上的变化。如果想了解更多属性的介绍的,可以提前看这个官方文档去了解更多vlayout的属性。当然下篇的话也是会讲这些属性,有兴趣的同学可以点开主页看下篇哈~
vlayout官方属性方法文档
https://github.com/alibaba/vlayout/blob/master/docs/ATTRIBUTES-ch.md