Fresco+RecyclerView初体验

完美解决大量图片下载卡顿问题 NULL 博文链接:https://chenleijava.iteye.com/blog/1868330 立即下载

目前网上存在好多图片加载框架,主流的框架有Volley、ImageLoader、fresco、Pisasso、glide,但是fresco无疑是最强大的一个图片加载框架,fresco是facebook推出的一款图片加载框架,它的诸多特性:内存管理、图片加载、以及图片的的渐进式加载和动图加载使得它一经推出收到许多公司的青睐。

     fresco框架主要主要由三部分组成:DraweeView、DraweeHierarchy、DraweeController,其中DraweeController通过管理ImagePipeLine实现对于图片的管理,ImagePipeLine采用三级缓存,二级内存缓存、一级磁盘缓存,DraweeHierarchy主要用来储存一些视图数据,DraweeController内部通过DraweeHolder用来组织管理DraweeHierarchy与DraweeView。


fresco采用MVC架构将三部分组织起来:

Model: DraweeHierarchy用于组织和维护最终绘制和呈现的 Drawable对象
View: DraweeView用于显示视图
Controller: DraweeController负责与Imagepipeline交互


接下来我先结合RecyclerView给大家简单介绍下fresco的使用:

首先我们在项目Bulder.gradle中引入fresco的包


接下来就上代码了:

首先初始化fresco,这个过程在Application中初始化,fresco也提供了两种初始化的方法我们可以自由选择,其中双参属的可以用来配置ImagePipeLine的参数。

initialize(Context context)
initialize(Context context, ImagePipelineConfig imagePipelineConfig) 


然后在布局中添加SimpleDraweeView组件:

<span style="font-size:18px;"> 
<LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="100dp"
        android:orientation="horizontal">
        <com.facebook.drawee.view.SimpleDraweeView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/ic_launcher"
            android:id="@+id/item_simpledraweeview">
        </com.facebook.drawee.view.SimpleDraweeView>
        <TextView
            android:id="@+id/text_show"
            android:textSize="16sp"
            android:layout_marginLeft="10dp"
            android:layout_width="fill_parent"
            android:gravity="left|center_vertical"
            android:textColor="#000000"
            android:layout_height="100dp" />

   </LinearLayout></span>

Activity页面:

<pre name="code" class="java">package com.example.pan.frescopro;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.View;

