以上两种方式比较简单,但是需要很多的图片和布局文件,如果项目中的图片按钮比较多,那就很浪费资源。第三种方式使用矩阵颜色滤镜。
颜色过滤矩阵是一个4x5的矩阵, 四行分别是 红色通道值,绿色通道值,蓝色通道值和alpha通道值。五列分别是 对应通道的红色值,绿色值,蓝色值,alpha值和偏移量。
RGB和Alpha的终值计算方法如下:
Red通道终值 = a[0] * srcR + a[1] * srcG + a[2] * srcB + a[3] * srcA + a[4]
Green通道终值 = a[5] * srcR + a[6] * srcG + a[7] * srcB + a[8] * srcA + a[9]
Blue通道终值 = a[10] * srcR + a[11] * srcG + a[12] * srcB + a[13] * srcA + a[14]
Alpha通道终值 = a[15] * srcR + a[16] * srcG + a[17] * srcB + a[18] * srcA + a[19]
备注:
srcR为原图Red通道值,srcG为原图Green通道值,srcB为原图Blue通道值,srcA为原图Alpha通道值。
每个通道的源值和终值都在0到255的范围内。即使计算结果大于255或小于0,值都将被限制在0到255的范围内。
实现代码如下:
- /**
- * 按钮被按下
- */
- private final static float[] BUTTON_PRESSED = new float[] {
- 2.0f, 0, 0, 0, -50,
- 0, 2.0f, 0, 0, -50,
- 0, 0, 2.0f, 0, -50,
- 0, 0, 0, 5, 0 };
- /**
- * 按钮恢复原状
- */
- private final static float[] BUTTON_RELEASED = new float[] {
- 1, 0, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 0, 1, 0 };
- private static final OnTouchListener touchListener = new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if(event.getAction() == MotionEvent.ACTION_DOWN) {
- v.getBackground().setColorFilter(new ColorMatrixColorFilter(BUTTON_PRESSED));
- v.setBackgroundDrawable(v.getBackground());
- }else if(event.getAction() == MotionEvent.ACTION_UP) {
- v.getBackground().setColorFilter(new ColorMatrixColorFilter(BUTTON_RELEASED));
- v.setBackgroundDrawable(v.getBackground());
- }
- return false;
- }
- };
- public static void setButtonStateChangeListener(View v) {
- v.setOnTouchListener(touchListener);
- }