阿里开源了一个Rv的多布局的替代方案alibaba/vlayout,简单用了下。总体感觉比较适合复杂多布局多嵌套的页面,像xx宝,xx东什么的那种,首页花里胡哨的一堆。(小萌新一直喜欢国外很多简约风格的以及高质量推送的那种,但是不是很花的那种,哈哈。。。)
如果是简单的一些应用,像小萌新参与开发的新闻类(界面简洁清爽的那种), 工具类,学习教育类的那种。感觉可以自己多布局基本就能满足需求。 之前小萌新不是也尝试做了通用适配器的封装么MonkeyLei:Android-RecyclerView通用适配器BaseAdapter-多绘制类型-Base相关类,目前该通用适配器以及MonkeyLei:Android-Retrofit2+Rxjava2之网络通用请求-初步封装-完善优化数据【对象】请求 以及运用到了新项目中,之前的有个工程已经重构完成,并经过测试。回头再琢磨琢磨看看!!!感觉还是不够呀。。其中有看过一个通用适配器的开源方案,小萌新的大体思路倒还蛮像的,哈哈!
vlayout一直没用,现在想起要试试。一方面可能新的App(具体年后定)会有用到。另外就是也看了一些个培训机构,有涉及到这个。所以对于小萌新来说,还是值得试试的。我的试法就是快速体验,各种博客网站巴拉巴拉,没去仔细看官方了。 使用过程看看能不能体会个流程,机制啥的!
走你...可以按照github上面的示例,注意的是MyAdapter的实现;另外可以下载官方demo来看,那样就妥了!
主要分三步:
1. 找到Rv,设置一个VirtualLayoutManager
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
2. 创建一个Adapter列表,并添加一个布局适配器,比如LinearLayoutAdapter
//设置Adapter列表
List<DelegateAdapter.Adapter> adapters = new LinkedList<>();
///< 线性布局
LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper();
linearLayoutHelper.setMarginBottom(100);
adapters.add(new LinearLayoutAdapter(this,linearLayoutHelper,2){
@Override
public void onBindViewHolder(MainViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
if (position == 0) {
holder.tv1.setText("linearLayout1");
}
}
});
///< 再添加一个
adapters.add(new LinearLayoutAdapter(this,linearLayoutHelper,2){
@Override
public void onBindViewHolder(MainViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
if (position == 0) {
holder.tv1.setText("linearLayout2");
}
}
});
3. 实现LinearLayoutAdapter
package com.example.hl;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.alibaba.android.vlayout.DelegateAdapter;
import com.alibaba.android.vlayout.LayoutHelper;
import com.example.lieyun_android.myapplication.R;
public class LinearLayoutAdapter extends DelegateAdapter.Adapter<LinearLayoutAdapter.MainViewHolder> {
private Context context;
private LayoutHelper layoutHelper;
private RecyclerView.LayoutParams layoutParams;
private int count = 0;
public LinearLayoutAdapter(Context context, LayoutHelper layoutHelper, int count) {
this(context, layoutHelper, count, new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 300));
}
public LinearLayoutAdapter(Context context, LayoutHelper layoutHelper, int count, @NonNull RecyclerView.LayoutParams layoutParams) {
this.context = context;
this.layoutHelper = layoutHelper;
this.count = count;
this.layoutParams = layoutParams;
}
@Override
public LayoutHelper onCreateLayoutHelper() {
return layoutHelper;
}
@Override
public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MainViewHolder(LayoutInflater.from(context).inflate(R.layout.layout,parent,false));
}
@Override
public void onBindViewHolder(MainViewHolder holder, int position) {
holder.tv1.setText(Integer.toString(position));
}
@Override
public int getItemCount() {
return count;
}
static class MainViewHolder extends RecyclerView.ViewHolder {
public TextView tv1;
public MainViewHolder(View itemView) {
super(itemView);
tv1 = (TextView) itemView.findViewById(R.id.item_tv1);
}
}
}
布局文件laoyut.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/item_tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
基本上就可以啦..加几个Adaper就对应嵌套了几个布局,大概这个意思。
image根据小萌新之前封装通用适配器的感受,其实就是多Adapter的LinkedList列表就相当于Rv多布局的类型,每个类型对应了一套View(也就是多个数量的Item被包装到了Adapter中)。小萌新的通用适配器是将类型type放到了List<Data>的每个Data中,根据type的分别进行不同布局的加载。
如果需要多种不同类型的布局,就往List<DelegateAdapter.Adapter> adapters中添加即可。只要把不同类型的适配器Adapter准备好就行。
image2. 比如再来个GridLayoutHelper类型的
///< 网格布局 - 构造中传入相应的列的数量
GridLayoutHelper gridHelper = new GridLayoutHelper(5);
gridHelper.setMarginTop(30);
//gridHelper.setSpanCount(5);
//设置垂直方向条目的间隔
gridHelper.setVGap(5);
//设置水平方向条目的间隔
gridHelper.setHGap(5);
gridHelper.setMarginLeft(30);
gridHelper.setMarginRight(30);
gridHelper.setMarginBottom(30);
//自动填充满布局,在设置完权重,若没有占满,自动填充满布局
gridHelper.setAutoExpand(true);
adapters.add(new GridHelperAdapter(null, gridHelper));
package com.example.hl;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.alibaba.android.vlayout.DelegateAdapter;
import com.alibaba.android.vlayout.LayoutHelper;
import com.alibaba.android.vlayout.layout.GridLayoutHelper;
import com.example.lieyun_android.myapplication.R;
import java.util.List;
public class GridHelperAdapter extends DelegateAdapter.Adapter<GridHelperAdapter.MainViewHolder>{
private List<String> imgList;
private GridLayoutHelper gridHelper;
public GridHelperAdapter(List<String> imgList, GridLayoutHelper gridHelper){
this.imgList = imgList;
this.gridHelper = gridHelper;
}
@Override
public LayoutHelper onCreateLayoutHelper() {
return gridHelper;
}
@Override
public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_grid_layout, parent, false);
return new MainViewHolder(view);
}
@Override
public void onBindViewHolder(MainViewHolder holder, int position) {
holder.iv1.setBackgroundResource(R.drawable.aaa);
}
@Override
public int getItemCount() {
return 11;
}
static class MainViewHolder extends RecyclerView.ViewHolder {
public ImageView iv1;
public MainViewHolder(View itemView) {
super(itemView);
iv1 = (ImageView) itemView.findViewById(R.id.item_iv1);
}
}
}
item_grid_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/item_iv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
也就oK了
image3. 然后像吸顶的StickyLayoutHelper也是类似做法,依葫芦画瓢,都差不多。
List<String> mList = new ArrayList<>();
mList.add("test");
StickyLayoutHelper stickyHelper = new StickyLayoutHelper();
adapters.add(new StickyLayoutAdapter(mList, stickyHelper));
package com.example.hl;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.alibaba.android.vlayout.DelegateAdapter;
import com.alibaba.android.vlayout.LayoutHelper;
import com.alibaba.android.vlayout.layout.StickyLayoutHelper;
import com.example.lieyun_android.myapplication.R;
import java.util.List;
public class StickyLayoutAdapter extends DelegateAdapter.Adapter<StickyLayoutAdapter.MainViewHolder>{
private List<String> imgList;
private StickyLayoutHelper stickyLayoutHelper;
public StickyLayoutAdapter(List<String> imgList, StickyLayoutHelper stickyLayoutHelper){
this.imgList = imgList;
this.stickyLayoutHelper = stickyLayoutHelper;
}
@Override
public LayoutHelper onCreateLayoutHelper() {
return stickyLayoutHelper;
}
@Override
public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_stick_layout, parent, false);
return new MainViewHolder(view);
}
@Override
public void onBindViewHolder(MainViewHolder holder, int position) {
holder.iv1.setBackgroundResource(R.drawable.aaa);
}
@Override
public int getItemCount() {
return imgList.size();
}
static class MainViewHolder extends RecyclerView.ViewHolder {
public ImageView iv1;
public MainViewHolder(View itemView) {
super(itemView);
iv1 = (ImageView) itemView.findViewById(R.id.item_iv1);
}
}
}
item_stick_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="20dp">
<ImageView
android:id="@+id/item_iv1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
差不多就是酱紫。重点是除了使用,我们要了解大概的原理。我们发现实现它的Adapter流程和我们之前普通的RecyclerView.Adapter差不多,不过阿里给做了一层包装,增加了额外的处理,可能重点区别就是:
@Override
public LayoutHelper onCreateLayoutHelper() {
return stickyLayoutHelper;
}
1. 首先被调用地方 - 这就是代理Adapter的设置方式,将多个Adapter进行了存储,具体不跟了,后面再学习下。就是觉得多布局被它封装成了多个Adapter的方式(以往我们的多布局是一个Adapter,根据type加载不同布局,形成了一对多;阿里貌似给搞成了一对一,但是一个就包含N个条目,那它怎么实现的渲染,这个要看VirtualLayoutManager - 还是后续看看源码吧,我都胡说这么多了,不能再胡说了..):
image image2. 此Adapter是:
image简单过到这里,具体怎么渲染,还不懂,呵呵哒! 总归目标就是一个Rv实现多布局渲染,I Think!
参考链接都给友情转发下:
阿里开源库VLayout的使用笔记 - totond的博客 - CSDN博客
[Android]使用VLayout,你可能遇到的问题 - 嵌套横向滚动的Rv的参考
网友评论