import com.facebook.drawee.view.SimpleDraweeView;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.api.GoogleApiClient;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    public String url1 = "http://www.xywangpan.cn/image/alone.png";
    public String url2 = "http://www.xywangpan.cn/image/biancheng.png";
    public String url3 = "http://www.xywangpan.cn/image/hongloumeng.png";
    public String url4 = "http://www.xywangpan.cn/image/java.png";
    public String url5 = "http://www.xywangpan.cn/image/leiyu.png";
    public String url6 = "http://www.xywangpan.cn/image/pingfandeshijie.png";
    public String url7 = "http://www.xywangpan.cn/image/suanfa.png";
    public String url8 = "http://www.xywangpan.cn/image/yigerendechaosheng.png";
    SimpleDraweeView simpleDraweeView;
    RecyclerView mRecyclerView;
    List<BookBean> datas = new ArrayList<BookBean>();
    RecyclerViewAdapter adapter;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
    }
    public void initData() {
        for (int i=0;i<10000;i++) {
            datas.add(new BookBean("愿有人陪你颠破流离", url1));
            datas.add(new BookBean("一个人的朝圣", url8));
            datas.add(new BookBean("边城", url2));
            datas.add(new BookBean("红楼梦", url3));
            datas.add(new BookBean("JAVA", url4));
            datas.add(new BookBean("雷雨", url5));
            datas.add(new BookBean("平凡的世界", url6));
            datas.add(new BookBean("算法", url7));
        }
    }

    public void initView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        adapter = new RecyclerViewAdapter(datas, getApplicationContext());
        LinearLayoutManager layoutManager=new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.addItemDecoration(new DividerItemDecoration(this,
                DividerItemDecoration.VERTICAL_LIST));
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setAdapter(adapter);
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    public class DividerItemDecoration extends RecyclerView.ItemDecoration {

        private  final int[] ATTRS = new int[]{
                android.R.attr.listDivider
        };

        public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;

        public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

        private Drawable mDivider;

        private int mOrientation;

        public DividerItemDecoration(Context context, int orientation) {
            final TypedArray a = context.obtainStyledAttributes(ATTRS);
            mDivider = a.getDrawable(0);
            a.recycle();
            setOrientation(orientation);
        }

        public void setOrientation(int orientation) {
            if ((orientation != HORIZONTAL_LIST)) {
                if ((orientation != VERTICAL_LIST)) {
                    throw new IllegalArgumentException("invalid orientation");
                }
            }
            mOrientation = orientation;
        }

        @Override
        public void onDraw(Canvas c, RecyclerView parent) {

            if (mOrientation == VERTICAL_LIST) {
                drawVertical(c, parent);
            } else {
                drawHorizontal(c, parent);
            }

        }


        public void drawVertical(Canvas c, RecyclerView parent) {
            final int left = parent.getPaddingLeft();
            final int right = parent.getWidth() - parent.getPaddingRight();

            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                RecyclerView v = new RecyclerView(parent.getContext());
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                        .getLayoutParams();
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }

        public void drawHorizontal(Canvas c, RecyclerView parent) {
            final int top = parent.getPaddingTop();
            final int bottom = parent.getHeight() - parent.getPaddingBottom();

            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                        .getLayoutParams();
                final int left = child.getRight() + params.rightMargin;
                final int right = left + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }

        @Override
        public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
            if (mOrientation == VERTICAL_LIST) {
                outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
            } else {
                outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
            }
        }
    }
}




RecyclerViewAdapter
RecylerViewAdapter.java

<pre name="code" class="java">package com.example.pan.frescopro;

import android.content.Context;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.drawable.ScalingUtils;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import java.util.List;

/**
 * Created by pan on 2016/8/2.
 */
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
    List<BookBean> strs;
    Context context;

    public RecyclerViewAdapter(List<BookBean> strs, Context context) {
        this.strs = strs;
        this.context = context;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View v = inflater.inflate(R.layout.fresco_item, parent, false);
        return new ViewHolder(v);
    }

    Uri uri;

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.mtextshow.setText(strs.get(position).getName());
        Log.d("Tag", strs.get(position).getUrl().toString());
        System.out.println("--------" + strs.get(position).getUrl().toString());
        uri = Uri.parse(strs.get(position).getUrl());
        holder.msimpleDraweeView.setController(controller);
        holder.msimpleDraweeView.setImageURI(uri);//通过调用simpleDraeeView的setImageUrI(UrI)方法设置图片
    }

    @Override
    public int getItemCount() {
        return strs.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView mtextshow;
        SimpleDraweeView msimpleDraweeView;
        public ViewHolder(View init) {
            super(init);
            mtextshow = (TextView) init.findViewById(R.id.text_show);
            msimpleDraweeView = (SimpleDraweeView) init.findViewById(R.id.item_simpledraweeview);
            //设置宽高比例
            msimpleDraweeView.setAspectRatio(1f);
            //设置对其方式

            msimpleDraweeView.getHierarchy().setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER);
        }
    }

    @Override
    public int getItemViewType(int position) {
        return strs.get(position).getType();
    }
}

运行效果如下(加载效果还是很流畅的):

那么大家有没有想过什么保证了fresco加载上千张图片而不溢出呢?大家是不是想到了ImageLoader的缓存机制了,ImageLoader里面使用Lrucahe通过LinkHashMap实现最近最久算法,保证在内存超出限定值是及时的移除最久未使用的Bitmap,但是fresco又是怎么实现的呢?

其实在Android5.0之前fresco将Bitmap存于ashmem这块内存中而不是存在于堆中,由于在堆中会频繁的触发GC,这样当内存不够是会清除一些数据,但是ashmen这块内存是归Linux内核去管理,它内部有一个引用计数器,他会在内存不够时,优先移除引用数为0的Bitmap,这样就保证了内存不会被溢出,

