Fresco图片加载

 

 

参考Yw_Ambition的博客https://blog.csdn.net/yw59792649/article/details/78921025

参考博客:https://blog.csdn.net/xiaoqiang_0719/article/details/52437780

 

Fresco图片加载的方法在网上有各种各样的方式,我自己看着写了一个自己的方法,包括了自己找的的和用到的总结的一下

Fresco开源地址:https://github.com/facebook/fresco 

Fresco文档地址:https://www.fresco-cn.org

 

依赖Fresco

// 一般依赖:

implementation 'com.facebook.fresco:fresco:1.11.0'

// 如果需要支持gif,再添加:

implementation 'com.facebook.fresco:animated-gif:1.10.0'

权限

<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

 

 

初始化

 

建议在App启动就初始化,记得在清单文件注册Application。

一般初始化:

public class App extends Application {

@Override
public void onCreate() {
super.onCreate();
Fresco.initialize(this);
    }
}

高级初始化-配置缓存文件夹

public class App extends Application {

@Override
public void onCreate() {
super.onCreate();

 //设置磁盘缓存 
DiskCacheConfig image = DiskCacheConfig.newBuilder(this)
.setBaseDirectoryName("images")
.setBaseDirectoryPath(Environment.getExternalStorageDirectory())
.build();

//设置磁盘缓存的配置,生成配置文件  
ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
.setMainDiskCacheConfig(image)
.build();

 //不设置默认传一个参数既可 
Fresco.initialize(this,config);
        }
}

配置缓存SD卡路径,这里涉及到Android6.0运行时权限,有解决方案,我使用的权限管理库是AndPermission(https://github.com/yanzhenjie/AndPermission):

 

首先在Application中判断是否有SD卡权限,如果有则初始化到SD卡,如果没有则采用默认配置:

public class App extends Application {
    private static App app;
    @Override
    public void onCreate() {
        super.onCreate();
        app = this;
        // 如果有SD卡权限则直接初始化到SD卡。
        if (AndPermission.hasPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE))
            initFresco();
        else { // 没有权限,暂时使用默认配置。
            Fresco.initialize(this);
        }
    }
    /**
     * 高级初始话Fresco。
     */
    public void initFresco() {
        // 高级初始化:
        Fresco.initialize(this, ImagePipelineConfig.newBuilder(App.this)
                .setMainDiskCacheConfig(
                        DiskCacheConfig.newBuilder(this)
                                .setBaseDirectoryPath(new File("SD卡的路径..."))
                                .build()
                )
                .build()
        );
    }
    public static App get() {
        return app;
    }
}

然后在SplashActivity申请SD卡权限,已被下次进入App时初始化Fresco时拥有SD卡权限:

public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 申请权限。
        AndPermission.with(this)
                .requestCode(100)
                .permission(Manifest.permission.READ_CALENDAR)
                .send();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String[] permissions, @NonNull int[] grantResults) {
        AndPermission.onRequestPermissionsResult(requestCode, permissions, grantResults, listener);
    }

    /**
     * 权限监听。
     */
    private PermissionListener listener = new PermissionListener() {
        @Override
        public void onSucceed(int requestCode, List<String> grantPermissions) {
            if(requestCode == 100)
                // 启动app:
                startActivity(new Intent(SplashActivity.this, MainActivity.class));
        }

        @Override
        public void onFailed(int requestCode, List<String> deniedPermissions) {
            if(requestCode == 100)
                // 用户不授权,则退出app:
                finish();
        }
    };
}

 

高级初始化-配置网络层为OkHttp

Fresco默认使用HttpURLConnection作为网络层,当然也可以配置OkHttp作为它的网络层,配置OkHttp为它的网络层需要依赖下面的库:

compile "com.facebook.fresco:imagepipeline-okhttp3:0.12.0+"

然后在Application中初始化的时候注意:

/**
 * 初始话Fresco。
 */
