言归正传,我们首先来看看实现的效果:
这篇文章主要讲的是底部瀑布流的实现,如果对于上面的布局存在疑问的话,请转移我的另一篇博客:
言归正传:
看到这种效果图的第一反应便是,卧槽,这什么鬼,布局太复杂了。
这种反应很正常,因为木有从一个宏观的角度去分析问题。依据之前博客的思路,我们根据不同的ItemType进行区分不同类型的条目,然后根据Type创建不同的ViewHolder,接着再进行setData()的数据绑定。介绍这个思路是为了告诉大家,总体的思路不变,这时候,有的同学可能会问了,江老师(某田姓同学一直这么叫我,哈哈),这下面的条目难道是和之前横向布局一样,定义一个ScrollView往里面添加相应的条目吗,No,Too young,Too Simple。
下面实际上是另外一个RecyclerView,那么某田姓同学又会问了,“这里的高度是怎么做出来这种效果的,直接的布局做不出来啊?”,这里我们就要介绍一种新的布局管理器,那就是:
StaggeredGridLayoutManager 瀑布流式布局管理器(可以实现类似于GridView的表格效果):详见hongyang大神的博客:点击打开链接
嗯,理清楚了思路之后,我们来进行相关的书写吧:
1.首先我们需要定义底部瀑布流的Adapter:MyRecyclerViewChileAdapter
老步骤,就不必多说了:
首先,创建构造方法以及定义相关的属性:
//定义常用的参数
private Context ctx;
private ArrayList<String> arrayList;
private List<Integer> mHeights = new ArrayList<>();
public MyRecyclerViewChileAdapter(Context ctx, ArrayList<String> arrayList) {
this.ctx = ctx;
this.arrayList = arrayList;
}
然后呢,重写几个重要的方法:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder holder = null;
holder = new ViewHolder1(View.inflate(ctx, R.layout.item4_layout, null));
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((ViewHolder1) holder).setData(position);
}
@Override
public int getItemCount() {
return arrayList.size();
}
这几个方法再不会的同学就要打屁股了,哈哈。
然后,重点来了,我们的高度差是怎么设定的呢?高度是根据返回条目中的图片高度设定的,但是这里由于没有服务,所以产生的条目高度都是我随机生成的,为了展示效果所以夸张了点儿,哈哈。
//为每种布局定义自己的ViewHolder
public class ViewHolder1 extends RecyclerView.ViewHolder {
private TextView home_read_title;
private ImageView home_read_piv_iv;
public ViewHolder1(View itemView) {
super(itemView);
if (mHeights.size() <= getItemCount()) {
mHeights.add((int) (500 + Math.random() * 400));
}
home_read_title = (TextView) itemView.findViewById(R.id.home_read_title);
home_read_piv_iv = (ImageView) itemView.findViewById(R.id.home_read_piv_iv);
home_read_title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
随机数获取之后,我们便可以随心所欲的设置高度啦!!!
public void setData(int position) {
ViewGroup.LayoutParams layoutParams = home_read_piv_iv.getLayoutParams();
if (mHeights.size() > position)
layoutParams.height = mHeights.get(position);
else layoutParams.height = 589;
home_read_piv_iv.setLayoutParams(layoutParams);
home_read_title.setText(arrayList.get(position) + "啊哈哈哈哈哈哈");
}
注意一下,这里的setData()方法是在之前打的RecyclerView中的onBindViewHolder方法中调用的,而产生随机高度的方法也就是构造方法是在onCreateViewHolder中调用的。
下面贴出来完整的Adapter的代码:
package com.marsjiang.complexrecyclerview.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.marsjiang.complexrecyclerview.R;
import java.util.ArrayList;
import java.util.List;
/**
* RecyclerView的Adapter
* Created by Jiang on 2017-07-17.
*/
public class MyRecyclerViewChileAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
//定义常用的参数
private Context ctx;
private ArrayList<String> arrayList;
private List<Integer> mHeights = new ArrayList<>();
public MyRecyclerViewChileAdapter(Context ctx, ArrayList<String> arrayList) {
this.ctx = ctx;
this.arrayList = arrayList;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder holder = null;
holder = new ViewHolder1(View.inflate(ctx, R.layout.item4_layout, null));
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((ViewHolder1) holder).setData(position);
}
@Override
public int getItemCount() {
return arrayList.size();
}
//为每种布局定义自己的ViewHolder
public class ViewHolder1 extends RecyclerView.ViewHolder {
private TextView home_read_title;
private ImageView home_read_piv_iv;
public ViewHolder1(View itemView) {
super(itemView);
if (mHeights.size() <= getItemCount()) {
mHeights.add((int) (500 + Math.random() * 400));
}
home_read_title = (TextView) itemView.findViewById(R.id.home_read_title);
home_read_piv_iv = (ImageView) itemView.findViewById(R.id.home_read_piv_iv);
home_read_title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
public void setData(int position) {
ViewGroup.LayoutParams layoutParams = home_read_piv_iv.getLayoutParams();
if (mHeights.size() > position)
layoutParams.height = mHeights.get(position);
else layoutParams.height = 589;
home_read_piv_iv.setLayoutParams(layoutParams);
home_read_title.setText(arrayList.get(position) + "啊哈哈哈哈哈哈");
}
}
}
好的接下来就是设定Adapter和设置布局管理器的方法了,这里参照了某个大神的写法,不好意思了,博客地址我没找到:
package com.marsjiang.complexrecyclerview.widget;
import android.content.Context;
import android.graphics.PointF;
import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.DisplayMetrics;
/**
* Created by Jiang on 2017/1/9.
* 用于改变recycleview加载更多结束以后向上滑动一段距离是,平滑, 可以控制时间
*/
public class MyStaggerGrildLayoutManger extends StaggeredGridLayoutManager {
private float MILLISECONDS_PER_INCH = 1f;
private Context contxt;
public MyStaggerGrildLayoutManger(Context context, int spanCount, int orientation) {
super(spanCount, orientation);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
// return MyStaggerGrildLayoutManger.this.computeScrollVectorForPosition(targetPosition);
return null;
}
//This returns the milliseconds it takes to
//scroll one pixel.
@Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.density;
//返回滑动一个pixel需要多少毫秒
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
public void setSpeedSlow() {
//自己在这里用density去乘,希望不同分辨率设备上滑动速度相同
//0.3f是自己估摸的一个值,可以根据不同需求自己修改
MILLISECONDS_PER_INCH = contxt.getResources().getDisplayMetrics().density * 0.3f;
}
public void setSpeedFast() {
MILLISECONDS_PER_INCH = contxt.getResources().getDisplayMetrics().density * 0.03f;
}
}
打完,收工,跑一跑,惊喜不断,哈哈,这样可比之前addHeader以及addFooter实现复杂条目布局来的方便的多了。嗯,就到这里,有点儿困了!
技术在于分享与提升,哈哈,代码地址: 点击打开链接 欢迎Star