它内部采用三级缓存策略:

1、首先会在解码后的Bitmap中去找,找到后就直接使用。

2、然后没有在缓存中找到就在未解码的缓存中去找,找到后就去解码使用。

3、最后未找到的话就去磁盘中去找,这些图片也是未解码的,找到后需要解码。

最后再没有的话就去网上请求并保存在缓存和磁盘中。

UE5.4像素流送实战:GPU驱动、WebRTC与系统级调优全解析 像素流送是将实时3D渲染画面通过WebRTC编码推流至浏览器的关键技术,其本质是GPU硬件编码(如NVENC)与低延迟网络传输(UDP+BBR)的深度协同。理解其原理需跨越图形API(Vulkan/DX12)、实时音视频(H.264/H.265)、WebRTC信令与NAT穿透四大技术层。技术价值在于突破终端算力限制,支撑远程工业仿真、云VR看房等高交互场景;但落地难点集中于基础设施层——如NVIDIA驱动与UE5.4.3的CUDA Toolkit 12.2兼容性、Linux内核TCP/UDP参数调优、GPU 阅读详情

相关推荐

嵌入式开发:用状态机实现STM32按键消抖,告别阻塞延时

在嵌入式系统开发中,处理异步事件和实时响应是核心挑战。状态机作为一种强大的编程模型,通过定义有限的状态、事件和状态转换规则,将复杂的、非线性的控制逻辑转化为清晰、确定且易于维护的代码结构。其技术价值在于实现逻辑的模块化、异步化和非阻塞化,能显著提升代码的可读性、可扩展性和系统实时性。这一思想广泛应用于协议解析、用户界面交互、传感器数据处理等场景。本文以嵌入式开发中基础的按键处理为例,针对传统“延时消抖”方法会阻塞主循环、影响实时性的痛点,深入讲解如何运用状态机思维重构按键消抖逻辑。通过分析状态机的核心三要素

weixin_33377602的博客 341

Fresco和 RecyclerView 实现瀑布流 <图片是用本地图片来模拟网络图片的>

RecyclerView 实现瀑布流非常的简单,只需要设置布局管理为 StaggeredGridLayoutManager。 0:首先要导入RecyclerView, 然后在布局里面添加RecyclerView, 然后创建item的布局,这个布局可以使用Fresco的SimpleDrawweView,记住要在Application里面进行初始化。 然后创建Adatper,首

Kodulf的专栏 4222

宇树机器人G1二次开发:语音对话、打断与激活功能实现指南

宇树机器人G1是一款功能强大的四足机器人,其开放的SDK和API为开发者提供了广阔的二次开发空间。其中,语音交互是提升机器人智能化水平和用户体验的关键功能。本文将详细介绍如何在宇树机器人G1上进行二次开发,实现。语音打断允许用户在机器人说话时随时中断并输入新指令,这是提升交互自然度的关键功能。三大核心功能,帮助你构建更自然、更智能的人机交互系统。语音识别是将用户的语音输入转换为文本的过程。识别文本后,需要理解用户意图并生成回复。将文本回复转换为语音输出。

m0_52645558的博客 667

Android RecyclerView中用fresco展示圆角图片,点击查看详情(或原生解析)

1.设置条目点击事件 2.在第二页面接收值 完整代码: -----------------MainActivity----------------- package com.example.earl.lianxilianxi; import android.support.v7.app.AppCompatActivity; import android.os.Bundle...

baipenggui_bo 1135

从零开始构建量化价值投资多因子模型

量化价值投资多因子模型的构建目的在于通过系统性的方法,综合考虑多个影响股票价值的因素,以更准确地评估股票的投资价值,为投资者提供科学的投资决策依据。本模型的构建范围涵盖了从因子的选取、数据的处理、模型的建立到模型的评估和优化等一系列过程。通过对历史数据的分析和回测,验证模型的有效性和稳定性,进而应用于实际的投资组合管理中。本文将按照以下结构进行组织:首先介绍量化价值投资和多因子模型的相关背景知识,包括核心概念和联系;接着详细阐述核心算法原理和具体操作步骤,并给出Python代码示例;