public void initFresco() {
    // 你的OkHttpClient根据你的设计来,建议是单例:
    OkHttpClient okHttpClient = new OkHttpClient();
    Fresco.initialize(this, OkHttpImagePipelineConfigFactory.newBuilder(App.this, okHttpClient)
            .setMainDiskCacheConfig(
                    DiskCacheConfig.newBuilder(this)
                            .setBaseDirectoryPath(new File("SD卡的路径..."))
                            .build()
            )
            .build()
    );
}

这里只需要注意原来的ImagePipelineConfig换成了OkHttpImagePipelineConfigFactory,并且需要一个OkHttpClient的对象。

 

加载网络图片、url、assets、res、本地File图片

 

先给出支持的URI格式列表(列表来自fresco-cn.org):

Type

Scheme

Sample

http远程图片

http://或者https://

HttpURLConnection或者OkHttp

本地文件

file://

FileInputStream

Content provider

content://

ContentResolver

res目录下的资源

res://

Resources.openRawResource

asset目录下的资源

asset://

AssetManager

Uri中指定图片数据

data:mime/type;base64,

数据类型必须符合rfc2397规定 (仅支持 UTF-8)

SimpleDraweeView

在使用Fresco时我们一般使用SimpleDraweeView,它也是继承ImageView的:

<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/iv_head_background"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_200"/>

把它当成我们平常使用的ImageView即可,不过我们要注意Fresco不支持wrap_content,需要使用match_parent或者显示指定view宽高,不过可以设置宽高比

<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/simple_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
fresco:viewAspectRatio="2.0"/>

加载http/https远程gif图片

AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(Uri.parse(urlgit))
.setAutoPlayAnimations(true)//是否可以加载动态图
.setOldController(simpleImage.getController())
.build();

simpleImage.setController(controller);

一、加载http/https远程图片

//直接加载

try {

simpleImage.setImageURI(Uri.parse(url));

} catch (Exception e) {

e.printStackTrace();

}

/**
 * 显示http或者https远程图片。
 *
 * @param draweeView imageView。
 * @param url        连接地址。
 */
