ImageView的高级使用技巧
来源:互联网 发布:淘宝商品列表代码 编辑:程序博客网 时间:2024/06/05 21:07
ImageView是大家用的非常多的控件之一,其相比于其他控件多了一个src属性。我们平时在其中显示的图片往往需要跟随外部的变化切换图片,这个时候我们一般会选择用多张图片来实现,如果变化后的图片和原图很类似,只是更改了颜色我们完全没有必要去弄张新图片来,今天就来教大家如何实现这种情况的需求。
如何使用Imageview的问题我就不再多说了,现在我们要实现下面这样一个Imageview:
一个圆形的Imageview,但是圆形的图片颜色和中间的那个src图片和其颜色都是可以变化的,比如这个是一个安全类的app,在扫描到有病毒的时候会根据病毒的类型变化成不同的样式。现在我们假定有3中状态:无病毒、低风险病毒、高风险病毒,分别对于上面的三个状态。对于这样一个情况,你可能会使用多张图片来实现,这样带来的后果就是增加项目的工作量和app的大小。我们如何使用最少的图片来实现呢?
使用background加src来实现
你可能最先想到的是分两个部分,第一个是圆形的纯色部分使用背景来实现,中间使用图片来实现。我们照着这个思路来实现第一种效果,打开手机开发者选项里面的过度绘制,来看看层级:
过度绘制的颜色从低到高分别是:蓝色-绿色-淡红-红色,分别对应x1-x2-x3-x4的绘制次数。很明显我们这里存在两层的绘制问题。这么我们的布局文件是这样的:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imgv_toHint" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:background="@drawable/imgv_bg" android:padding="30dp" android:scaleType="centerInside" android:src="@drawable/center_icon" /></RelativeLayout>
这里的Imageview分别设置了一个背景和一个图片。那么我们如何根据状态来设置对应的状态呢?来看java代码部分:
imgv_toHint = (ImageView) findViewById(R.id.imgv_toHint); LightingColorFilter bFilter = new LightingColorFilter(Color.TRANSPARENT, getResources().getColor(R.color.imgv_bg_yellow)); imgv_toHint.getBackground().setColorFilter(bFilter); LightingColorFilter iFilter = new LightingColorFilter(Color.TRANSPARENT, getResources().getColor(R.color.src_bg_second)); imgv_toHint.getDrawable().setColorFilter(iFilter);运行效果:
运行之后就可以看到和第二种效果是一样的,这种方式有点略屌。使用了一个ColorFilter来对图像进行处理,其中ColorFilter是一个抽象的类,不能直接来使用,需要使用其子类,他的子类有3个: LightingColorFilter、 ColorMatrixColorFilter、PorterDuffColorFilter;具体的使用我这里就不过多的展开了,有兴趣的同学可以深入的学习下,对处理图片是非常有用的。当然还可以使用图片中的各种tint属性来实现,这里就不再具体的演示如何实现了。
使用layer-list加level-list来实现
layer-list:其实质是给其中定义的item中的图片按照顺序一张张的绘制上去,默认是绘制一样的大小,但是我们可以指定偏移量来达到不一样的大小。
level-list:其实质是定义多张图片对应多个状态(使用int值来表示),在代码中我们设置不同的状态来控制显示不同的图片。
我们来看xml中的代码:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imgv_toHint" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:src="@drawable/level_icon" /></RelativeLayout>
来看看level_icon文件:
<?xmlversion="1.0" encoding="utf-8"?><level-listxmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/layer_bg_first" android:maxLevel="1"/> <item android:drawable="@drawable/layer_bg_secend" android:maxLevel="2"/> <item android:drawable="@drawable/layer_bg_third" android:maxLevel="3"/></level-list>
来看看其中一个layer-list:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:width="160dp" android:height="160dp" android:drawable="@drawable/imgv_bg_first" /> <item android:width="100dp" android:height="100dp" android:drawable="@drawable/center_icon_first" android:left="30dp" android:top="30dp" /></layer-list>
在代码中我们可以这样使用:
imgv_toHint = (ImageView) findViewById(R.id.imgv_toHint); imgv_toHint.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { imgv_toHint.getDrawable().setLevel(level = level >= 3 ? 1 : ++level); } });
获取到drawable对象,然后设置其level系统就自动更换图片了,来看效果:
说了这么多,过度绘制的问题还是没能解决,其根本原因是我们还没有给他们做到一张图片来显示。如果要做到一张图片显示又不过多的引入图片的数量,我们可以使用一个bitmap对象来绘制一张图片然后设置到imageview上面去。因为bitmap在绘制的时候不管是多么复杂,其也算是一层view。利用这个思路,我们来减少过度绘制的问题。
去掉过度绘制的问题
这种方式就不能够在xml文件中直接设置src图片了,因为前面我们知道这种方式设置的话是行不通的。那么我们只能在代码中来设置,我们可以给资源文件中的layer-list转化为一张图片,然后设置到imageview上面,这样的话多了一层转化少了一层绘制。来看java中的代码:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imgv_toHint = (ImageView) findViewById(R.id.imgv_toHint); Drawable src = getDrawable(R.drawable.layer_bg_secend); imgv_toHint.setImageBitmap(drawable2Bmp(src)); } private Bitmap drawable2Bmp(Drawable drawable) { Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); drawable.draw(canvas); return bitmap; }
这里我们定义了一个drawable转为Bitmap的方法,给资源中的drawable对象转化为一张bitmap图片,然后设置到imageview上面。来看下过度绘制的问题:
我们看到过度绘制的问题已经不存在了。
总结
说了这么多小的使用技巧,对我们平时的开发是非常有帮助的。有的技巧会使代码变得整洁,有的会取消掉过度绘制的问题。但是由于google设计的缺陷,过度绘制和代码的整洁行没有办法同时做到,我们以后在开发中需要灵活的运用。如果你对这块有更好的理解,欢迎在下面指出来,谢谢~~~
欢迎关注我的微信公众号“android教科书”,最新最好的文章第一时间送到手!可以扫描下面的二维码来关注:
- ImageView的高级使用技巧
- ImageView的src和background的区别、padding的使用技巧、ImageView根据屏幕对缩放
- Shell使用的高级技巧(pwd)
- id选择器的使用----jQuery高级技巧
- Emmet的高级功能与使用技巧
- Redis高级特性:虚拟内存的使用技巧
- Redis高级特性:虚拟内存的使用技巧
- Redis高级特性:虚拟内存的使用技巧
- Emmet的高级功能与使用技巧
- 20个css使用的高级技巧
- android--imageview的小技巧
- vim 高级使用技巧
- Excel高级使用技巧
- Excel高级使用技巧
- Excel高级使用技巧
- vim高级使用技巧
- Eclipse高级使用技巧
- fiddler高级使用技巧
- C#将图像存成视频
- Hibernate查询和缓存
- javascript学习笔记(一)
- java项目上线时摘取更新文件工具
- myeclipse中安装SVN插件
- ImageView的高级使用技巧
- Swift WKWebView的js调用swift
- MVC设计模式
- sql 执行顺序
- 第二次试验2 质数 分段函数
- NoSQL概述
- 折线分割平面 (sdut oj)
- 欢迎使用CSDN-markdown编辑器
- 006