Android 自定義View 滑動解鎖
自定義view來繪製一個類似滑動解鎖的button,註釋都在,效果如下
程式碼在下面,替換一下資源,可以直接使用,如果需要畫的是圓角的話,需要把下面兩行註釋的DrawLine的註釋開啟,然後把兩行drawRoundRect註釋掉。
package com.vendingontrack.vendcoin.customView;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import com.vendingontrack.vendcoin.R;
public class SlideUnlockView extends View {
private Paint mPaint;//繪製背景
private Paint mTextPaint;//繪製文字
private Paint mSlideTextPaint;//滑動文字
private Paint mSwipeBgPaint;
private Bitmap mIconBitmap;
private int mWidth;
private int mHeight;
private int mPadding;
private String content = "Slide to begin";
private String mSlideContent = "VendCoin";
private Rect mTextRect;
private float mDrawX;
private boolean mCanMove;
private OnUnlockListener mListener;
private int mBackgroudColor;
private int mTextColor;
private int mIconId;
private boolean unSlide;
private int mFillColor;
private Context mContext;
private boolean isSlide;
public SlideUnlockView(Context context) {
this(context,null);
}
public SlideUnlockView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public SlideUnlockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initAttr(attrs);
init();
}
private void initAttr(AttributeSet attrs){
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.SlideUnlockView);
mBackgroudColor = ta.getColor(R.styleable.SlideUnlockView_backgroundColor,getResources().getColor(R.color.color_E9DDC7));
mTextColor = ta.getColor(R.styleable.SlideUnlockView_textColor,getResources().getColor(R.color.clolor_091431));
mIconId = ta.getResourceId(R.styleable.SlideUnlockView_icon, R.drawable.icon_thumb);
// unSlide = ta.getBoolean(R.styleable.SlideUnlockView_unSlide,false);
ta.recycle();
}
//設定為不可滑動
public void setUnSlide(boolean unable){
this.unSlide = unable;
}
private void init() {
mTextPaint = new Paint();
mTextPaint.setColor(mTextColor);
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(sp2px(getContext(),16));
mTextRect = new Rect();
mTextPaint.getTextBounds(content,0,content.length(),mTextRect);
mSlideTextPaint = new Paint();
mSlideTextPaint.setColor(mContext.getResources().getColor(R.color.color_E9DDC7));
mSlideTextPaint.setAntiAlias(true);
mSlideTextPaint.setTextSize(sp2px(getContext(),22));
// mTextRect = new Rect();
mSlideTextPaint.getTextBounds(mSlideContent,0,mSlideContent.length(),mTextRect);
mIconBitmap = BitmapFactory.decodeResource(getResources(), mIconId);
mPadding = 0;
mHeight = mIconBitmap.getHeight()+mPadding*2;
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setColor(mBackgroudColor);
mPaint.setStrokeWidth(mHeight);
mSwipeBgPaint = new Paint();
mSwipeBgPaint = new Paint();
mSwipeBgPaint.setAntiAlias(true);
mSwipeBgPaint.setStyle(Paint.Style.FILL);
mSwipeBgPaint.setStrokeCap(Paint.Cap.ROUND);
mSwipeBgPaint.setColor(mContext.getResources().getColor(R.color.clolor_091431));
mSwipeBgPaint.setStrokeWidth(mHeight);
//預設滑動圖示跟文字間的間隔
int middle = dp2px(getContext(), 20);
mWidth = mPadding + mHeight*2 + mTextRect.width() + middle *2;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int wSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int wSpecSize = MeasureSpec.getSize(widthMeasureSpec);
//如果設定的寬度比控制元件預設需求的大,則修改,否則就用預設寬度
if (wSpecMode == MeasureSpec.EXACTLY){
if (wSpecSize>mWidth){
mWidth = wSpecSize;
}
}
setMeasuredDimension(mWidth,mHeight);
}
public void setUnlockListener(OnUnlockListener listener){
mListener = listener;
}
@Override
protected void onDraw(Canvas canvas) {
if (mDrawX < mPadding ){
mDrawX = mPadding;
}else if (mDrawX > mWidth - mIconBitmap.getWidth()-mPadding){
mDrawX = mWidth - mIconBitmap.getWidth()-mPadding;
}
canvas.drawRoundRect(new RectF(0, 0, mWidth, mHeight), 18, 18, mPaint);
//畫背景顏色,需要給圓形筆鋒預留半個高度的位置
// canvas.drawLine(mHeight/2,mHeight/2,mWidth-mHeight/2,mHeight/2,mPaint);
int textX = mWidth / 2 - mTextRect.width()/2;
// canvas.drawLine(mHeight/2,mHeight/2,mDrawX+mIconBitmap.getWidth()/2,mHeight/2,mSwipeBgPaint);
canvas.drawRoundRect(new RectF(0, 0, mDrawX+mIconBitmap.getWidth(), mHeight), 18, 18, mSwipeBgPaint);
if(isSlide){
canvas.drawText(mSlideContent, textX, mHeight / 2 + mTextRect.height() / 2, mSlideTextPaint);
}else {
//繪製文字到中間位置
canvas.drawText(content, textX, mHeight / 2 + mTextRect.height() / 2, mTextPaint);
}
//根據滑動位置繪製圖示
canvas.drawBitmap(mIconBitmap,mDrawX,mPadding,mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
isSlide = false;
//如果不可滑動,立即返回
if (unSlide)return false;
if (x <= mIconBitmap.getWidth()+mPadding){
mCanMove = true;
}
return true;
case MotionEvent.ACTION_MOVE:
//如果是可移動狀態才繼續繪製
if (mCanMove){
isSlide = true;
mDrawX = x;
invalidate();
}
return true;
case MotionEvent.ACTION_UP:
isSlide = false;
//如果是可移動狀態才繼續繪製
if (mCanMove){
reset();
mCanMove = false;
//判斷是否在指定位置抬起手指
if (mDrawX >= mWidth - mIconBitmap.getWidth()-mPadding){
if (mListener!=null)
mListener.onUnlock();
}
}
break;
}
return super.onTouchEvent(event);
}
public void setmCanMove(boolean canMove){
mCanMove = canMove;
}
//用屬性動畫將圖示位置重置
private void reset(){
ObjectAnimator animator = ObjectAnimator.ofFloat(this,"mDrawX",mDrawX,mPadding);
animator.setDuration(200);
animator.start();
}
private float getMDrawX() {
return mDrawX;
}
private void setMDrawX(float mDrawX) {
this.mDrawX = mDrawX;
invalidate();
}
public interface OnUnlockListener{
void onUnlock();
}
/**
* dp轉px
*
* @param context 上下文
* @param dpValue dp值
* @return px值
*/
public static int dp2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* sp轉px
*
* @param context 上下文
* @param spValue sp值
* @return px值
*/
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}
相關文章
- 【朝花夕拾】Android自定義View篇之(十一)View的滑動,彈性滑動與自定義PagerViewAndroidView
- android 滑動刪除的listview(自定義view)AndroidView
- Android開發自定義View之滑動按鈕與自定義屬性AndroidView
- android view 自定義viewgroup 例項--螢幕滑動AndroidView
- Android自定義View(四)側滑佈局AndroidView
- 防手機鎖屏解鎖自定義ViewView
- Android自定義view詳解AndroidView
- Android 自定義 view 詳解AndroidView
- Android自定義View:View(二)AndroidView
- Android自定義滑動刻度尺Android
- Android 自定義viewAndroidView
- Android: 自定義ViewAndroidView
- Android自定義View之星球運動AndroidView
- 自定義View:側滑選單實現View
- 【朝花夕拾】Android自定義View篇之(七)Android事件分發機制(下)解決滑動衝突AndroidView事件
- Android自定義View整合AndroidView
- Android自定義view-自繪ViewAndroidView
- 自定義View:側滑選單動畫實現View動畫
- android自定義view(自定義數字鍵盤)AndroidView
- android自定義View&自定義ViewGroup(下)AndroidView
- android自定義View&自定義ViewGroup(上)AndroidView
- 重拾Android自定義ViewAndroidView
- Android自定義View教你一步一步實現薄荷健康滑動捲尺AndroidView
- 自定義view——仿酷狗的側滑選單View
- 【朝花夕拾】Android自定義View篇之(四)自定義View的三種實現方式及自定義屬性詳解AndroidView
- Android View 滑動衝突解決方式以及原理AndroidView
- Android自定義View播放Gif動畫AndroidView動畫
- Android 自定義View基礎(一)AndroidView
- Android自定義View:ViewGroup(三)AndroidView
- android自定義View——座標系AndroidView
- Android自定義View之捲尺AndroidView
- Android 自定義View之下雨動畫AndroidView動畫
- Android自定義View之分貝儀AndroidView
- Android自定義View注意事項AndroidView
- Android自定義View 水波氣泡AndroidView
- Android 自定義View 字型變色AndroidView
- Android 自定義View 點贊效果AndroidView
- Android自定義View-卷軸AndroidView