最近正在完成一个摇一摇的项目,打算加入一点社交元素。第一步是实现登陆界面,一个人独自设计加开发。最后的效果还是比较满意,但还是有性能上的损失,应该可以做得更好。
背景图片可以循环左右移动,界面里的Edittext使用三方控件:MaterrialEdittext,其实现了Edittext的向下兼容。此库继承自AppCompatEdittext,所以支持Edittext的所有特性,而且添加了字符检测,标签动画,组件颜色的定制等。有了它基本上可以忘记系统提供的Edittext了。jar下载地址 (注意此控件依赖于NineOldAndroid,所以还需要一起导入它的jar包)
new AsyncTask
这里使用了 AsyncTask 新开了一个线程加载图片,然而效果并不好,反而在打开登陆界面时有一段时间的黑屏过程,还不如直接在UI线程中加载。
这里遇到了两个坑:
1、使用Matrix控制图片必须在xml文件中为ImageView添加android:scaleType=”matrix”
2、放在不同资源限定符的drawable文件夹中的Bitmap,它的Density属性是不同的。而每个设备的TargetDensity属性也是不同的(小米note是440,Vivo X3t 是320) ,系统就是根据TargetDensity到不同的drawable文件夹找图片的。举个例子,我只在drawable-mdpi中放了一张图片,那它的Density是160(图片像素1440x900)。小米note加载这张图片,因为drawable-xxhdpi没图片,于是它会对其进行缩放1440 x (440 \ 160) = 3960 , 900 x (440 \ 160 ) = 2475。于是内存中图片的真正像素是(3960 x 2475)。所以,如果不注意为每个drawable文件夹配上图片,可能不同设备上的图片像素会不一致。(注意:测试系统 API23、AndroidStudio2.1)
自动滚动图片是由一个MoveImageAnimator实现的动画的效果。
private class MoveImageAnimator extends Animation {
@Override
protected void applyTransformation(float interpolatedTime,Transformation t) {
super.applyTransformation(interpolatedTime,t);
RectF r = getMatrixRectF();
if (r.left > 0 || r.right < getWidth()) {
back = !back;
}
if (back) {
matrix.postTranslate(2,0);
} else {
matrix.postTranslate(-2,0);
}
setImageMatrix(matrix);
}
}
移动方法很简单,使用Matrix对图片进行水平位移操作。这里需要注意的就是对图片左右边框的判断,如果到达图片的左右边框,让back=!back 就是碰撞到边框马上返回。检测图片的左右边框可以使用下面的方法:
/**
* 此方法能获取View中图片的描述RectF
* @return
*/
private RectF getMatrixRectF() {
Matrix m = matrix;
RectF rectF = new RectF();
Drawable d = getDrawable();
if (d != null) {
rectF.set(0,0,d.getIntrinsicWidth(),d.getIntrinsicHeight());//当前图片宽高(不改变的)
m.mapRect(rectF);//将matrix中的值映射到rectF中
}
return rectF;
}
项目GitHub: https://github.com/HYY-yu/MovePicImageView