Android 仿蘋果IOS6開關(guān)按鈕
先給大家展示下效果圖:

不知道大家對效果圖感覺怎么樣,個(gè)人覺還不錯(cuò),感興趣的朋友可以參考下實(shí)現(xiàn)代碼哦。
public class ToggleButton extends View {
private SpringSystem springSystem;
private Spring spring ;
/** */
private float radius;
/** 開啟顏色*/
private int onColor = Color.parseColor("#4ebb7f");
/** 關(guān)閉顏色*/
private int offBorderColor = Color.parseColor("#dadbda");
/** 灰色帶顏色*/
private int offColor = Color.parseColor("#ffffff");
/** 手柄顏色*/
private int spotColor = Color.parseColor("#ffffff");
/** 邊框顏色*/
private int borderColor = offBorderColor;
/** 畫筆*/
private Paint paint ;
/** 開關(guān)狀態(tài)*/
private boolean toggleOn = false;
/** 邊框大小*/
private int borderWidth = 2;
/** 垂直中心*/
private float centerY;
/** 按鈕的開始和結(jié)束位置*/
private float startX, endX;
/** 手柄X位置的最小和最大值*/
private float spotMinX, spotMaxX;
/**手柄大小 */
private int spotSize ;
/** 手柄X位置*/
private float spotX;
/** 關(guān)閉時(shí)內(nèi)部灰色帶高度*/
private float offLineWidth;
/** */
private RectF rect = new RectF();
/** 默認(rèn)使用動(dòng)畫*/
private boolean defaultAnimate = true;
/** 是否默認(rèn)處于打開狀態(tài)*/
private boolean isDefaultOn = false;
private OnToggleChanged listener;
private ToggleButton(Context context) {
super(context);
}
public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setup(attrs);
}
public ToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
setup(attrs);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
spring.removeListener(springListener);
}
public void onAttachedToWindow() {
super.onAttachedToWindow();
spring.addListener(springListener);
}
public void setup(AttributeSet attrs) {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Style.FILL);
paint.setStrokeCap(Cap.ROUND);
springSystem = SpringSystem.create();
spring = springSystem.createSpring();
spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(50, 7));
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
toggle(defaultAnimate);
}
});
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ToggleButton);
offBorderColor = typedArray.getColor(R.styleable.ToggleButton_tbOffBorderColor, offBorderColor);
onColor = typedArray.getColor(R.styleable.ToggleButton_tbOnColor, onColor);
spotColor = typedArray.getColor(R.styleable.ToggleButton_tbSpotColor, spotColor);
offColor = typedArray.getColor(R.styleable.ToggleButton_tbOffColor, offColor);
borderWidth = typedArray.getDimensionPixelSize(R.styleable.ToggleButton_tbBorderWidth, borderWidth);
defaultAnimate = typedArray.getBoolean(R.styleable.ToggleButton_tbAnimate, defaultAnimate);
isDefaultOn = typedArray.getBoolean(R.styleable.ToggleButton_tbAsDefaultOn, isDefaultOn);
typedArray.recycle();
borderColor = offBorderColor;
if (isDefaultOn) {
toggleOn();
}
}
public void toggle() {
toggle(true);
}
public void toggle(boolean animate) {
toggleOn = !toggleOn;
takeEffect(animate);
if(listener != null){
listener.onToggle(toggleOn);
}
}
public void toggleOn() {
setToggleOn();
if(listener != null){
listener.onToggle(toggleOn);
}
}
public void toggleOff() {
setToggleOff();
if(listener != null){
listener.onToggle(toggleOn);
}
}
/**
* 設(shè)置顯示成打開樣式,不會(huì)觸發(fā)toggle事件
*/
public void setToggleOn() {
setToggleOn(true);
}
/**
* @param animate asd
*/
public void setToggleOn(boolean animate){
toggleOn = true;
takeEffect(animate);
}
/**
* 設(shè)置顯示成關(guān)閉樣式,不會(huì)觸發(fā)toggle事件
*/
public void setToggleOff() {
setToggleOff(true);
}
public void setToggleOff(boolean animate) {
toggleOn = false;
takeEffect(animate);
}
private void takeEffect(boolean animate) {
if(animate){
spring.setEndValue(toggleOn ? 1 : 0);
}else{
//這里沒有調(diào)用spring,所以spring里的當(dāng)前值沒有變更,這里要設(shè)置一下,同步兩邊的當(dāng)前值
spring.setCurrentValue(toggleOn ? 1 : 0);
calculateEffect(toggleOn ? 1 : 0);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
Resources r = Resources.getSystem();
if(widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST){
widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, r.getDisplayMetrics());
widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
}
if(heightMode == MeasureSpec.UNSPECIFIED || heightSize == MeasureSpec.AT_MOST){
heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, r.getDisplayMetrics());
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
final int width = getWidth();
final int height = getHeight();
radius = Math.min(width, height) * 0.5f;
centerY = radius;
startX = radius;
endX = width - radius;
spotMinX = startX + borderWidth;
spotMaxX = endX - borderWidth;
spotSize = height - 4 * borderWidth;
spotX = toggleOn ? spotMaxX : spotMinX;
offLineWidth = 0;
}
SimpleSpringListener springListener = new SimpleSpringListener(){
@Override
public void onSpringUpdate(Spring spring) {
final double value = spring.getCurrentValue();
calculateEffect(value);
}
};
private int clamp(int value, int low, int high) {
return Math.min(Math.max(value, low), high);
}
@Override
public void draw(Canvas canvas) {
//
rect.set(0, 0, getWidth(), getHeight());
paint.setColor(borderColor);
canvas.drawRoundRect(rect, radius, radius, paint);
if(offLineWidth > 0){
final float cy = offLineWidth * 0.5f;
rect.set(spotX - cy, centerY - cy, endX + cy, centerY + cy);
paint.setColor(offColor);
canvas.drawRoundRect(rect, cy, cy, paint);
}
rect.set(spotX - 1 - radius, centerY - radius, spotX + 1.1f + radius, centerY + radius);
paint.setColor(borderColor);
canvas.drawRoundRect(rect, radius, radius, paint);
final float spotR = spotSize * 0.5f;
rect.set(spotX - spotR, centerY - spotR, spotX + spotR, centerY + spotR);
paint.setColor(spotColor);
canvas.drawRoundRect(rect, spotR, spotR, paint);
}
/**
* @param value
*/
private void calculateEffect(final double value) {
final float mapToggleX = (float) SpringUtil.mapValueFromRangeToRange(value, 0, 1, spotMinX, spotMaxX);
spotX = mapToggleX;
float mapOffLineWidth = (float) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, 10, spotSize);
offLineWidth = mapOffLineWidth;
final int fb = Color.blue(onColor);
final int fr = Color.red(onColor);
final int fg = Color.green(onColor);
final int tb = Color.blue(offBorderColor);
final int tr = Color.red(offBorderColor);
final int tg = Color.green(offBorderColor);
int sb = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fb, tb);
int sr = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fr, tr);
int sg = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fg, tg);
sb = clamp(sb, 0, 255);
sr = clamp(sr, 0, 255);
sg = clamp(sg, 0, 255);
borderColor = Color.rgb(sr, sg, sb);
postInvalidate();
}
/**
* @author ThinkPad
*
*/
public interface OnToggleChanged{
/**
* @param on = =
*/
public void onToggle(boolean on);
}
public void setOnToggleChanged(OnToggleChanged onToggleChanged) {
listener = onToggleChanged;
}
public boolean isAnimate() {
return defaultAnimate;
}
public void setAnimate(boolean animate) {
this.defaultAnimate = animate;
}
}
別忘了自定義屬性:attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ToggleButton"> <attr name="tbBorderWidth" format="dimension"/> <attr name="tbOffBorderColor" format="reference|color"/> <attr name="tbOffColor" format="reference|color"/> <attr name="tbOnColor" format="reference|color"/> <attr name="tbSpotColor" format="reference|color"/> <attr name="tbAnimate" format="reference|boolean"/> <attr name="tbAsDefaultOn" format="reference|boolean"/> </declare-styleable> </resources>
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:toggle="http://schemas.android.com/apk/res-auto" android:orientation="vertical" > <LinearLayout android:layout_marginTop="10dp" android:layout_width="match_parent" android:gravity="center_horizontal" android:layout_height="wrap_content"> <com.example.ekikousei.view.ToggleButton android:id="@+id/mToggleButton01" android:layout_width="54dp" android:layout_height="30dp"> </com.example.ekikousei.view.ToggleButton> </LinearLayout> <LinearLayout android:layout_marginTop="10dp" android:layout_width="match_parent" android:gravity="center_horizontal" android:layout_height="wrap_content"> <com.example.ekikousei.view.ToggleButton android:id="@+id/mToggleButton02" android:layout_width="54dp" android:layout_height="30dp" toggle:tbBorderWidth="2dp" toggle:tbOffBorderColor="#000" toggle:tbOffColor="#ddd" toggle:tbOnColor="#f00" toggle:tbSpotColor="#00f"> </com.example.ekikousei.view.ToggleButton> </LinearLayout> </LinearLayout>
Maintivity
public class MainActivity extends Activity {
private ToggleButton mToggleButton01;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToggleButton01 = (ToggleButton) findViewById(R.id.mToggleButton01);
mToggleButton01.setOnToggleChanged(new ToggleButton.OnToggleChanged() {
@Override
public void onToggle(boolean on) {
if (on) {
Toast.makeText(MainActivity.this, "打開", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(MainActivity.this, "默認(rèn)關(guān)閉", Toast.LENGTH_SHORT).show();
}
}
});
}
}
猛戳這里:studio點(diǎn)擊下載
以上所述是小編給大家介紹的Android 之仿蘋果IOS6開關(guān)按鈕,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- Android開發(fā)之開關(guān)按鈕用法示例
- Android開發(fā)之開關(guān)按鈕控件ToggleButton簡單用法示例
- Android 自定義Switch開關(guān)按鈕的樣式實(shí)例詳解
- Android中ToggleButton開關(guān)狀態(tài)按鈕控件使用方法詳解
- Android基于ImageView繪制的開關(guān)按鈕效果示例
- Android動(dòng)畫 實(shí)現(xiàn)開關(guān)按鈕動(dòng)畫(屬性動(dòng)畫之平移動(dòng)畫)實(shí)例代碼
- Android自定義View實(shí)現(xiàn)開關(guān)按鈕
- Android模擬開關(guān)按鈕點(diǎn)擊打開動(dòng)畫(屬性動(dòng)畫之平移動(dòng)畫)
- Android自定義實(shí)現(xiàn)開關(guān)按鈕代碼
- Android自定義開關(guān)按鈕源碼解析
相關(guān)文章
Android利用Intent實(shí)現(xiàn)記事本功能(NotePad)
這篇文章主要為大家詳細(xì)介紹了Android利用Intent實(shí)現(xiàn)簡單記事本功能(NotePad)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06
Android官方下拉刷新控件SwipeRefreshLayout使用詳解
這篇文章主要為大家詳細(xì)介紹了Android官方下拉刷新控件SwipeRefreshLayout使用方法,實(shí)例展示如何使用下拉刷新控件,感興趣的小伙伴們可以參考一下2016-07-07
HorizontalScrollView水平滾動(dòng)控件使用方法詳解
這篇文章主要為大家詳細(xì)介紹了HorizontalScrollView水平滾動(dòng)控件的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android實(shí)現(xiàn)數(shù)字跳動(dòng)效果的TextView方法示例
數(shù)字跳動(dòng)效果相信大家應(yīng)該都見過,在開發(fā)加上這種效果后會(huì)讓ui交互看起來非常不錯(cuò),所以下面這篇文章主要給大家介紹了Android實(shí)現(xiàn)數(shù)字跳動(dòng)的TextView的相關(guān)資料,文中給出了詳細(xì)的示例代碼,需要的朋友可以參考學(xué)習(xí),下面來一起看看吧。2017-04-04
Android 中Lambda表達(dá)式的使用實(shí)例詳解
這篇文章主要介紹了 Android 中Lambda表達(dá)式的使用實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05
Android UI控件之Gallery實(shí)現(xiàn)拖動(dòng)式圖片瀏覽效果
這篇文章主要為大家詳細(xì)介紹了Android UI控件之Gallery實(shí)現(xiàn)拖動(dòng)式圖片瀏覽效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12