AI天才研究院 1249

Unity Addressable资源缓存路径自定义指南:告别C盘爆满烦恼

本文详细介绍了如何自定义Unity Addressable系统的资源缓存路径,解决其默认存储在C盘导致的磁盘空间不足问题。通过配置CacheInitializationSettings并编写编辑器脚本,开发者可以将缓存迁移至项目目录,实现资源的集中管理,提升团队协作效率与开发环境一致性。

pytorch8learner的博客 475

Android:引入Fresco项目解决图片加载乱序的问题

今天玩着自己写的android程序,滑来滑去发现有一些图片的存放顺序出错了,本以为是viewholder出问题,后来发现这是android上常见的问题: 由于GirdView、ListView、RecyclerView等的复用机制,导致快速滑动引起的图片乱序。 其实不仅是图片,视频,checkbox等放入item,在快速滑动都会出现乱序的现象。 办法一: 在adapter的onCr

一天不进步就是退步 2369

Ghost卷积原理与构建YOLOv11的GhostNet变体

本文探讨了在边缘设备部署YOLOv11时使用Ghost卷积进行模型轻量化的实践经验。针对Jetson Nano的4GB内存限制,作者通过替换Backbone中的3x3标准卷积为Ghost卷积,实现了参数减少28%、推理速度提升38%,仅损失1.1%mAP的优化效果。文章详细介绍了Ghost卷积的实现原理、在YOLOv11中的具体替换策略,以及训练调参和部署优化的关键技巧。作者强调轻量化是计算效率与模型性能的权衡,建议工程团队保留原模型和Ghost变体两个版本,根据实际需求灵活切换。Ghost卷积的核心价值在

as1225120794的博客 169

RecyclerView如何实现滑动过程中暂停图片加载

实现列表滑动时,使图片暂停加载,减少列表滑动时出现卡顿现象

Koro1丶的博客 1万+

06 电子内窥镜_用户需求规范

FUNC:功能PERF:性能PHYS:物理特性PACK:包装LABE:标识TRAN:存储和运输LIFE:有效期和寿命TRAI:培训本产品在医疗机构中使用,与自研图像处理器配合使用,用于通过视频监视器提供影像供尿道、膀胱内的观察。

sinat_17832251的博客 54

Qualcomm AI Engine Direct SDK(QNN)的使用介绍

Qualcomm AI Engine Direct SDK,高通新的AI模型推理框架,又名QNN,为AI开发提供统一API的底层框架。通过这个SDK,可以在高通的 CPU/GPU和HTP上对AI模型进行性能加速。2.Qualcomm AI Engine Direct SDK的公开英文文档。1.Qualcomm AI Engine Direct SDK的下载和安装。

u013250861的博客 6974

Fresco获取动图,RecyclerView展示(只展示动图)

**第一步:添加依赖,如** /*recyclerview依赖*/ compile 'com.android.support:recyclerview-v7:26.1.0' /*fresco加载图片*/ compile 'com.facebook.fresco:fresco:0.11.0' /*fresco加载动图*/ compile 'com.fac

love_mysunshine的博客 947

手把手教你从入门到精通C# Modbus通信

本文是《Modbus通信从入门到精通》的导读,本专栏将会详细介绍ModusRTU 、ModbusASCII、ModbusTCP这三种协议的C#实现,由一个高级工程师多年实战经验总结而成,绝对干货!

qq_34059233的博客 1万+

XBanner+recyclerView+ Fresco

package com.bawei.mvp.view; /** * 作者:$yangxiangrong * <p> * 2019/4/22 09:07 */ public interface MainView { void sueccss(int type ,String data); void fail(int type ,String error); } ...

weixin_44297368的博客 390

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Fresco加载Gif写入RecyclerView

