工作内容:
1.第三方框架universal-image-loader【图片加载】的使用
2.universal-image-loader的OOM问题处理
3.CardView使用【给列表中项+边框】
学习分享:
一、universal-image-loader图片加载,缓存使用步骤
1.下载universal-image-loader,点击下载[是在百度云盘里的]
2.将下载下来的universal-image-loader-1.9.4.jar复制到你的项目下的app → libs目录下 → 右键点它“add as library”
3.使用步骤:
第一步:由于在项目中经常用到,在项目中创建类class MyApplication extends Application{}【MyApplication 需在manifests中的application添加name = “.base.MyApplication”属性】,在其中的onCreate方法中添加代码如下:【作用:配置图片显示风格】
File cacheDir = StorageUtils.getCacheDirectory(context); //缓存文件夹路径
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.memoryCacheExtraOptions(480, 800) // default = device screen dimensions 内存缓存文件的最大长宽
.diskCacheExtraOptions(480, 800, null) // 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个
.taskExecutor(...)
.taskExecutorForCachedImages(...)
.threadPoolSize(3) // default 线程池内加载的数量
.threadPriority(Thread.NORM_PRIORITY - 2) // default 设置当前线程的优先级
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通过自己的内存缓存实现
.memoryCacheSize(2 * 1024 * 1024) // 内存缓存的最大值
.memoryCacheSizePercentage(13) // default
.diskCache(new UnlimitedDiscCache(cacheDir)) // default 可以自定义缓存路径
.diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值
.diskCacheFileCount(100) // 可以缓存的文件数量
// default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator())
.imageDownloader(new BaseImageDownloader(context)) // default
.imageDecoder(new BaseImageDecoder()) // default
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
.writeDebugLogs() // 打印debug log
.build(); //开始构建
我的项目中使用:
//1.配置图片显示信息 ImageLoaderConfiguration imageLoaderConfiguration = new ImageLoaderConfiguration.Builder(this) .memoryCacheExtraOptions(480,800) .threadPoolSize(5) .threadPriority(Thread.NORM_PRIORITY-1) .denyCacheImageMultipleSizesInMemory() .memoryCacheSize(2 * 1024 * 1024) .memoryCacheSizePercentage(13) // .diskCacheSize(50 * 1024 * 1024).diskCacheFileCount(50) // .diskCacheFileNameGenerator(new HashCodeFileNameGenerator())// default // .imageDownloader(new BaseImageDownloader(this))//default .imageDecoder(new BaseImageDecoder(true)) .defaultDisplayImageOptions(DisplayImageOptions.createSimple())// default .writeDebugLogs() .build(); //2.将配置信息给予我们的ImageLoader对象 ImageLoader.getInstance().init(imageLoaderConfiguration);第二步:在适配器中的构造函数中【也可以写入MyApplication中】写入下面代码:【作用:配置具体显示的图片——加载过程中和完成后(包括加载失败,加载为空,正常加载)】
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub) // 设置图片下载期间显示的图片
.showImageForEmptyUri(R.drawable.ic_empty) // 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.ic_error) // 设置图片加载或解码过程中发生错误显示的图片
.resetViewBeforeLoading(false) // default 设置图片在加载前是否重置、复位
.delayBeforeLoading(1000) // 下载前的延迟时间
.cacheInMemory(false) // default 设置下载的图片是否缓存在内存中
.cacheOnDisk(false) // default 设置下载的图片是否缓存在SD卡中
.preProcessor(...)
.postProcessor(...)
.extraForDownloader(...)
.considerExifParams(false) // default
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default 设置图片以如何的编码方式显示
.bitmapConfig(Bitmap.Config.ARGB_8888) // default 设置图片的解码类型
.decodingOptions(...) // 图片的解码设置
.displayer(new SimpleBitmapDisplayer()) // default 还可以设置圆角图片new RoundedBitmapDisplayer(20)弧度20
.handler(new Handler()) // default
.build();
在我的项目中使用:
options = new DisplayImageOptions.Builder().cacheInMemory(true) .showImageForEmptyUri(R.drawable.img_news_lodinglose) //url指向为空时显示的图片 .showImageOnFail(R.drawable.img_news_lodinglose) //加载失败时显示的图片 .showImageOnLoading(R.drawable.img_news_loding) //加载中时显示的图片 .cacheOnDisk(true) //缓存到磁盘(存储卡) .imageScaleType(ImageScaleType.IN_SAMPLE_INT) //尺寸类型(枚举类) .bitmapConfig(Bitmap.Config.RGB_565) //位图配置--影响图片显示质量--值越大越好下载流量越多 .build();第三步:在Adapter中给ImageView中添加图片(使用框架加载——前提是已经找到对应图片的url)
@Override public void onBindNormalHolder(RecyclerView.ViewHolder holder, final int position) { NormalHolder normalHolder = (NormalHolder)holder; if(list.get(position).getImageurls().size()==0){ //没有图片则不显示图片 normalHolder.imageView.setVisibility(View.GONE); }else{ //有图片则去加载图片 ImageLoader.getInstance().displayImage(list.get(position).getImageurls().get(0).getUrl()//传入图片url , normalHolder.imageView //加载后的图片放入ImageView , options); //显示图片的选择 } normalHolder.tvTitle.setText(list.get(position).getTitle()); normalHolder.tvDisc.setText(list.get(position).getDesc()); normalHolder.tvTime.setText(list.get(position).getPubDate()); normalHolder.linearLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { recyItemPositionListener.getRecyItemPosition(position); } }); }
完成,最后显示效果:先加载出文字,图片之后加载出来
二、ImageLoader的OOM问题
这个框架产生OOM的概率比较小,并不保证OOM问题永不发生。这个框架对OOM做了简单的crash,保证我们的程序遇到OOM而不被crash掉,但如果我们使用该框架经常发生OOM,可以做如下处理
1、减少线程池中线程的个数。在ImageLoaderConfiguration中的(.threadPoolSize)中配置,推荐1-5。
2、在DisplayImageOptions选项中配置bitmapConfig为Bitmap.Config.RGB_565,因为默认是ARGB_8888,使用RGB_565会比ARGB_8888少消耗2倍内存。
3、在ImageLoaderConfiguration中配置图片的内存缓存为memoryCache(new WeakMemoryCache())或者不使用内存缓存。
4、在DisplayImageOptions选项中设置.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者imageScaleType(ImageScale.EXACTY)
【ARGB_8888解释:A:透明度 R:红色 G:绿色 B:蓝色
Bitmap.Config ARGB_4444:每个像素占四位,即A=4,R=4,G=4,B=4,那么一个像素点占4+4+4+4=16位
Bitmap.Config ARGB_8888:每个像素占四位,即A=8,R=8,G=8,B=8,那么一个像素点占8+8+8+8=32位
Bitmap.Config RGB_565:每个像素占四位,即R=5,G=6,B=5,没有透明度,那么一个像素点占5+6+5=16位
Bitmap.Config ALPHA_8:每个像素占四位,只有透明度,没有颜色。】
【ImageScaleType.IN_SAMPLE_INT解释:
EXACTLY :图像将完全按比例缩小的目标大小
EXACTLY_STRETCHED:图片会缩放到目标大小完全
IN_SAMPLE_INT:图像将被二次采样的整数倍
IN_SAMPLE_POWER_OF_2:图片将降低2倍,直到下一减少步骤,使图像更小的目标大小
NONE:图片不会调整】
三、CardView使用步骤
1.在Android studio中添加控件:“file” → “Project Structure” → “Dependencies”看图片
检查:build gradle(Module:app)中出现compile 'com.android.support:cardview-v7:23.2.1'则是成功了
使用:
这个FrameLayout特殊点就是有rounded corner(圆角)和shadow(阴影),这个就是它的特殊之处,回首往日,我们需要自定义shape文件进行实现圆角和阴影的设计,现在google的大牛已经把它设计为CardView的属性供我们设置进行使用。下面我们看看CardView新增了哪些属性:
- CardView_cardBackgroundColor 设置背景色
- CardView_cardCornerRadius 设置圆角大小
- CardView_cardElevation 设置z轴阴影
- CardView_cardMaxElevation 设置z轴最大高度值
- CardView_cardUseCompatPadding 是否使用CompadPadding
- CardView_cardPreventCornerOverlap 是否使用PreventCornerOverlap
- CardView_contentPadding 内容的padding
- CardView_contentPaddingLeft 内容的左padding
- CardView_contentPaddingTop 内容的上padding
- CardView_contentPaddingRight 内容的右padding
- CardView_contentPaddingBottom 内容的底padding
card_view:cardUseCompatPadding 设置内边距,V21+的版本和之前的版本仍旧具有一样的计算方式
card_view:cardPreventConrerOverlap 在V20和之前的版本中添加内边距,这个属性为了防止内容和边角的重叠
实例:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" app:cardBackgroundColor="@android:color/white" //背景色 app:cardCornerRadius="5dp" //圆角半径 app:cardElevation="5dp" //Z轴阴影 app:contentPadding="5dip"> //内边距(与内容) <!--属性app需alt+Enter引入xmls:app=...--> <LinearLayout android:id="@+id/linear_normal" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ImageView android:id="@+id/iv_normal" android:layout_width="130dp" android:layout_height="130dp" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="3dp" android:orientation="vertical"> <TextView android:id="@+id/tv_title_normal" style="@style/fraginfo_normal_tv" android:text="标题" android:maxLines="2" android:textColor="@color/black" android:textSize="18sp" /> <TextView android:id="@+id/tv_disc_normal" style="@style/fraginfo_normal_tv" android:layout_below="@+id/tv_title_normal" android:maxLines="3" /> <TextView android:id="@+id/tv_time_normal" style="@style/fraginfo_normal_tv" android:text="2016-12-16" android:layout_below="@+id/tv_disc_normal" android:textSize="14sp" /> </RelativeLayout> </LinearLayout> </android.support.v7.widget.CardView> </LinearLayout>
实现效果:【列表项的外边框】