zoukankan      html  css  js  c++  java
  • [Android] Android 锁屏实现与总结 (三)

    上接:

    Android 锁屏实现与总结 (二)

     

    系列文章链接如下:

    [Android] Android 锁屏实现与总结 (一)

    [Android] Android 锁屏实现与总结 (二)

    [Android] Android 锁屏实现与总结 (三)

    代码文件地址:

    https://github.com/wukong1688/Android-BaseLockScreen

     

    3、按键的屏蔽

    当自定义锁屏页最终出现在手机上时,我们希望它像系统锁屏页那样屹立不倒,所有的按键都不能触动它,只有通过划屏或者指纹才能解锁,因此有必要对按键进行一定程度上的屏蔽。针对只有虚拟按键的手机,我们可以通过隐藏虚拟按键的方式部分解决这个问题。但是当用户在锁屏页底部滑动,隐藏后的虚拟按键还是会滑出,而且如果用户是物理按键的话就必须进行屏蔽了。需要重写Activity的onBackPressed()方法即可。


    public boolean onKeyDown(int keyCode, KeyEvent event) {
            int key = event.getKeyCode();
            switch (key) {
                case KeyEvent.KEYCODE_BACK: {
                    return true;
                }
                case KeyEvent.KEYCODE_MENU: {
                    return true;
                }
            }
            return super.onKeyDown(keyCode, event);
        }
     
    Home键 与Recent键的点击事件是在framework层进行处理的,因此onKeyDown()与dispatchKeyEvent()都捕获不到点击事件。关于这两个按键的屏蔽方法,网上相关的资料有很多,有的用到了反射,有的通过改变Window的标志位和Type等,总的来说这些方法只对部分android版本有效,有的则完全无法编译通过。其实这么做的目的无非是为了实现一个纯粹的锁屏页,但是这种做法容易造成锁屏页的异常崩溃,我们要满足的是用户在锁屏页的快捷操作,Home键和Recent键无关痛痒,基本可以不管。


    4、滑屏解锁
     
    做完以上几步,当屏幕熄灭后,再打开屏幕就能够看到我们的自定义锁屏页了。接下来要实现划屏解锁。
     
    实现滑屏解锁的类LockScreenView.java:
    package com.jack.applockscreen.activity;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Paint.Align;
    import android.graphics.Paint.Style;
    import android.graphics.Point;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.support.v4.view.ViewConfigurationCompat;
    import android.text.TextPaint;
    import android.util.AttributeSet;
    import android.view.Display;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.view.WindowManager;
    
    import com.jack.applockscreen.R;
    
    
    /**
     * 解锁按钮控件
     *
     * @author chenglei
     */
    public class LockScreenView extends View {
    
        private int mWidth;
        private int mHeight;
    
        private int mScreenWidth;
        private int mScreenHeight;
        private WindowManager mWindowManager;
        private Display mDisplay;
        private float mTouchPadRadius;
        private float mTouchPadBorderWidthNormal;
        private float mTouchPadBorderWidthPressed;
        private Paint mPaintNormal;
        private TextPaint mTextPaint;
        private Paint mBackgroundPaint;
    
        private Point mTouchPadCenter = new Point();
    
        private int mTouchSlop;
        private int mStartX;
        private int mCurrX;
        private int mOffectX;
        private boolean mCanMove;
    
        private Drawable mDrawableLeft;
        private Drawable mDrawableRight;
        private Drawable mDrawableCenter;
        private String mTextLeft;
        private String mTextRight;
    
        private Point mTargetDrawableLeftPosition = new Point();
        private Point mTargetDrawableRightPosition = new Point();
        private Point mTargetTextLeftPosition = new Point();
        private Point mTargetTextRightPosition = new Point();
        private float mDensity;
        private static final float TOUCH_PAD_BORDER_WIDTH_NORMAL = 3;
        private static final float TOUCH_PAD_BORDER_WIDTH_PRESSED = 3;
        private static final float TARGET_DRAWABLE_PADDING = 32;
        private static final float TARGET_TEXT_SIZE = 16;
    
        private static final int STATE_TRIGGER_NONE = 0;
        private static final int STATE_TRIGGER_LEFT = 1;
        private static final int STATE_TRIGGER_RIGHT = 2;
        private int mTouchPadTriggerState = STATE_TRIGGER_NONE;
    
        private OnTriggerListener mOnTriggerListener;
    
        private Drawable mDotsLeft;
        private Drawable mDotsRight;
    
        public LockScreenView(Context context) {
            this(context, null, 0);
        }
    
        public LockScreenView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public LockScreenView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        private void init() {
            mWindowManager = ((Activity) getContext()).getWindowManager();
            mDisplay = mWindowManager.getDefaultDisplay();
            mScreenWidth = mDisplay.getWidth();
            mScreenHeight = mDisplay.getHeight();
    
    //        mTouchPadBorderWidthNormal = DensityUtil.dip2px(getContext(), 8);
    //        mTouchPadBorderWidthPressed = DensityUtil.dip2px(getContext(), 2);
    
            mDensity = getResources().getDisplayMetrics().density;
            mTouchPadBorderWidthNormal = TOUCH_PAD_BORDER_WIDTH_NORMAL * mDensity;
            mTouchPadBorderWidthPressed = TOUCH_PAD_BORDER_WIDTH_PRESSED * mDensity;
    
            final ViewConfiguration configuration = ViewConfiguration.get(getContext());
            mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
    
            mDrawableCenter = getResources().getDrawable(R.mipmap.ic_launcher);
            mDotsLeft = getResources().getDrawable(R.mipmap.keyguaid_dots_left);
            mDotsRight = getResources().getDrawable(R.mipmap.keyguaid_dots_right);
    
            initNormalPaint();
            initTextPaint();
        }
    
        private void initNormalPaint() {
            mPaintNormal = new Paint();
            mPaintNormal.setFlags(Paint.ANTI_ALIAS_FLAG);
            mPaintNormal.setColor(Color.WHITE);
            mPaintNormal.setStyle(Style.STROKE);
            mPaintNormal.setStrokeWidth(mTouchPadBorderWidthNormal);
            mBackgroundPaint = new Paint();
            mBackgroundPaint.setColor(Color.parseColor("#66000000"));
        }
    
        private void initTextPaint() {
            mTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
            mTextPaint.setColor(Color.WHITE);
            mTextPaint.setTextAlign(Align.CENTER);
            mTextPaint.setTextSize(TARGET_TEXT_SIZE * mDensity);
        }
    
    
        @Override
        protected void onDraw(Canvas canvas) {
            drawBackground(canvas);
            drawDots(canvas);
            drawTouchPad(canvas);
            drawTargetDrawablesAndTexts(canvas);
        }
    
        private void drawBackground(Canvas canvas) {
            canvas.drawRect(0, mHeight / 4, mWidth, mHeight * 3 / 4, mBackgroundPaint);
        }
    
        private void drawDots(Canvas canvas) {
            if (!mTouchDown) {
                BitmapDrawable dotsLeft = (BitmapDrawable) mDotsLeft;
                BitmapDrawable dotsRight = (BitmapDrawable) mDotsRight;
                canvas.drawBitmap(dotsLeft.getBitmap(),
                        mWidth / 4 - mDotsLeft.getIntrinsicWidth() / 2,
                        mHeight / 2 - mDotsLeft.getIntrinsicHeight() / 2,
                        mPaintNormal);
                canvas.drawBitmap(dotsRight.getBitmap(),
                        mWidth * 3 / 4 - mDotsRight.getIntrinsicWidth() / 2,
                        mHeight / 2 - mDotsRight.getIntrinsicHeight() / 2,
                        mPaintNormal);
            }
        }
    
        private void drawTouchPad(Canvas canvas) {
            BitmapDrawable bd = (BitmapDrawable) mDrawableCenter;
            if (mTouchDown) {
                canvas.drawCircle(mTouchPadCenter.x, mTouchPadCenter.y, mDrawableCenter.getIntrinsicWidth() - 20, mPaintNormal);
            } else {
                canvas.drawBitmap(bd.getBitmap(),
                        mTouchPadCenter.x - mDrawableCenter.getIntrinsicWidth() / 2,
                        mTouchPadCenter.y - mDrawableCenter.getIntrinsicHeight() / 2,
                        mPaintNormal);
                canvas.drawCircle(mTouchPadCenter.x, mTouchPadCenter.y, mDrawableCenter.getIntrinsicWidth() - 20, mPaintNormal);
            }
        }
    
        private void drawTargetDrawablesAndTexts(Canvas canvas) {
            if (mDrawableLeft != null) {
                BitmapDrawable bd = (BitmapDrawable) mDrawableLeft;
                canvas.drawBitmap(
                        bd.getBitmap(),
                        mTargetDrawableLeftPosition.x - mDrawableLeft.getIntrinsicWidth() / 2,
                        mTargetDrawableLeftPosition.y - mDrawableLeft.getIntrinsicHeight() / 2,
                        mPaintNormal);
            }
    
            if (mDrawableRight != null) {
                BitmapDrawable bd = (BitmapDrawable) mDrawableRight;
                canvas.drawBitmap(
                        bd.getBitmap(),
                        mTargetDrawableRightPosition.x - mDrawableRight.getIntrinsicWidth() / 2,
                        mTargetDrawableRightPosition.y - mDrawableRight.getIntrinsicHeight() / 2,
                        mPaintNormal);
            }
    
            if (mTextLeft != null) {
                canvas.drawText(mTextLeft, mTargetTextLeftPosition.x, mTargetTextLeftPosition.y, mTextPaint);
            }
    
            if (mTextRight != null) {
                canvas.drawText(mTextRight, mTargetTextRightPosition.x, mTargetTextRightPosition.y, mTextPaint);
            }
        }
    
        @Override
        public boolean performClick() {
            return super.performClick();
        }
    
        private boolean mTouchDown = false;
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    mStartX = (int) event.getX();
                    if (mStartX > mTouchPadCenter.x - mTouchPadRadius && mStartX < mTouchPadCenter.x + mTouchPadRadius) {
                        mPaintNormal.setStrokeWidth(mTouchPadBorderWidthPressed);
                        mTouchDown = true;
                        invalidate();
                    } else {
                        return false;
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    mCurrX = (int) event.getX();
    //            mOffectX = mCurrX - mStartX;
    //            
    //            if (!mCanMove && Math.abs(mOffectX) < mTouchSlop) {
    //                return false;
    //            } else {
    //                mCanMove = true;
    //                if (mOffectX > mTouchSlop) {
    //                    mOffectX += mTouchSlop;
    //                } else if (mOffectX < -mTouchSlop) {
    //                    mOffectX -= mTouchSlop;
    //                }
    //            }
    
                    mStartX = mCurrX;
                    if (mDrawableRight != null && mCurrX < mWidth * 5 / 12 /*mTargetDrawableLeftPosition.x + mDrawableRight.getIntrinsicWidth() * 2.5*/) {
                        mTouchPadCenter.set(mTargetDrawableLeftPosition.x, mTargetDrawableLeftPosition.y);
                        mTouchPadTriggerState = STATE_TRIGGER_LEFT;
                    } else if (mDrawableRight != null && mCurrX > mWidth * 7 / 12 /*mTargetDrawableRightPosition.x - mDrawableRight.getIntrinsicWidth() * 2.5*/) {
                        mTouchPadCenter.set(mTargetDrawableRightPosition.x, mTargetDrawableRightPosition.y);
                        mTouchPadTriggerState = STATE_TRIGGER_RIGHT;
                    } else {
                        mTouchPadCenter.x = mCurrX;
                        mTouchPadCenter.set(mTouchPadCenter.x + mOffectX, mTouchPadCenter.y);
                        mTouchPadTriggerState = STATE_TRIGGER_NONE;
                    }
    
    
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    mCanMove = false;
                    if (STATE_TRIGGER_NONE == mTouchPadTriggerState) {
                        mTouchPadCenter.set(mWidth / 2, mHeight / 2);
                        //mPaintNormal.setStrokeWidth(mTouchPadBorderWidthNormal);
                        mTouchDown = false;
                        invalidate();
                    } else if (STATE_TRIGGER_LEFT == mTouchPadTriggerState) {
                        if (mOnTriggerListener != null) {
                            mOnTriggerListener.onTriggerLeft();
                        }
                    } else if (STATE_TRIGGER_RIGHT == mTouchPadTriggerState) {
                        if (mOnTriggerListener != null) {
                            mOnTriggerListener.onTriggerRight();
                        }
                    }
                    break;
            }
            return true;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    
            if (widthMode == MeasureSpec.EXACTLY) {
                // Parent has told us how big to be. So be it.  
                mWidth = widthSize;
            } else {
                mWidth = mScreenWidth;
    
                // Check against our minimum width
                mWidth = Math.max(mWidth, getSuggestedMinimumWidth());
    
                if (widthMode == MeasureSpec.AT_MOST) {
                    mWidth = Math.min(widthSize, mWidth);
                }
            }
    
            if (heightMode == MeasureSpec.EXACTLY) {
                mHeight = heightSize;
            } else {
                mHeight = mScreenHeight / 4;
    
                // Check against our minimum width
                mHeight = Math.max(mHeight, getSuggestedMinimumHeight());
    
                if (heightMode == MeasureSpec.AT_MOST) {
                    mHeight = Math.min(heightSize, mHeight);
                }
            }
    
            setMeasuredDimension(mWidth, mHeight);
            mTouchPadRadius = mDrawableCenter.getIntrinsicWidth();
    
            mTouchPadCenter.set(mWidth / 2, mHeight / 2);
    
            mTargetDrawableLeftPosition.set((int) (TARGET_DRAWABLE_PADDING * mDensity), mHeight / 2);
            mTargetDrawableRightPosition.set((int) (mWidth - TARGET_DRAWABLE_PADDING * mDensity), mHeight / 2);
            mTargetTextLeftPosition.set((int) (TARGET_DRAWABLE_PADDING * mDensity), (int) (mHeight / 2 - 20 * mDensity));
            mTargetTextRightPosition.set((int) (mWidth - TARGET_DRAWABLE_PADDING * mDensity), (int) (mHeight / 2 - 20 * mDensity));
        }
    
        public void setTargetDrawablesAndTexts(Drawable drawableLeft, Drawable drawableRight, String textLeft, String textRight) {
            mDrawableLeft = drawableLeft;
            mDrawableRight = drawableRight;
            mTextLeft = textLeft;
            mTextRight = textRight;
            invalidate();
        }
    
        public void setTargetDrawablesAndTexts(int drawableLeftId, int drawableRightId, String textLeft, String textRight) {
            mDrawableLeft = drawableLeftId > 0 ? getResources().getDrawable(drawableLeftId) : null;
            mDrawableRight = drawableRightId > 0 ? getResources().getDrawable(drawableRightId) : null;
            mTextLeft = textLeft;
            mTextRight = textRight;
            invalidate();
        }
    
        public interface OnTriggerListener {
            public void onTriggerLeft();
    
            public void onTriggerRight();
        }
    
        public void setOnTriggerListener(OnTriggerListener l) {
            mOnTriggerListener = l;
        }
    
    }

    很多朋友私下问我代码文件的位置,这里也贴出来分享给大家!

    Github地址:

    https://github.com/wukong1688/Android_BaseLockScreen

    本博客地址: wukong1688

    本文原文地址:https://www.cnblogs.com/wukong1688/p/10725092.html

    转载请著名出处!谢谢~~

     
  • 相关阅读:
    Mybaits-plus实战(三)
    Mybaits-plus实战(二)
    Mybaits-plus实战(一)
    面向对象的理解
    如何理解算法
    将yyyyMMdd HH:mm:ss格式的时间转换成时间类型
    泛型/dynamic/object作用
    成功之道
    ASP.NET注意事项
    Razor引擎总结
  • 原文地址:https://www.cnblogs.com/wukong1688/p/10727247.html
Copyright © 2011-2022 走看看