編輯:關於Android編程
最近心血來潮,寫了一個自定義仿iPhone的開關。有需要的同學可以來下載啦。支持點擊自動滾動,速率可以自己根據需要修改。觸摸滾動,大小自定義,支持修改樣式。就不錄制動畫,就上傳了兩張圖給大家看看。

主要代碼:
package com.example.switchbutton;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
public class SwitchButton extends View {
public static final int DEFAULT_WIDTH = 100;
public static final int DEFAULT_HEIGTH = 45;
public static final int PER_POST_TIME = 20;
public static final int CLICK = 0;
public static final int LEFT = 1;
public static final int RIGHT = 2;
private int mSelectBg;
private int mUnSelectBg;
private int mBorderColor;
private int mSelectCirlceColor;
private int mUnSelectCircleColor;
private boolean isChecked;
private Paint mPaint;
private int mWidth;
private int mHeight;
private int mClickTimeout;
private int mTouchSlop;
private float mAnimMove;
private final float VELOCITY = 350;
private float firstDownX;
private float firstDownY;
private float lastDownX;
private int mCriclePostion;
private int mStartCriclePos;
private int mEndCirclePos;
private boolean isScroll;
private int status;
private Handler mHander;
private AnimRunnable mAnim;
private OnCheckChangeListener mOnCheckChangeListener;
public interface OnCheckChangeListener {
void OnCheck(SwitchButton switchButton,boolean isChecked);
}
public SwitchButton(Context context, AttributeSet attrs) {
super(context, attrs);
Resources res = getResources();
int defaultSelectBg = res.getColor(R.color.default_switch_button_select_bg);
int defaultUnSelectBg = res.getColor(R.color.default_switch_button_unselect_bg);
int defaultBorderColor = res.getColor(R.color.default_switch_button_border_color);
int defaultSelectCircleColor = res.getColor(R.color.default_switch_button_select_color);
int defaultUnSelectCircleColor = res.getColor(R.color.default_switch_button_unselect_color);
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.SwitchButton);
mSelectBg = a.getColor(R.styleable.SwitchButton_select_bg, defaultSelectBg);
mUnSelectBg = a.getColor(R.styleable.SwitchButton_unselect_bg, defaultUnSelectBg);
mBorderColor = a.getColor(R.styleable.SwitchButton_select_border_color, defaultBorderColor);
mSelectCirlceColor = a.getColor(R.styleable.SwitchButton_select_cricle_color, defaultSelectCircleColor);
mUnSelectCircleColor = a.getColor(R.styleable.SwitchButton_unselect_cricle_color, defaultUnSelectCircleColor);
isChecked = a.getBoolean(R.styleable.SwitchButton_isChecked,false);
a.recycle();
initView(context);
}
private void initView(Context context) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
final float density = getResources().getDisplayMetrics().density;
mAnimMove = (int) (VELOCITY * density + 0.5f) / 150; //自動滾動速度
mClickTimeout = ViewConfiguration.getPressedStateDuration()
+ ViewConfiguration.getTapTimeout(); //點擊時間
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();//觸摸滾動Slop
mHander = new Handler();
mAnim = new AnimRunnable();
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(mBorderColor);
mPaint.setStyle(Paint.Style.STROKE);
RectF rect = new RectF(0, 0, mWidth, mHeight);
canvas.drawRoundRect(rect, mHeight/2, mHeight/2, mPaint);
mPaint.setColor(isChecked ? mSelectBg :mUnSelectBg);
RectF innerRect = new RectF(1, 1, mWidth -1, mHeight -1);
canvas.drawRoundRect(innerRect, mHeight/2 -1, mHeight/2 -1, mPaint);
mPaint.setColor(isChecked ? mSelectCirlceColor : mUnSelectCircleColor);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(mCriclePostion, mHeight/2, mHeight/2 -1, mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if(isScroll){
return false;
}
firstDownX = x;
firstDownY = y;
lastDownX = x;
mCriclePostion = isChecked ? mEndCirclePos : mStartCriclePos;
break;
case MotionEvent.ACTION_MOVE:
float delaX = x - lastDownX;
setCriclePositon(delaX);
lastDownX = x;
invalidate();
break;
case MotionEvent.ACTION_UP:
float totalX = x - firstDownX;
float totalY = y - firstDownY;
float time = event.getEventTime() - event.getDownTime();
if(totalX < mTouchSlop && totalY mWidth -mHeight /2){
mCriclePostion = mWidth -mHeight /2;
stopView(true);
}
}
invalidate();
}
//停止移動View
private void stopView(boolean endChecked) {
mHander.removeCallbacks(mAnim);
isScroll = false;
isChecked = endChecked;
//回調監聽事件
if(mOnCheckChangeListener != null){
mOnCheckChangeListener.OnCheck(SwitchButton.this, isChecked);
}
}
}
//設置圓心的位置
private synchronized void setCriclePositon(float delaX){
int pos = (int) (mCriclePostion + delaX);
if(pos < mHeight / 2){
mCriclePostion = mHeight / 2;
}else if(pos > mWidth - mHeight /2){
mCriclePostion = mWidth - mHeight /2;
}else{
mCriclePostion = pos;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if(widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST){
mWidth = DEFAULT_WIDTH;
}else{
mWidth = MeasureSpec.getSize(widthMeasureSpec);
}
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if(heightMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.AT_MOST){
mHeight = DEFAULT_HEIGTH;
}else{
mHeight = MeasureSpec.getSize(heightMeasureSpec);
}
mStartCriclePos = mHeight / 2;
mEndCirclePos = mWidth - mHeight /2;
mCriclePostion = isChecked ? mEndCirclePos :mStartCriclePos;
setMeasuredDimension(mWidth, mHeight);
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
invalidate();
}
public void setOnCheckChangeListener(OnCheckChangeListener onCheckChangeListener) {
this.mOnCheckChangeListener = onCheckChangeListener;
}
}
attrs:
UI控件之ProgressBar(進度條)
(一)概述(二)常用屬性與基礎實例從官方的API我們可以看到這樣一個類的關系圖:常用屬性詳解 :對應在java我們可以調用下述方法:先看看系統給我們提供的進度條吧運行效果
Android動畫之補間動畫(Tween Animation)基礎學習
前言之前說過了在Android中,動畫Animation的實現有兩種方式:Tween Animation(漸變動畫)和Frame Animation(幀動畫)。漸變動畫是
Android 使用Vitamio打造自己的萬能播放器(10)—— 本地播放 (縮略圖、視頻信息、視頻掃描服務)
前言 Vitamio是我們團隊的誠意之作,除了要將VPlayer打造成Android最好的播放器,也要將Vitamio打造成Android最好的播放器組件。新版
activity 啟動模式
最近新參加的項目中使用到了activity的singleInstance 模式並在開發中產生了一些bug,發現組內的同事們對launchmode這件事情還缺少一些基本的認
Android系統之路(初識MTK) ------ System-Bluetooth name/WiFi AP name/sleep add never/Notification popup
今天拿到一個客戶新的訂單需求,大概有40多個需求,今天先講更改系統的藍牙