延续前面的随笔,此篇随笔也是在项目中对一个按钮事件处理的总结与思考;在项目中需要用到一个View,在不同状态下{ACTION_DOWN、ACTION_UP},按钮的背景,以及按钮的文字颜色都不一样,最开始想到的是selector,但是在selector虽然可以设置按钮图片背景,但是并没有支持字体颜色,字体大小改变的属性配置。既然没有属性配置,于是我就重写View的onTouchEvent事件,但是因为很多个地方都要用到这个按钮以及它的状态的change,实现起来很麻烦,于是想到了自定义控件,好切入正题;
先看两张图片:分别是正常normal状态下和按下press_down状态下的View的样式{当然效果不是很好看,实际上可以让美工给做带感的图片};
两个状态的字体颜色,大小,以及View的背景都不同!
1.自定义属性首先需要在values文件夹下创建一个名为attrs.xml文件
自定义属性需要在resources节点下配置一个declare-styleable节点,在里面有arrt节点,每个节点代表一个属性;这些属性会在R.java文件夹中生成对应的资源id,此id为:
declare-styleable节点名称 + "_" + attr节点名称;ex:
public static final int MyView_normal_textColor = 0;
2.写一个类MyView,继承自View或者View的子类,为了方便,我使用的是继承TextView
public class MyView extendsTextView {
@Overridepublic booleanonTouchEvent(MotionEvent event) {if (event.getAction() ==MotionEvent.ACTION_DOWN) {// 设置按下状态this.setTextColor(textColor_press);this.setBackgroundResource(background_press);this.setTextSize(textSize_press);
}else if (event.getAction() ==MotionEvent.ACTION_UP) {// 设置按下之后又放开的状态this.setTextColor(textColor_normal);this.setBackgroundResource(background_normal);this.setTextSize(textSize_normal);
}return true;
}private inttextSize_press;private inttextSize_normal;private inttextColor_press;private inttextColor_normal;private intbackground_press;private intbackground_normal;publicMyView(Context context, AttributeSet attrs) { // 实现此构造方法,此构造方法会自动从xml配置的属性中进行View的初始化super(context, attrs);
TypedArray typeArray=context.obtainStyledAttributes(attrs, R.styleable.MyView);
textSize_press=typeArray.getDimensionPixelSize(R.styleable.MyView_press_textSize,15);
textSize_normal=typeArray.getDimensionPixelSize(R.styleable.MyView_normal_textSize,15);
textColor_press=typeArray.getColor(R.styleable.MyView_press_textColor, Color.parseColor("#cccccc"));
textColor_normal=typeArray.getColor(R.styleable.MyView_normal_textColor, Color.parseColor("#cccccc"));
background_press=typeArray.getResourceId(R.styleable.MyView_press_background, R.drawable.ic_launcher);
background_normal=typeArray.getResourceId(R.styleable.MyView_normal_background, R.drawable.ic_launcher);this.setTextColor(textColor_normal);this.setBackgroundResource(background_normal);this.setTextSize(textSize_normal);
typeArray.recycle();
}publicMyView(Context context) {super(context);
}
// 类中的方法就不多解释,变量名命名还算比较规范,比较易懂
}
3.写好MyView之后,需要在一个layout.xml文件中查看定义的View的样式;
注意上面划下划线的一行,此行设置对自定义属性的引用的别名,res/之后跟的是程序的包名{在此程序包名为com.studynote},而不是MyView所在的包名(博主就是在这个问题上给困扰了好久没有实现出来),究其原因,想一想其实就能明白;别名之后相当于跟的是自定义属性的配置路径,而上面第一步中也提到R文件中生成的属性id名为:declare-styleable节点名称 + "_" + attr节点名称;表明ls将要引用的属性名在此包{即程序包名}之下,如果定义成其它的包名,在该包名下不存在R.Java文件中对应的属性名,固然出错;以上纯属于个人理解,如有误,还望大家指教;
4.配置好上面的属性及View、布局文件之后,运行程序,按下按钮和正常状态下,可以看到View的外观已经改变;
PS:本来想直接继承View写控件的,但是由于对View的绘制流程不熟悉,所以不能很好的操纵状态改变事件,希望得到大家的指点!