1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Android RecyclerView实现瀑布流 图片自适应高度 不闪烁 解决位置交换

Android RecyclerView实现瀑布流 图片自适应高度 不闪烁 解决位置交换

时间:2024-05-11 21:06:23

相关推荐

Android  RecyclerView实现瀑布流 图片自适应高度 不闪烁 解决位置交换

记录一下以前自己代码中用到过代码效果,也做个备份,省的以后代码找不到,大家也可以参考参考,也许看过网上某些笔记,但是不记得了链接了,有问题可以联系本人

以下会写从布局到java代码以及用到的工具类都写出来,供大家参考

一、首先上两个布局xml文件

activity_waterfall

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid: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="/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="5dp"android:orientation="vertical"><ImageViewandroid:id="@+id/imgRV"android:layout_width="match_parent"android:layout_height="wrap_content"android:scaleType="center" /><TextViewandroid: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 /3/13*/public class WaterfallActivity extends BaseActivtiy {@BindView(R.id.recylerview)RecyclerView recyclerView;private RecyclerAdapter recyclerAdapter;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Overridepublic int getLayoutId() {return R.layout.activity_waterfall;}@Overrideprotected void initView() {}@Overrideprotected 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() {@Overridepublic void onScrollStateChanged(RecyclerView recyclerView, int newState) {super.onScrollStateChanged(recyclerView, newState);}@Overridepublic void onScrolled(RecyclerView recyclerView, int dx, int dy) {super.onScrolled(recyclerView, dx, dy);layoutManager.invalidateSpanAssignments();//防止第一行到顶部有空白}});}@Overridepublic 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./it/u=1595128334,82706458&fm=26&gp=0.jpg";String path2 = "http://img2./it/u=3663359702,1992818410&fm=26&gp=0.jpg";String path3 = "http://img1./it/u=1935467811,195414982&fm=26&gp=0.jpg";String path4 = "http://img1./it/u=2939811527,4256764476&fm=26&gp=0.jpg";String path5 = "http://img5./it/u=2433540234,3071973675&fm=11&gp=0.jpg";String path6 = "http://img0./it/u=2252193884,3728807126&fm=11&gp=0.jpg";String path7 = "http://img5./it/u=3404931913,2642312894&fm=26&gp=0.jpg";String path8 = "http://img2./it/u=3656563200,458275370&fm=26&gp=0.jpg";String path9 = "http://img3./it/u=272626499,1769311702&fm=11&gp=0.jpg";String path10 = "http://img2./it/u=3656563200,458275370&fm=26&gp=0.jpg";String path11 = "http://img0./it/u=1641821854,2305393622&fm=15&gp=0.jpg";String path12 = "http://img0./it/u=1641821854,2305393622&fm=15&gp=0.jpg";String path13 = "http://img./upload/1019/177f8df712764c3ea2355a5dfed785da_th.gif";String path14 = "http://img3./it/u=547082689,2172122564&fm=11&gp=0.jpg";String path15 = "http://img4./it/u=4213113895,2522756905&fm=11&gp=0.jpg";String path16 = "http://img4./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 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 /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@Overridepublic 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;}@Overridepublic 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);}@Overridepublic 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 /3/19*/public class WaterfullBean {public String tv;public String img;public String imgHeight;}

到此就测试的瀑布流就完成了,至于用到项目中自己实际调式即可

如果发现了问题欢迎大家留言,我及时修改。毕竟改了自己以后我自己也可以copy.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。