前言:

Android我一直想要做效果Button,終於大海撈針般找到別人寫好的,因此我花了一些時間簡化與整理成一個一個範例。

-MainActivity.java-

 

import android.widget.CompoundButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ToggleButton;
 
public class MainActivity extends Activity
implements CompoundButton.OnCheckedChangeListener, SeekBar.OnSeekBarChangeListener {
 
private TButton twitterBtn;
private TextView shadowHeight;
private SeekBar shadowHeightBar;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
twitterBtn = (TButton) findViewById(R.id.f_twitter_button);
ToggleButton shadowSwitch = (ToggleButton) findViewById(R.id.enable_shadow_switch);
shadowHeightBar = (SeekBar) findViewById(R.id.shadow_height_seekbar);
shadowHeight = (TextView) findViewById(R.id.shadow_height_value);
shadowSwitch.setOnCheckedChangeListener(this);
shadowHeightBar.setOnSeekBarChangeListener(this);
 
 
}
 
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
twitterBtn.setShadowEnabled(isChecked);
updateShadowHeight(shadowHeightBar.getProgress());
}
 
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
shadowHeight.setText(progress + "dp");
updateShadowHeight(progress);
}
 
private void updateShadowHeight(int height) {
//Convert from dp to pixel
int shadowHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, getResources().getDisplayMetrics());
twitterBtn.setShadowHeight(shadowHeight);
}
 
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
 
}
 
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
 
}
}

-TButton.java-

import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Rect;
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;
 
 
 
 
 
/**
* Created by hoang8f on 5/5/14.
*/
 
public class TButton extends Button implements View.OnTouchListener {
 
//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 TButton(Context context) {
super(context);
init();
this.setOnTouchListener(this);
}
 
public TButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
parseAttrs(context, attrs);
this.setOnTouchListener(this);
}
 
public TButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
parseAttrs(context, attrs);
this.setOnTouchListener(this);
}
 
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//Update background color
refresh();
}
 
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
updateBackground(pressedDrawable);
//左,上,右,下
this.setPadding(mPaddingLeft, mPaddingTop + mShadowHeight, mPaddingRight, mPaddingBottom);
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_OUTSIDE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
updateBackground(unpressedDrawable);
this.setPadding(mPaddingLeft, mPaddingTop + mShadowHeight, mPaddingRight, mPaddingBottom + mShadowHeight);
break;
}
return false;
}
 
private void init() {
//Init default values
isShadowEnabled = true;
Resources resources = getResources();
if (resources == null) return;
mButtonColor = resources.getColor(R.color.fbutton_default_color);
mShadowColor = resources.getColor(R.color.fbutton_default_shadow_color);
mShadowHeight = resources.getDimensionPixelSize(R.dimen.fbutton_default_shadow_height);
 
}
 
private void parseAttrs(Context context, AttributeSet attrs) {
//Load from custom attributes
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TButton);
if (typedArray == null) return;
for (int i = 0; i < typedArray.getIndexCount(); i++) {
int attr = typedArray.getIndex(i);
if (attr == R.styleable.TButton_shadowEnabled) {
isShadowEnabled = typedArray.getBoolean(attr, true); //Default is true
} else if (attr == R.styleable.TButton_shadowHeight) {
mShadowHeight = typedArray.getDimensionPixelSize(attr, R.dimen.fbutton_default_shadow_height);
}
}
typedArray.recycle();
 
//Get paddingLeft, paddingRight
int[] attrsArray = new int[]{
android.R.attr.paddingLeft, // 0
android.R.attr.paddingRight, // 1
};
TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray);
if (ta == null) return;
mPaddingLeft = ta.getDimensionPixelSize(0, 0);
mPaddingRight = ta.getDimensionPixelSize(1, 0);
ta.recycle();
 
