广告
返回顶部
首页 > 资讯 > 移动开发 >Android RecyclerView实现瀑布流,图片自适应高度,不闪烁,解决位置交换
  • 874
分享到

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

图片recyclerview瀑布瀑布流自适应Android 2022-06-06 13:06:17 874人浏览 安东尼
摘要

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

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

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

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


activity_waterfall


item_waterfall 适配器中item布局

其中最外层 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;

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 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 = "/file/imgs/upload/202206/06/3pyfpaazdjj.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 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;

public class RecyclerAdapter extends RecyclerView.Adapter {
    private List list;
    private Context context;
    public RecyclerAdapter(List 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

public class WaterfullBean {
    public String tv;
    public String img;
    public String imgHeight;
}

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

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


作者:csdnwangyong


--结束END--

本文标题: Android RecyclerView实现瀑布流,图片自适应高度,不闪烁,解决位置交换

本文链接: https://www.lsjlt.com/news/29236.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作