public static void showUrl(SimpleDraweeView draweeView, String url) {
    try {
        draweeView.setImageURI(Uri.parse(url));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

二、显示本地图片

这里就有个坑了,先看一下下面我写了两个方法,一个需要传入View的实际宽高,一个不需要。上面已经说了,SimpleDraweeView需要在xml中、java中指定它的宽高,或者是使用match_parent。

这里需要注意,1. 如果view指定的宽高不是match_parent则直接调用第二个不需要传入宽高的发那个发,如果为SimpleDraweeView写的宽高是match_parent时,加载图片需要告诉Fresco你的View在屏幕上的实际宽高是多少,否则是不能加载出来的。

比如,你的SimpleDraweeView是全屏的,那么你就填入屏幕的宽高,如果不是全屏,就利用上面讲的方法测量出View的实际宽高后传入。

/**
         * 显示一个本地图片。
         *
         * @param draweeView imageView。
         * @param path       路径。
         * @param width      实际宽。
         * @param height     实际高度。
         */
        public static void showFile(SimpleDraweeView draweeView, String path, int width, int height) {
            try {
                Uri uri = Uri.parse("file://" + path);
                ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                        .setResizeOptions(new ResizeOptions(width, height))
                        .build();
                AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
                        .setOldController(draweeView.getController())
                        .setImageRequest(request)
                        .build();
                draweeView.setController(controller);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

/**
 * 显示本地图片。
 *
 * @param draweeView imageView。
 * @param path       路径。
 */
        public static void showFile(SimpleDraweeView draweeView, String path) {
            try {
                Uri uri = Uri.parse("file://" + path);
                draweeView.setImageURI(uri);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

三、显示res中图片

这里要注意,我们在为res中的图片生成Uri的时候:

Uri uri = Uri.parse("res://包名(任何字符串或者留空)/" + R.drawable.ic_launcher);

所以我们一般留空,因此我们的代码看起来是下面的样子:

/**
 * 显示一个Res中的图片。
 *
 * @param draweeView ImageView。
 * @param resId      资源ID。
 */
public static void showRes(SimpleDraweeView draweeView, @DrawableRes int resId) {
    try {
        // 你没看错,这里是三个///。
        draweeView.setImageURI(Uri.parse("res:///" + resId));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

四、显示ContentProvider图片

/**
 * 显示content provider图片。
 *
 * @param draweeView image view。
 * @param path       路径。
 */
public static void showContentProvider(SimpleDraweeView draweeView, String path) {
    try {
        draweeView.setImageURI(Uri.parse("content://" + path));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

五、显示assets中的图片

/**
 * 显示Assets中的图片。
 *
 * @param draweeView ImageView.
 * @param path       路径。
 */
public static void showAsset(SimpleDraweeView draweeView, String path) {
    try {
        draweeView.setImageURI(Uri.parse("asset://" + path));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

 

一些默认属性的设置

simpleImage.setAspectRatio(1.2f);//改变宽高比

<com.facebook.drawee.view.SimpleDraweeView
        android:layout_width="20dp"
        android:layout_height="20dp"
        fresco:fadeDuration="300" // 淡出时间,毫秒。
        fresco:actualImageScaleType="focusCrop" // 等同于android:scaleType。
        fresco:placeholderImage="@color/wait_color" // 加载中…时显示的图。
        fresco:placeholderImageScaleType="fitCenter" // 加载中…显示图的缩放模式。
        fresco:failureImage="@drawable/error" // 加载失败时显示的图。
        fresco:failureImageScaleType="centerInside" // 加载失败时显示图的缩放模式。
        fresco:retryImage="@drawable/retrying" // 重试时显示图。
        fresco:retryImageScaleType="centerCrop" // 重试时显示图的缩放模式。
        fresco:progressBarImage="@drawable/progress_bar" // 进度条显示图。
        fresco:progressBarImageScaleType="centerInside" // 进度条时显示图的缩放模式。
        fresco:progressBarAutoRotateInterval="1000" // 进度条旋转时间间隔。
        fresco:backgroundImage="@color/blue" // 背景图,不会被View遮挡。

        fresco:roundAsCircle="false" // 是否是圆形图片。
        fresco:roundedCornerRadius="1dp" // 四角圆角度数,如果是圆形图片,这个属性被忽略。
        fresco:roundTopLeft="true" // 左上角是否圆角。
        fresco:roundTopRight="false" // 右上角是否圆角。
        fresco:roundBottomLeft="false" // 左下角是否圆角。
        fresco:roundBottomRight="true" // 左下角是否圆角。
        fresco:roundingBorderWidth="2dp" // 描边的宽度。
        fresco:roundingBorderColor="@color/border_color" 描边的颜色。
/>

xml中可以配置,在Java代码中也是可以配置的,我这里列出一部分API:

        SimpleDraweeView simpleDraweeView = new SimpleDraweeView(context);
        simpleDraweeView.setLayoutParams(new ViewGroup.LayoutParams(-1, -1));

        GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(context.getResources())
                .setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER)
                .setPlaceholderImage(R.drawable.fresco_failed)
                .setPlaceholderImageScaleType(ScalingUtils.ScaleType.FIT_XY)
                .setFailureImage(R.drawable.fresco_failed)
                .setPressedStateOverlay(ResCompat.getDrawable(R.drawable.transparent_half_1))
                .setFailureImageScaleType(ScalingUtils.ScaleType.FIT_XY)
                .build();
        simpleDraweeView.setHierarchy(hierarchy);

圆形图片带白色的边:

<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/iv_user_fund_user_head"
android:layout_width="80dp"
android:layout_height="80dp"
fresco:roundAsCircle="true" // 圆形图片。
fresco:roundingBorderColor="@color/white" // 白色描边。
fresco:roundingBorderWidth="2dp"/> // 描边宽度。

Fresco高斯模糊:

/**
 * 以高斯模糊显示。
 *
 * @param draweeView View。
 * @param url        url.
 * @param iterations 迭代次数,越大越魔化。
 * @param blurRadius 模糊图半径,必须大于0,越大越模糊。
 */
public static void showUrlBlur(SimpleDraweeView draweeView, String url, int iterations, int blurRadius) {
    try {
        Uri uri = Uri.parse(url);
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                .setPostprocessor(new IterativeBoxBlurPostProcessor(iterations, blurRadius))
                .build();
        AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
                .setOldController(draweeView.getController())
                .setImageRequest(request)
                .build();
        draweeView.setController(controller);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

//参考博客:https://blog.csdn.net/xiaoqiang_0719/article/details/52437780

Fresco-Java代码实现圆形圆角效果

圆角图—setRoundingParams:

设置圆角图只有一种方式,但它有六种方法:

限定符和类型

方法

说明

static RoundingParams

fromCornersRadius(float radius)

设置圆角半径

static RoundingParams

fromCornersRadii(float[] radii)

分别设置左上角、右上角、左下角、右下角圆角半径

static RoundingParams

fromCornersRadii(float topLeft, float topRight, float bottomRight, float bottomLeft)

分别设置左上角、右上角、左下角、右下角圆角半径

RoundingParams

setCornersRadius(float radius)

设置圆角半径

RoundingParams

setCornersRadii(float[] radii)

分别设置左上角、右上角、左下角、右下角圆角半径

RoundingParams

setCornersRadii(float topLeft, float topRight, float bottomRight, float bottomLeft)

分别设置左上角、右上角、左下角、右下角圆角半径

//圆形

RoundingParams roundingParams = new RoundingParams();

roundingParams.setRoundAsCircle(true);

GenericDraweeHierarchy hierarchy = GenericDraweeHierarchyBuilder.newInstance(getResources())

.setRoundingParams(roundingParams)

.build();

simpleImage.setHierarchy(hierarchy);

//圆角

RoundingParams roundingParams1 = new RoundingParams();

roundingParams1.setRoundAsCircle(false);

roundingParams1.setCornersRadius(20);

GenericDraweeHierarchy hierarchy1 = GenericDraweeHierarchyBuilder.newInstance(getResources())

.setRoundingParams(roundingParams1)

.build();

simpleImage.setHierarchy(hierarchy1);

总结:

限定符和类型

方法

说明

static RoundingParams

asCircle()

将图像设置成圆形

static RoundingParams

fromCornersRadii(float[] radii)

分别设置(前2个)左上角、(3、4)右上角、(5、6)左下角、(7、8)右下角的圆角半径

static RoundingParams

fromCornersRadii(float topLeft, float topRight, float bottomRight, float bottomLeft)

分别设置左上角、右上角、左下角、右下角的圆角半径

static RoundingParams

fromCornersRadius(float radius)

设置圆角半径

int

getBorderColor()

获取边框颜色

float

getBorderWidth()

获取边框宽度

float[]

getCornersRadii()

获取圆角半径

int

getOverlayColor()

获取叠加颜色

boolean

getRoundAsCircle()

获取图像是否是圆形

RoundingParams.RoundingMethod

getRoundingMethod()

获取当前圆形圆角模式

RoundingParams

setBorder(int color, float width)

设置边框颜色及其宽度

RoundingParams

setCornersRadii(float[] radii)

分别设置(前2个)左上角、(3、4)右上角、(5、6)左下角、(7、8)右下角的圆角半径

RoundingParams

setCornersRadii(float topLeft, float topRight, float bottomRight, float bottomLeft)

分别设置左上角、右上角、左下角、右下角的圆角半径

RoundingParams

setCornersRadius(float radius)

设置圆角半径

RoundingParams

setOverlayColor(int overlayColor)

设置叠加颜色并将设置圆形圆角的方法改为RoundingMethod.COLOR_OVERLAY

RoundingParams

setRoundAsCircle(boolean roundAsCircle)

设置图像是否为圆形

RoundingParams

setRoundingMethod(RoundingParams.RoundingMethod roundingMethod)

设置圆形圆角模式

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值