Android自定义控件学习笔记四

概要

本篇主要针对上一篇中onMeasure方法应用做一个简单的介绍,自定义一个按一定比例缩放的ImageView以实现图片的等比例缩放,当然了在实际开发中可以自定义一个按一定比例显示的布局视图。

上一篇中Android自定义控件学习笔记三中已经对onMeasure相关知识有了一定的了解,那么这篇笔记就通过上一篇知识点来做一个简单的应用,虽说简单可是用处也很大,在实际开发中我们常常需要处理各种图片资源,而图片如何显示的更为好美观不拉伸,让用户体验更好一些,一个图片从网络下载之后再在本地如何等比例缩放显示,这些都是每一个开发者必须要处理的事情,通过这篇笔记我们就可以很容易的解决上述问题。

ImageView显示图片

ImageView显示图片一般我们不会将图片用作背景图片的,而是直接src中设置图片,先来看一个简单的ImageView的xml的布局:

上述布局文件ImageView加上灰色的背景色是为了对比图片显示区用的,为了方面我们将手机进行横竖屏切换来对比显示,下面我们看一下显示效果:

横屏下的显示效果

imageView01

竖屏下显示效果

ImageView02

然而一般情况下我们希望图片可以填充父窗体显示,ImageView布局文件更改如下:

对ImageView添加了一个scaleType属性,属性值为fixXY。这里在竖屏下图片已经填充父窗体了,图片就不再截取了,我们看一下横屏下图片的显示效果:

ImageView03

图片明显已经被拉伸变形了,而在这里我们仅仅进行了横竖屏两种分辨率测试,事实上市场上Android手机的分辨率远远超过这里的两种,可想而知在不同手机上的显示更是千差万别。那么该如何结果这种问题呢,现在只是知道这种静态很直接的处理方式是不可行的,那么只有动态计算了,只要知道图片的宽或者高以及宽高比值就可以了,在每一张图片显示之前动态计算一下。

处理方式一

本文示例所采用的图片是546*360的,宽高比为1.5,我们以屏幕的宽度为已知变量,然后通过宽高比计算出高度h=w/1.5;

在实际开发中我们要显示的图片多数会在ListView或者GridView中,这种情况需要批量处理图片,如在GridView中一般会在适配器Adapter中暴露一个方法比如setItemWidth(int width),当知道列数以及列数之间间隔宽度时就很容易计算出每一列的宽度,这样我们在适配器Adapter中的getView(int position, View convertView, ViewGroup parent)方法中就可以动态设置宽高了。这种处理方式虽然复杂了一些,但是也不失为一种很好的解决方式,因为目前市场上有许多应用就是采用的这种处理方式,接下来再讲一种处理方式,该方式也是今天的重点,自定义等比例缩放控件。

处理方式二

这种处理方式可以说是达到了一劳永逸的效果,想要很好的掌握该种方式,必须对上一篇笔记Android自定义控件学习笔记三中的onMeasure以及MeasureSpec有比较深入的理解,因为measure方法是不可以被重写的,而如果想要得到一个控件的宽高,也就父控件所分配给自己的空间大小,必须得在onMeasure执行过后才可以,现在就应该有些眉目了,如果要让一个控件按照一定比例显示,只需要在onMeasure方法中做一些想要的处理就可以了。
接下来线简单分析一下:

通过上一篇笔记我们知道控件的宽高测量都想要一个MeasureSpec,每一个MeasureSpec代表了一个对宽度和高度的要求,它有三种模式,在这里我们只需要对一种模式进行处理就可以了EXACTLY,在布局文件中有两种方式都对应这该模式一种是MATCH_PARENT,另外一种就是具体的dimension。

  • 当宽度确定时(宽度为EXACTLY),高度模式不是EXACTLY时(也即高度不确定时),高度按照ratio的比例来重新测量;
  • 当高度确定时(高度为EXACTLY),宽度模式不是EXACTLY时(也即宽度不确定时),宽度按照ratio的比例来重新测量。

测量完毕之后,因为已经得到了想要的宽度或者高度的具体的精确的值,我们再通过MeasureSpec.makeMeasureSpec()方法来调用精确的值和精确的模式,来合成一个宽度/高度方向上的合成值,最后将合成好的值传递给super.onMeasure(widthMeasureSpec, heightMeasureSpec);设置控件为我们想要的大小。

首先看一下自定义属性,有关自定义属性更多内容可以参看Android自定义控件学习笔记一

RatioImageView类

下面是三张图片对应的布局:

效果如下图:

ImageView04

本文地址www.sunnyang.com/332.html

发表评论