package com.android.mrlin.flattbutton;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
public class FButton extends Button
{
// Custom values
private boolean isShadowEnabled = true; // 默认 显示阴影
private int mButtonColor; // 按键 颜色
private int mShadowColor; // 阴影颜色
private int mShadowHeight; // 阴影距离
private int mCornerRadius; // 弧度
// Native values
private int mPaddingLeft;
private int mPaddingRight;
private int mPaddingTop;
private int mPaddingBottom;
// Background drawable
private Drawable pressedDrawable;
private Drawable unpressedDrawable;
boolean isShadowColorDefined = false; // 是否定义了 阴影颜色
public FButton(Context context)
{
super(context);
this.setOnTouchListener(new TouchListener());
}
public FButton(Context context, AttributeSet attrs)
{
super(context, attrs);
praseAtts(context, attrs);
this.setOnTouchListener(new TouchListener());
}
public FButton(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
praseAtts(context, attrs);// 解析自定义参数和个别系统自动参数
this.setOnTouchListener(new TouchListener());//触摸时间,用于进行图片切换和文字位置变动
}
@Override
protected void onFinishInflate()
{
super.onFinishInflate();
refresh();
}
@Override
public void setEnabled(boolean enabled)
{
super.setEnabled(enabled);
refresh();
}
/**
* 2.解析自定义参数
*/
private void praseAtts(Context context,
AttributeSet attrs)
{
//解析自定义参数
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.FButton);
if (null == typedArray) return;
for (int i = 0; i < typedArray.getIndexCount(); i++)
{
int index = typedArray.getIndex(i);
if ( R.styleable.FButton_shadowHeight == index)
{
isShadowColorDefined = true; // 是否自定义了阴影颜色
}
else
{
isShadowColorDefined = false;
}
}
isShadowEnabled=typedArray.getBoolean(R.styleable.FButton_shadowEnabled, true);
mButtonColor = typedArray.getColor(R.styleable.FButton_buttonColor,
R.color.fbutton_default_color);
// mShadowColor = typedArray.getColor(R.styleable.FButton_shadowColor,
// R.color.fbutton_default_shadow_color);
mShadowHeight = typedArray.getDimensionPixelSize(
R.styleable.FButton_shadowHeight,
R.dimen.fbutton_default_shadow_height);
mCornerRadius = typedArray.getDimensionPixelSize(
R.styleable.FButton_cornerRadius,
R.dimen.fbutton_default_conner_radius);
typedArray.recycle();
// 获取系统自动参数值 Get paddingLeft, paddingRight,paddingTop, paddingBottom
int[] attrsArray = new int[]
{ android.R.attr.paddingLeft, // 0
android.R.attr.paddingRight, // 1
};
TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray);
if (ta == null) return;
// 0 1 2 3 为上面属性attrsArray下标
mPaddingLeft = ta.getDimensionPixelSize(0, 0);
mPaddingRight = ta.getDimensionPixelSize(1, 0);
ta.recycle();
int[] attrsArray1 = new int[]
{
android.R.attr.paddingTop, // 2
android.R.attr.paddingBottom// 3
};
TypedArray ta1 = context.obtainStyledAttributes(attrs, attrsArray1);
if (ta == null) return;
// 0 1 为上面属性ta下标
mPaddingTop = ta.getDimensionPixelSize(0, 0);
mPaddingBottom = ta.getDimensionPixelSize(1, 0);
ta1.recycle();
}
/**
* 3.刷新UI 背景/阴影颜色 阴影宽度 显示阴影
*/
private void refresh()
{
// 透明度 红 绿 蓝
int alpha = Color.alpha(mButtonColor);
float[] hsv = new float[3];
Color.colorToHSV(mButtonColor, hsv);
hsv[2] *= 0.8f; // value component 第二个参数值为原有的80%
// if shadow color was not defined, generate shadow color = 80%
// brightness
if (!isShadowColorDefined)
{
mShadowColor = Color.HSVToColor(alpha, hsv);
}
// Create pressed background and unpressed background drawables
// 创建 按下和非按下 状态的背景图片
if (this.isEnabled())
{
// 默认图片和点击时的背景图片 ,,颜色值互换或者 底色为透明
if (isShadowEnabled)
{
pressedDrawable = createDrawable(mCornerRadius,
Color.TRANSPARENT, mButtonColor);
unpressedDrawable = createDrawable(mCornerRadius, mButtonColor,
mShadowColor);
}
else
{
mShadowHeight = 0;
pressedDrawable = createDrawable(mCornerRadius, mShadowColor,
Color.TRANSPARENT);
unpressedDrawable = createDrawable(mCornerRadius, mButtonColor,
Color.TRANSPARENT);
}
}
else
{
hsv[1] *= 0.25f;
int disableColor = mShadowColor = Color.HSVToColor(alpha, hsv);
pressedDrawable = createDrawable(mCornerRadius, disableColor,
Color.TRANSPARENT);
unpressedDrawable = createDrawable(mCornerRadius, disableColor,
Color.TRANSPARENT);
}
updateBackground(unpressedDrawable);
//Button 里面的字体位置也要跟着 按下和弹起 状态进行变动
setPadding(mPaddingLeft-mShadowHeight, mPaddingTop- mShadowHeight, mPaddingRight+ mShadowHeight, mPaddingBottom + mShadowHeight);
}
/**
* 4.图层叠加显示
* radius 弧度值
* topcolor 顶层 颜色值
* bottomcolor 底层颜色值
*/
private LayerDrawable createDrawable(int radius,
int topcolor,
int bottomcolor)
{
// LayerDrawable 两张或多张图片叠加 生成为一张图片
float[] radii = new float[]
{ radius, radius, radius, radius, radius, radius, radius, radius };
/*
* 一个包含8个弧度值,指定外部圆角矩形的 4个角部的弧度及 :new float[] {l, l, t, t, r, r, b, b};
* 前2个 左上角, 3 4 , 右上角, 56, 右下, 78 ,左下,如果没弧度的话,传入null即可
*/
RoundRectShape topRRS = new RoundRectShape(radii, null, null);
ShapeDrawable topShapeDrawable = new ShapeDrawable(topRRS);
topShapeDrawable.getPaint().setColor(topcolor);
RoundRectShape buttomRRS = new RoundRectShape(radii, null, null);
ShapeDrawable buttomShapeDrawable = new ShapeDrawable(buttomRRS);
buttomShapeDrawable.getPaint().setColor(bottomcolor);
Drawable[] layer = new Drawable[]
{ buttomShapeDrawable, topShapeDrawable };
//LayerDrawable 层叠样式layer-list 即 从 layer[0]底层图片 --到- layer[size]顶层图片 叠加成一张新图片
LayerDrawable layerDrawable = new LayerDrawable(layer);
if (isShadowEnabled && topcolor != Color.TRANSPARENT)
{
/*
* * index, left, top, right, bottom index 图层1 buttomShapeDrawable
* index 图层序列号
* left, top, right, bottom 图层位置的偏移量
*/
layerDrawable.setLayerInset(0, mShadowHeight, mShadowHeight, 0, 0);
}
else
{
layerDrawable.setLayerInset(0, 0, 0, 0, 0);
}
layerDrawable.setLayerInset(1, 0, 0, mShadowHeight, mShadowHeight);
return layerDrawable;
}
/**
* 5.更新控件的背景图案
*/
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void updateBackground(Drawable drawable)
{
if (null == drawable) return;
if (Build.VERSION.SDK_INT >= 16)
{
setBackground(drawable);
}
else
{
setBackgroundDrawable(drawable);
}
}
private void setFButtonPadding(int left,int top,int right,int buttom)
{
this.mPaddingLeft = left;
this.mPaddingTop = top;
this.mPaddingRight = right;
this.mPaddingBottom = buttom;
refresh();
}
public boolean isShadowEnabled()
{
return isShadowEnabled;
}
public void setShadowEnabled(boolean isShadowEnabled)
{
this.isShadowEnabled = isShadowEnabled;
refresh();
}
public int getmButtonColor()
{
return mButtonColor;
}
public void setmButtonColor(int mButtonColor)
{
this.mButtonColor = mButtonColor;
refresh();
}
public int getmShadowColor()
{
return mShadowColor;
}
public void setmShadowColor(int mShadowColor)
{
this.mShadowColor = mShadowColor;
refresh();
}
public int getmShadowHeight()
{
return mShadowHeight;
}
public void setmShadowHeight(int mShadowHeight)
{
this.mShadowHeight = mShadowHeight;
refresh();
}
public int getmCornerRadius()
{
return mCornerRadius;
}
public void setmCornerRadius(int mCornerRadius)
{
this.mCornerRadius = mCornerRadius;
refresh();
}
private class TouchListener implements View.OnTouchListener{
@Override
public boolean onTouch(View v,
MotionEvent event)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
updateBackground(pressedDrawable);
setPadding(mPaddingLeft, mPaddingTop , mPaddingRight, mPaddingBottom);
break;
case MotionEvent.ACTION_UP:
updateBackground(unpressedDrawable);
setPadding(mPaddingLeft-mShadowHeight, mPaddingTop- mShadowHeight, mPaddingRight+ mShadowHeight, mPaddingBottom + mShadowHeight);
break;
default:
break;
}
return false;
}
}
}