Android RadioButton drawableTop drawableBottomが中央に表示され、アニメーション付き
6712 ワード
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
public class TabRadioButton extends android.support.v7.widget.AppCompatRadioButton {
/** , 3/4 */
private static final float DEFAULT_SCALE_RATE = 0.75f;
/** */
private static final int DEFAULT_DURATION = 200;
/** drawable size -1, */
private static final int DEFAULT_DRAWABLE_SIZE = -1;
private Drawable leftDrawable;
private Drawable topDrawable;
private Drawable rightDrawable;
private Drawable bottomDrawable;
/** drawable */
private int drawableSize;
private int drawablePadding;
private String text;
private float textHeight;
private float textWidth;
/** */
private boolean enableAnimation;
/** */
private Animator pressedAnimator;
/** */
private Animator releasedAnimator;
private long duration;
private float scaleRate;
public TabRadioButton(Context context) {
this(context, null);
}
public TabRadioButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TabRadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
parseAttrs(context, attrs);
init();
}
private void parseAttrs(Context context, AttributeSet attrs) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.TabRadioButton);
drawableSize = array.getDimensionPixelSize(R.styleable.TabRadioButton_trb_drawable_size, DEFAULT_DRAWABLE_SIZE);
scaleRate = array.getFloat(R.styleable.TabRadioButton_trb_scale_rate, DEFAULT_SCALE_RATE);
duration = array.getInteger(R.styleable.TabRadioButton_trb_duration, DEFAULT_DURATION);
enableAnimation = array.getBoolean(R.styleable.TabRadioButton_trb_enable_animation, false);
drawableSize = drawableSize < 0
? -1
: drawableSize;
array.recycle();
}
private void init() {
setClickable(true);
setFocusable(true);
setGravity(Gravity.CENTER);
text = getText().toString();
if (TextUtils.isEmpty(text)){
setTextSize(0);
}
//
pressedAnimator = getAnimator(true);
releasedAnimator = getAnimator(false);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
this.performClick();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//
if (enableAnimation && !pressedAnimator.isRunning()){
pressedAnimator.start();
}
break;
case MotionEvent.ACTION_UP:
//
if (enableAnimation && !releasedAnimator.isRunning()){
releasedAnimator.start();
}
break;
}
return super.onTouchEvent(event);
}
@Override
public boolean performClick() {
return super.performClick();
}
@Override
protected void onDraw(Canvas canvas) {
Drawable[] drawables = getCompoundDrawables();
leftDrawable = drawables[0];
topDrawable = drawables[1];
rightDrawable = drawables[2];
bottomDrawable = drawables[3];
textWidth = getFontWidth(getPaint(), text);
textHeight = getFontHeight(getPaint());
drawablePadding = getCompoundDrawablePadding();
int drawableWidth;
int drawableHeight;
//
if (leftDrawable != null && topDrawable == null && rightDrawable == null && bottomDrawable == null){
drawableWidth = drawableSize < 0
? leftDrawable.getIntrinsicWidth()
: drawableSize;
drawableHeight = drawableSize < 0
? leftDrawable.getIntrinsicHeight()
: drawableSize;
int left = (int) ((this.getWidth() - drawableWidth - drawablePadding - textWidth) / 2);
leftDrawable.setBounds(left, 0, left + drawableWidth, drawableHeight);
}
//
if (topDrawable != null && leftDrawable == null && rightDrawable == null && bottomDrawable == null){
drawableWidth = drawableSize < 0
? topDrawable.getIntrinsicWidth()
: drawableSize;
drawableHeight = drawableSize < 0
? topDrawable.getIntrinsicHeight()
: drawableSize;
int top = (int) ((this.getHeight() - drawableHeight - drawablePadding - textHeight) / 2);
topDrawable.setBounds(0, top, drawableWidth, top + drawableHeight);
}
// drawable
setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable);
super.onDraw(canvas);
}
/**
* @param whenPressed
* @return
*/
private Animator getAnimator(boolean whenPressed) {
return getDefaultScaleAnimator(whenPressed ? 1.0f : scaleRate,
whenPressed ? scaleRate : 1.0f, duration);
}
private Animator getDefaultScaleAnimator(float from, float to, long duration){
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator animatorX = ObjectAnimator.ofFloat(this, "ScaleX", from, to);
ObjectAnimator animatorY = ObjectAnimator.ofFloat(this, "ScaleY", from, to);
animatorSet.play(animatorX).with(animatorY);
animatorSet.setDuration(duration);
animatorSet.setTarget(this);
return animatorSet;
}
private float getFontWidth(Paint paint, String text) {
return paint.measureText(text);
}
private float getFontHeight(Paint paint){
Paint.FontMetrics fm = paint.getFontMetrics();
return fm.descent - fm.ascent;
}
public void setEnableAnimation(boolean enableAnimation) {
this.enableAnimation = enableAnimation;
}
public void setDuration(long duration) {
this.duration = duration;
}
public void setScaleRate(float scaleRate) {
this.scaleRate = scaleRate;
}
}