记录一下以前自己代码中用到过代码效果,也做个备份,省的以后代码找不到,大家也可以参考参考,也许看过网上某些笔记,但是不记得了链接了,有问题可以联系本人
以下会写从布局到java代码以及用到的工具类都写出来,供大家参考
一、首先上两个布局xml文件
activity_waterfall
<?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"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recylerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp" />
</LinearLayout>
item_waterfall 适配器中item布局
<?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="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
<ImageView
android:id="@+id/imgRV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="center" />
<TextView
android:id="@+id/recycler_item_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:textColor="#F80F40"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin" />
</LinearLayout>
其中最外层 LinearLayout 和imageview的高度必须设置为 wrap_content
二、上java代码文件
-
WaterfallActivity.java
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.bumptech.glide.Glide;
import com.example.mytest.R;
import com.example.mytest.adapter.RecyclerAdapter;
import com.example.mytest.bean.WaterfullBean;
import com.example.mytest.util.AGlide;
import com.example.mytest.view.StaggeredDividerItemDecoration;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* 描述 实现瀑布流效果
* by creat wyp 2020/3/13
*/
public class WaterfallActivity extends BaseActivtiy {
@BindView(R.id.recylerview)
RecyclerView recyclerView;
private RecyclerAdapter recyclerAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public int getLayoutId() {
return R.layout.activity_waterfall;
}
@Override
protected void initView() {
}
@Override
protected void initData() {
recyclerAdapter = new RecyclerAdapter(getData(),this);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);//防止item交换位置
recyclerView.setLayoutManager(layoutManager);
//以下三行去掉 RecyclerView 动画代码,防止闪烁
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
recyclerView.getItemAnimator().setChangeDuration(0);
recyclerView.setAdapter(recyclerAdapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
layoutManager.invalidateSpanAssignments();//防止第一行到顶部有空白
}
});
}
@Override
public void initOther() {
}
private List<WaterfullBean> getData() {
String[] names = {"晓风残月","杨柳依依","二月春分","杏花诗雨随风至,","中华少年不屈不挠,少年强中国强,壮我中国魂","铁马冰河","庐山迷雾","竹林幽潭","大唐雄风","暖风袭的游人醉","一切疫情都是纸老虎",
"我自横刀向天笑,去留肝胆两昆仑","春如一夜春风留春痕","人生若只是初见","风雨不曾动我心","皎皎明月","流觞","若水三千"};
String[] imgHeight={"260","300","100","220","180","260","200","320","200","300","250","280","150","240","200","280"};
String path1 = "http://img0.imgtn.bdimg.com/it/u=1595128334,82706458&fm=26&gp=0.jpg";
String path2 = "http://img2.imgtn.bdimg.com/it/u=3663359702,1992818410&fm=26&gp=0.jpg";
String path3 = "http://img1.imgtn.bdimg.com/it/u=1935467811,195414982&fm=26&gp=0.jpg";
String path4 = "http://img1.imgtn.bdimg.com/it/u=2939811527,4256764476&fm=26&gp=0.jpg";
String path5 = "http://img5.imgtn.bdimg.com/it/u=2433540234,3071973675&fm=11&gp=0.jpg";
String path6 = "http://img0.imgtn.bdimg.com/it/u=2252193884,3728807126&fm=11&gp=0.jpg";
String path7 = "http://img5.imgtn.bdimg.com/it/u=3404931913,2642312894&fm=26&gp=0.jpg";
String path8 = "http://img2.imgtn.bdimg.com/it/u=3656563200,458275370&fm=26&gp=0.jpg";
String path9 = "http://img3.imgtn.bdimg.com/it/u=272626499,1769311702&fm=11&gp=0.jpg";
String path10 = "http://img2.imgtn.bdimg.com/it/u=3656563200,458275370&fm=26&gp=0.jpg";
String path11 = "http://img0.imgtn.bdimg.com/it/u=1641821854,2305393622&fm=15&gp=0.jpg";
String path12 = "http://img0.imgtn.bdimg.com/it/u=1641821854,2305393622&fm=15&gp=0.jpg";
String path13 = "http://img.mp.itc.cn/upload/20161019/177f8df712764c3ea2355a5dfed785da_th.gif";
String path14 = "http://img3.imgtn.bdimg.com/it/u=547082689,2172122564&fm=11&gp=0.jpg";
String path15 = "http://img4.imgtn.bdimg.com/it/u=4213113895,2522756905&fm=11&gp=0.jpg";
String path16 = "http://img4.imgtn.bdimg.com/it/u=3043589085,1773439913&fm=26&gp=0.jpg";
String[] imgUrs={path1,path2,path3,path4,path5,path6,path7,path8,path9,path10,path11,path12,path13,path14,path15,path16};
List<WaterfullBean> waterfullList = new ArrayList<>();
for (int i = 0; i <16 ; i++) {
WaterfullBean bean=new WaterfullBean();
bean.img=imgUrs[i];
bean.tv=names[i];
bean.imgHeight = imgHeight[i];
waterfullList.add(bean);
}
return waterfullList;
}
//获取随机字符串的 测试textview数据值 可以测试用 不用就删除
private String getRandomLengthName(String name) {
Random random = new Random();
int length = random.nextInt(10) + 1;//取0~20之间的一个随机数
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length; i++) {
builder.append(name);//字符串拼接
}
return builder.toString();
}
}
实际上项目中让后台服务给返回图片的地址和图片的宽高,我现在写测试就自己定义了 String[] imgHeight高,至于宽在适配器中固定写了350
androidxGoogle 2018 IO 大会推出了 ,用于替换原来的 Android扩展库,将原来的android.*
替换成androidx.*
我自己用的是Android新的扩展库 AndroidX,如果用还是android.的可以自己导入对应的库,关于
ButterKnife的注解获取id 就不说了,估计现在也很普及,网上很多资料不清楚可以自己看
RecyclerView.LayoutManager提供了三个实现类其中LinearLayoutManager 现行管理器,支持横向、纵向,GridLayoutManager 网格布局管理器,StaggeredGridLayoutManager 瀑布就式布局管理器,有兴趣的可以细细研究一下,关于瀑布流就是用StaggeredGridLayoutManager
代码中注意以下:
防止item交换位置
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
以下三行去掉 RecyclerView 动画代码,防止闪烁
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
recyclerView.getItemAnimator().setChangeDuration(0);
2、RecyclerAdapter
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.mytest.R;
import com.example.mytest.bean.WaterfullBean;
import com.example.mytest.util.ScreenUtils;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* 描述 瀑布流适配器
* by creat wyp 2020/3/19
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.LinearHolder> {
private List<WaterfullBean> list;
private Context context;
public RecyclerAdapter(List<WaterfullBean> list,Context context){
this.context=context;
this.list=list;
}
@NonNull
@Override
public LinearHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.item_waterfall, parent,false);
//new一个我们的ViewHolder,findViewById操作都在LinearHolder的构造方法中进行了
LinearHolder simpleViewHolder = new LinearHolder(view);
simpleViewHolder.setIsRecyclable(true);
return simpleViewHolder;
}
@Override
public void onBindViewHolder(@NonNull LinearHolder holder, int position) {
holder.recycler_item.setText(list.get(position).tv);
//动态设置控件宽高
//先算出item的宽度,给RecyclerView设置完间隔后,屏幕宽度-间隔*3 就是两个item的宽度和了,
// 故 itemWidth=(ScreenWidth-间隔*3)/2 ,换算过程,记得只有最终结果转int,计算过程用float,防止莫名其妙的四舍五入导致height过多偏差。
ViewGroup.LayoutParams layoutParams=holder.imgRV.getLayoutParams();
float itemWidth=(ScreenUtils.getScreenWidth(holder.itemView.getContext())-5*3)/2;
layoutParams.width= (int) itemWidth;
float scale=(itemWidth+0f)/350;//这儿是图片的宽度 目前写死了 自己可以根据自己实际情况替换掉
layoutParams.height= (int) (Integer.parseInt(list.get(position).imgHeight)*scale);
holder.imgRV.setLayoutParams(layoutParams);
Glide.with(context).load(list.get(position).img).override(layoutParams.width,layoutParams.height).into(holder.imgRV);
}
@Override
public int getItemCount() {
return list.size();
}
class LinearHolder extends RecyclerView.ViewHolder {
@BindView(R.id.recycler_item_tv)
TextView recycler_item;
@BindView(R.id.imgRV)
ImageView imgRV;
public LinearHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
3、WaterfullBean
/**
* 描述
* by creat wyp 2020/3/19
*/
public class WaterfullBean {
public String tv;
public String img;
public String imgHeight;
}
到此就测试的瀑布流就完成了,至于用到项目中自己实际调式即可
如果发现了问题欢迎大家留言,我及时修改。毕竟改了自己以后我自己也可以copy.