//Get paddingTop, paddingBottom
int[] attrsArray2 = new int[]{
android.R.attr.paddingTop, // 0
android.R.attr.paddingBottom,// 1
};
TypedArray ta1 = context.obtainStyledAttributes(attrs, attrsArray2);
if (ta1 == null) return;
mPaddingTop = ta1.getDimensionPixelSize(0, 0);
mPaddingBottom = ta1.getDimensionPixelSize(1, 0);
ta1.recycle();
}
 
public void refresh() {
int alpha = Color.alpha(mButtonColor);
float[] hsv = new float[3];
Color.colorToHSV(mButtonColor, hsv);
hsv[2] *= 0.8f; // value component
//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 (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);
}
 
updateBackground(unpressedDrawable);
//Set padding
this.setPadding(mPaddingLeft, mPaddingTop + mShadowHeight, mPaddingRight, mPaddingBottom + mShadowHeight);
}
 
private void updateBackground(Drawable background) {
if (background == null) return;
//Set button background
if (Build.VERSION.SDK_INT >= 16) {
this.setBackground(background);
} else {
this.setBackgroundDrawable(background);
}
}
private LayerDrawable createDrawable(int radius, int topColor, int bottomColor) {
 
float[] outerRadius = new float[]{radius, radius, radius, radius, radius, radius, radius, radius};
 
//Top
RoundRectShape topRoundRect = new RoundRectShape(outerRadius, null, null);
ShapeDrawable topShapeDrawable = new ShapeDrawable(topRoundRect);
topShapeDrawable.getPaint().setColor(topColor);
//Bottom
RoundRectShape roundRectShape = new RoundRectShape(outerRadius, null, null);
ShapeDrawable bottomShapeDrawable = new ShapeDrawable(roundRectShape);
bottomShapeDrawable.getPaint().setColor(bottomColor);
//Create array
Drawable[] drawArray = {bottomShapeDrawable, topShapeDrawable};
LayerDrawable layerDrawable = new LayerDrawable(drawArray);
 
//上方按下效果
if (isShadowEnabled && topColor != Color.TRANSPARENT) {
//unpressed drawable
layerDrawable.setLayerInset(0, 0, 0, 0, 0); /*index, left, top, right, bottom*/
} else {
//pressed drawable
layerDrawable.setLayerInset(0, 0, mShadowHeight, 0, 0); /*index, left, top, right, bottom*/
}
//下方陰影按下效果
layerDrawable.setLayerInset(1, 0, 0, 0, mShadowHeight); /*index, left, top, right, bottom*/
 
return layerDrawable;
}
 
//Setter
public void setShadowEnabled(boolean isShadowEnabled) {//開啟陰影
this.isShadowEnabled = isShadowEnabled;
setShadowHeight(0);
refresh();
}
 
public void setShadowHeight(int shadowHeight) {//陰影高度
this.mShadowHeight = shadowHeight;
refresh();
}
 
}

-activity_main.xml-

xmlns:fbutton="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.flatbutton.MainActivity" >
 
<LinearLayout
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
 
<com.example.flatbutton.TButton
android:id="@+id/f_twitter_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:drawableLeft="@drawable/twitter"
android:drawablePadding="0dp"
android:minHeight="80dp"
android:minWidth="250dp"
android:paddingLeft="30dp"
android:paddingRight="20dp"
android:paddingTop="-5dp"
android:text="Twitter"
android:textColor="@android:color/white" />
 
<TextView
android:id="@+id/shadow_height_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Shadow height: " />
 
<TextView
android:id="@+id/shadow_height_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="4dp" />
 
<SeekBar
android:id="@+id/shadow_height_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:max="10"
android:progress="4" />
 
<ToggleButton
android:id="@+id/enable_shadow_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:checked="true"
android:minHeight="55dp"
android:text="Shadow" />
</LinearLayout>
 
</ScrollView>

效果圖:

原始碼下載:

Github

Google硬碟

 

arrow
arrow
    全站熱搜

    程式小試身手 發表在 痞客邦 留言(0) 人氣()