依赖 compile 'com.facebook.fresco:fresco:1.5.0' compile 'com.facebook.fresco:animated-gif:1.5.0' compile 'com.android.support:recyclerview-v7:26.1.0'注册public class App extends Application {

这个不能实现 1万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

WindowImageView完全指南:从基础用法到Fresco高级配置

WindowImageView是一款专为RecyclerView设计的创新图片展示控件,它能让图片以独特的"窗口"效果呈现,为Android应用带来更加生动的视觉体验。本文将从基础使用到高级配置,全面介绍如何在项目中集成和优化WindowImageView。 ## 什么是WindowImageView? WindowImageView是一个开源的Android自定义控件,它扩展了传统Image

gitblog_00343的博客 1046

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

retrofit+Fresco+Recyclerview

package com.example.lenvov.myapplication; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.v...

lgz_306752的博客 311

RecyclerView线性布局,表格布局,fresco图片获取,点击删除条目

例:RecyclerView线性布局,表格布局,点击弹出对话框删除条目fresco图片获取添加依赖:dependencies { implementation 'com.android.support:recyclerview-v7:26.1.0' compile 'com.squareup.okhttp3:okhttp:3.4.2' compile 'com.google...

jun_tong的博客 423

Fresco,Retrofit 和 RecyclerView 实现瀑布流

图片是通过Retrofit进行网络请求得到的地址

Kodulf的专栏 2663

fresco+mvp+okhttp+recyclerview多条目

//导包 compile 'com.android.support:recyclerview-v7:27.1.1' compile 'com.facebook.fresco:fresco:1.9.0' compile 'com.squareup.okhttp3:okhttp:3.9.0' compile 'com.google.code.gson:gson:2.8.2'//...

Androidoux98的博客 321

5分钟上手 AI 网页浏览 CLI oc:面向 Claude Code 与 Codex 用户的完整安装教程

oc 是一款面向 AI Agent 的 AI 网页浏览 CLI 工具,它把任意网站变成紧凑的命令行视图:一条 `oc open <url>` 命令,就能让 Claude Code、Codex 这类 Agent 用几百个 token 读完全整网页,而不是吞下数万 token 的原始 HTML。无需浏览器扩展、无需常驻进程,5 分钟即可完成安装与上手。 [![oc AI 网页浏览 CLI:把杂乱原始

gitblog_00118的博客 253

RecyclerView 视频播放列表 用到 retrofit-convert,fresco,SurfaceView

------------------------------------------------------------------------------- 7:RecycleView 首先在dependency 里面添加recycleView,retrofit-convert,fresco 或者直接在build.gradle文件里面的dependencies直接添

Kodulf的专栏 2143

RecyclerView点击 长按 多条目 fresco

compile 'com.android.support:recyclerview-v7:25.1.0' ---------- 主类 package com.bwie.recyclerviewdemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.sup

ZkMao1007的博客 377

Retrofit网络请求+Recyclerview展示数据+Fresco显示图片

//依赖  compile 'com.squareup.retrofit2:retrofit:2.3.0'     compile  'com.squareup.retrofit2:converter-gson:2.3.0'     compile  'com.android.support:recyclerview-v7:26.1.0'     compile 'com.jakewhar

qq_39969337的博客 713

Fresco进阶 图片错位 宽高自适应

一、Fresco图片错位 在recycleview的adapter中 定义了一组view <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/sdv_item_goods_pic1" android:layout_width="@dimen/s2...

天海行者的专栏 9968

294.Fresco

Fresco 是 Facebook 开发的一个强大的 Android 图片加载和显示库。作为一名曾经只使用过 Coil 的 Android 开发者,你会发现 Fresco 提供了更全面的图片处理功能和优化机制。// 创建图片请求.build();// 创建控制器构建器.setAutoPlayAnimations(true) // 自动播放动画(GIF 等).build();// 设置控制器。

2303_79132118的博客 1230
上一篇: Android插件-动态加载
Mr_lu_code
博客等级 码龄12年 13粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值