反思了一下最近发现以前做事不是那么的认真,所以这次想认真的对待以后的事情
我们在开始学习fresco的时候要知道他是美国著名的FaceBook公司出品的,因为我们要学习一些新的技术肯定要跟着名流走呀
下面开始附上官方文档和GitHub的网址
Api: https://www.fresco-cn.org/
GitHub: https://github.com/facebook/fresco
有文档之后,其实可以跟着文档学习,但是肯定有一些小白是看不太懂文档的所以就有了下面的文章.
在最初开始使用fresco的时候,用的是picasso和Glide当然还有最初的ImageLoader,但是为什么最后开始使用fresco呢?
其实呢在我们加载少的图片用哪个图片框架都行,但是一但我们的App图片多的话,当到达几千张的时候我发现了使用ImageLoader和gilde的时候会出现卡顿,这是为什么呢?,看了一下源码发现fresco的底层是由c语言开发的,所以它加载图片不是一下全部加载出来的而是根据用户的滑动出现的,而且它还能支持各种各样的图片格式(gif,webp,jpg,png)以及样式(圆形、圆角、渐进等)
介绍了这么多,是不是很想开始学习这个图片框架呢,下面开始吧
在开始使用一个第三方框架的时候我们的第一步就是搭建环境,这些官方文档上面都有的,但是呢,我也配置一下下吧
1.导入依赖包
1.1必须导入的依赖包
// fresco基础的依赖
implementation 'com.facebook.fresco:fresco:0.14.1'
1.2使用GIF动态图的时候导入的依赖
/*Fresco的GIF功能的依赖*/
implementation 'com.facebook.fresco:animated-gif:1.10.0'
1.3还有官方文档上介绍的依赖,但是我没有用的所以也就没有做demo,有需求的自己了解下
2.进行初始化
2.1在application中进行全局初始化
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Fresco.initialize(this);
}
}
3.进行加权限和声明application
<uses-permission android:name="android.permission.INTERNET" />
<application>
android:name="xxx"
</application>
配置好了之后呢,当然就开始代码了
我们使用的时候要用它提供的自定义控件加载图片,这里有一个坑就是控件的宽和高不能使用wrap_content,否则没有效果,这是一个缺点,还有一个缺点就是依赖包加载的有点多,影响体积
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/putong_pt"
android:layout_width="150dp"
android:layout_height="150dp"
fresco:placeholderImage="@mipmap/ic_launcher"/>
这个的意思就是一个占位符的意思,就是在加载你的图片之前进行显示的图片,使用fresco要添加下面的代码
fresco:placeholderImage="@mipmap/ic_launcher"
//使用fresco的时候要在父控件上面添加下面的话
xmlns:fresco="http://schemas.android.com/apk/res-auto"
a.第一点就是最简单的使用fresco加载图片,(没有任何效果,就简单的加载图片一张)
//初始化控件
SimpleDraweeView draweeView = findViewById(R.id.putong_pt);
//图片的网址
Uri parse = Uri.parse(“图片的网址”);
//向控件设置图片
draweeView.setImageURI(parse);
效果:
在写小知识点的时候我就不写上面的自定义控件了都一样差不多
b.渐进式加载图片
SimpleDraweeView draweeView = findViewById(R.id.grad_image);
//获取图片URL
Uri parse = Uri.parse("图片网址");
//加载质量配置,为了实现节省GPU(图形处理器),随着图片的下载,下完的扫描序列:1、4、5、10(固定)
ProgressiveJpegConfig jpegConfig = new ProgressiveJpegConfig() {
@Override
public int getNextScanNumberToDecode(int scanNumber) {
return scanNumber + 2;
}
@Override
public QualityInfo getQualityInfo(int scanNumber) {
boolean isGoodEnough = scanNumber >= 5;
return ImmutableQualityInfo.of(scanNumber,isGoodEnough,false);
}
};
ImagePipelineConfig.newBuilder(this).setProgressiveJpegConfig(jpegConfig).build();
//固定代码
//创建ImageRequest对象
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(parse)
.setProgressiveRenderingEnabled(true)//打开渐进模式
.build();
AbstractDraweeController draweeController = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setTapToRetryEnabled(true)
.setOldController(draweeView.getController())
.build();
draweeView.setController(draweeController);
效果就不一一展示了,有点麻烦我就不截图了
c.加载图片的时候先显示进度条
//找控件
SimpleDraweeView draweeView = findViewById(R.id.progress_pr);
//网址
Uri parse = Uri.parse("图片网址");
/*DraweeHierarchy 用于组织和维护最终绘制和呈现的 Drawable 对象,相当于MVC中的M。
你可以通过它来在Java代码中自定义图片的展示*/
GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources())
.setProgressBarImage(new ProgressBarDrawable())
.build();
/*对于同一个View,请不要多次调用setHierarchy,即使这个View是可回收的。
创建 DraweeHierarchy 的较为耗时的一个过程,应该多次利用。*/
//将样式设置给drawee
mDraweeView_image.setHierarchy(hierarchy);
//加载图片成功
draweeView.setImageURI(parse);
d.圆形和圆角显示图片
public class RoundCircleActivity extends AppCompatActivity implements View.OnClickListener {
private SimpleDraweeView roundandCircle;
private Button round;
private Button circle;
private GenericDraweeHierarchyBuilder mGdb;
private Uri mParse;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_round_circle);
//初始化控件
initView();
//网址
mParse = Uri.parse("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2319890138,675520422&fm=200&gp=0.jpg");
//创建Builder对象
mGdb = new GenericDraweeHierarchyBuilder(getResources());
}
private void initView() {
roundandCircle = (SimpleDraweeView) findViewById(R.id.roundandCircle);
round = (Button) findViewById(R.id.round);
circle = (Button) findViewById(R.id.circle);
round.setOnClickListener(this);
circle.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.round://圆形
circle();
break;
case R.id.circle://圆角
round();
break;
}
}
//圆角
private void round() {
RoundingParams roundingParams = RoundingParams.fromCornersRadius(50f);
GenericDraweeHierarchy build = mGdb.setRoundingParams(roundingParams).build();
roundandCircle.setHierarchy(build);
roundandCircle.setImageURI(mParse);
}
//圆形
private void circle() {
//设置形状对象,形状为圆形
RoundingParams params = RoundingParams.asCircle();
//把形状设置给参数对象
GenericDraweeHierarchy rounding = mGdb.setRoundingParams(params).build();
//设置给图片控件
roundandCircle.setHierarchy(rounding);
//加载图片控件
roundandCircle.setImageURI(mParse);
}
}
效果:(主要看下布局)
e.Gif动图,
首先就是加入依赖,依赖在顶楼
public class GifActivity extends AppCompatActivity implements View.OnClickListener {
private SimpleDraweeView gif_image;
private Button start;
private Button stop;
private Button start_gif;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gif);
//初始化控件
initView();
}
private void initView() {
gif_image = (SimpleDraweeView) findViewById(R.id.gif_image);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
start_gif = (Button) findViewById(R.id.start_gif);
start_gif.setOnClickListener(this);
start.setOnClickListener(this);
stop.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.start_gif://加载图片
//GIF动画网址,加载需要一段时间
Uri uri = Uri.parse("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1514259038111&di=312e8557563f428353811cc457f96ee3&imgtype=0&src=http%3A%2F%2Fimg.mp.itc.cn%2Fupload%2F20161116%2Ffc10ee2abef545c7bbd6f46a09c20ed2_th.gif");
AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setAutoPlayAnimations(true)//是否自动播放动画,false不播放
.setOldController(gif_image.getController())//内存优化
.build();
gif_image.setController(controller);
break;
case R.id.start://开始播放
if(gif_image.getController() != null){
Animatable animatable = gif_image.getController().getAnimatable();
//非空判断同时判断有没有播放
if(animatable != null && !animatable.isRunning()){
animatable.start();
}
}
break;
case R.id.stop://停止播放图片
if(gif_image.getController() != null){
Animatable animatable = gif_image.getController().getAnimatable();
//非空判断同时判断有没有播放
if(animatable != null && animatable.isRunning()){
animatable.stop();
}
}
break;
}
}
}
这里又发现一点优点,就是当我们使用fresco的时候连帧动画都不需要用了,间接的就减少我们APK的体积
效果布局:由于没有网速就不适用视频效果了
f.多图加载就是在加载图片之前先加载一个低分辨率的图起到视觉缓冲
//获取网址
Uri highUri = Uri.parse("网址");
Uri lowUri = Uri.parse(“网址”);
//先显示低分辨率的图,再显示高分辨率的图
AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
.setLowResImageRequest(ImageRequest.fromUri(highUri))
.setImageRequest(ImageRequest.fromUri(lowUri))
.build();
//加载图片
控件名.setController(controller);
效果的话,在网速快的时候很难看出来
g.动态的加载图片,就是不写它提供的自定义控件啦,为了让你们看的清楚我的代码才随意乱放的,不要学哟
/**
* 动态的加载fresco
* */
SimpleDraweeView draweeView = new SimpleDraweeView(this);
//设置控件的宽高比 参数如果大于1,宽度是高度的几倍
draweeView.setAspectRatio(0.5f);
//获取网址
Uri highUri = Uri.parse(path);
//图片请求
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(highUri).build();
//加载图片的控制
AbstractDraweeController build = Fresco.newDraweeControllerBuilder()
.setOldController(draweeView.getController())
.setImageRequest(request)
.build();
//加载图片
draweeView.setController(build);
//向我们的控件添加view
LinearLayout linearLayout = findViewById(R.id.line1);
linearLayout.addView(draweeView);