customize a button with click effect on Android
Damon
Usually in Android when we need button click effect we will define different state images and create a drawable as button background.
But sometime it is really troublesome. coz you have to create different drawable files for different button. I am so lazy so try to find some generic ways.
So I just extends the Button and when get touch event change the colors.
Following codes.
After get the drawable of the button you can change the color using color filter. so add a simple darker effect.
But there is one problem the text color not changed after that . So when init this button get the default text color. After that just change text color as what you want .
So from this way I think I can also change the ImageButton. The only difference is besides change the background we also need to change the image of that ImageButton.
Codes following:
At first I change that inside of onDraw(). If so I can only change the layout color not the child views. So I moved the methods to dispatchDraw().
But there is another problem : coz the touch up event will be consumed and not come to layout this level. So I need to consume this first.
So the next problem came out . Because of this the layout will not call onClickListener. So I have to performclick by myself. And then added a check whether user click inside of the layout.
So thats it. Now no need to create some many different buttons drawable xml.
Still have issues :
like the layout can not draw that shadow effect only on valid part. Now cover all the layout even some parts are transparent.
There should be some better ways????????
Usually in Android when we need button click effect we will define different state images and create a drawable as button background.
But sometime it is really troublesome. coz you have to create different drawable files for different button. I am so lazy so try to find some generic ways.
So I just extends the Button and when get touch event change the colors.
Following codes.
public class EffectButton extends Button { int textColor ; public EffectButton(Context context, AttributeSet attrs) { super(context, attrs); int[] attrsArray = new int[] { android.R.attr.textColor }; TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray); textColor = ta.getColor(0, Color.TRANSPARENT); ta.recycle(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { getBackground() .setColorFilter(0x88000000, PorterDuff.Mode.SRC_ATOP); setTextColor(Color.parseColor("#88000000")); invalidate(); break; } case MotionEvent.ACTION_UP: { getBackground().clearColorFilter(); setTextColor(textColor); invalidate(); break; } } return super.onTouchEvent(event); } }
So from this way I think I can also change the ImageButton. The only difference is besides change the background we also need to change the image of that ImageButton.
Codes following:
public class EffectImageButton extends ImageButton { int textColor ; public EffectImageButton(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { getBackground() .setColorFilter(0x88000000, PorterDuff.Mode.SRC_ATOP); getDrawable().setColorFilter(0x88000000, PorterDuff.Mode.SRC_ATOP); invalidate(); break; } case MotionEvent.ACTION_UP: { getBackground().clearColorFilter(); getDrawable().clearColorFilter(); invalidate(); break; } } return super.onTouchEvent(event); } }After this continue... I want to find some more generic ways. So I changed the RelativeLayout.
public class EffectRelativeLayout extends RelativeLayout { boolean isDown = false; public EffectRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); } @SuppressLint("NewApi") @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (isDown) { canvas.save(); canvas.drawColor(Color.parseColor("#88000000"), PorterDuff.Mode.SRC_ATOP); canvas.restore(); } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { isDown = true; invalidate(); return true; } case MotionEvent.ACTION_UP: { isDown = false; invalidate(); if (isInsideClick(event)) { performClick(); } return true; } } return super.onTouchEvent(event); } private boolean isInsideClick(MotionEvent event) { if(event.getRawX()>=getLeft() && event.getRawX()<= getRight() && event.getRawY()>=getTop() && event.getRawY()<=getBottom()){ return true; } return false; } }This time there is a bit difference. coz I can not just directly get the background and child views. So I decide to change the canvas directly.
At first I change that inside of onDraw(). If so I can only change the layout color not the child views. So I moved the methods to dispatchDraw().
But there is another problem : coz the touch up event will be consumed and not come to layout this level. So I need to consume this first.
So the next problem came out . Because of this the layout will not call onClickListener. So I have to performclick by myself. And then added a check whether user click inside of the layout.
So thats it. Now no need to create some many different buttons drawable xml.
Still have issues :
like the layout can not draw that shadow effect only on valid part. Now cover all the layout even some parts are transparent.
There should be some better ways????????
Comments
Post a Comment