首页我们先看一下效果图

下边来说一下实现逻辑,其主要思路就是新建一个activity使其覆盖在锁屏页上边。

一、我们新建一个LockActivty,既然是四大组件之一,必不可少的在AndroidManifest.xml中注册:


这里注意,LockActivty的启动模式,我们使用singleInstance,使其单独存在一个activity task中。

android:exported="false"标签,这个标签是用来表示不能被其他应用程序组件调用或跟它交互。

android:noHistory="true",表示该Activity在task中不留历史痕迹。
style文件如下:
 

   


二、在LockActivty的onCreate方法中添加标志,使其能够在锁屏页上显示:
 

@Overrideprotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);             getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);     fullScreen(this);         setContentView(R.layout.activity_lock);}

这里同时也加入全屏的代码 fullScreen(this):

public static void fullScreen(Activity activity) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {                        //5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色                        Window window = activity.getWindow();                        View decorView = window.getDecorView();                        //两个 flag 要结合使用,表示让应用的主体内容占用系统状态栏的空间                        int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN                                             | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;                        decorView.setSystemUiVisibility(option);                        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);                        window.setStatusBarColor(Color.TRANSPARENT);            } else {                    Window window = activity.getWindow();                    WindowManager.LayoutParams attributes = window.getAttributes();                    int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;                    attributes.flags |= flagTranslucentStatus;                    window.setAttributes(attributes);            }      }}


三、重写物理返回键使其不能响应返回键。

@Overridepublic void onBackPressed() {}


四、向右滑动销毁页面,这里我们要用到触摸反馈的知识,自定义一个SlidingFinishLayout的view 继承RelativeLayout在LockActivity的布局文件中引用,这里重写onTouchEvent方法:

@Overridepublic boolean onTouchEvent(MotionEvent event) {        switch (event.getActionMasked()) {                case MotionEvent.ACTION_DOWN:                       downX = tempX = (int) event.getRawX();                       downY = (int) event.getRawY();                       break;                case MotionEvent.ACTION_MOVE:                       int moveX = (int) event.getRawX();                       int deltaX = tempX - moveX;                       tempX = moveX;                       if (Math.abs(moveX - downX) > mTouchSlop                 && Math.abs((int) event.getRawY() - downY) < mTouchSlop) {               isSliding = true;                       }                       if (moveX - downX >= 0 && isSliding) {                               mParentView.scrollBy(deltaX, 0);                        }                       break;                case MotionEvent.ACTION_UP:            i            sSliding = false;                        if (mParentView.getScrollX() <= -viewWidth / 4) {                            isFinish = true;                            scrollRight();                        } else {                                  scrollOrigin();                                  isFinish = false;                          }                       break;                default:                    break;        }        return true;}


这里只贴出了主要代码,详细代码请看demo,文章末尾会有demo地址。

五、关于下方滑动解锁text的实现,是利用了颜色渐变器和矩阵平移实现:

public class HintTextView extends AppCompatTextView {        private Paint paint;            private int mWidth;        private LinearGradient gradient;        private Matrix matrix;        /**          * 渐变的速度          */        private int deltaX;      public HintTextView(Context context) {                super(context, null);        }     public HintTextView(Context context, AttributeSet attrs) {                super(context, attrs);        }        {            paint = getPaint();        }     @Override        protected void onSizeChanged(int w, int h, int oldw, int oldh) {                super.onSizeChanged(w, h, oldw, oldh);                if(mWidth == 0 ){                        mWidth = getMeasuredWidth();                        //颜色渐变器                        gradient = new LinearGradient(0, 0, mWidth, 0, new int[]{Color.GRAY, Color.WHITE, Color.GRAY},             new float[]{0.3f,0.5f,1.0f},             Shader.TileMode.CLAMP);                        paint.setShader(gradient);                        matrix = new Matrix();                   }        }    @Override        protected void onDraw(Canvas canvas) {        super.onDraw(canvas);                if(matrix !=null){                        deltaX += mWidth / 8;                        if(deltaX > 2 * mWidth){                                deltaX = -mWidth;                         }                }                //通过矩阵的平移实现                matrix.setTranslate(deltaX, 0);                gradient.setLocalMatrix(matrix);                postInvalidateDelayed(100);       }}


六、最后我们首先新建一个service做接收锁屏键事件的逻辑,使其启动后在任何页面都可以响应锁屏事件让LockActivity出现在锁屏页面上。

1、在AndroidManifest.xml中注册service:


2、在service中注册广播接收锁屏事件,并跳转锁屏页面:

ScreenBroadcastReceiver screenBroadcastReceiver;@Nullable@Overridepublic IBinder onBind(Intent intent) {        return null;}@Overridepublic void onCreate() {        super.onCreate();        screenBroadcastReceiver = new ScreenBroadcastReceiver();        final IntentFilter filter = new IntentFilter();        filter.addAction(Intent.ACTION_SCREEN_OFF);        registerReceiver(screenBroadcastReceiver, filter);}public class ScreenBroadcastReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {                handleCommandIntent(intent);            }    }private void handleCommandIntent(Intent intent) {        final String action = intent.getAction();        if (Intent.ACTION_SCREEN_OFF.equals(action) ){                Intent lockScreen = new Intent(this, LockActivity.class);                lockScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                startActivity(lockScreen);            }    }    @Override    public void onDestroy() {            super.onDestroy();            unregisterReceiver(screenBroadcastReceiver); }


这样,锁屏页面的实现就大概完成了,有一点要注意的是像小米、vivo、等一些手机会有锁屏显示和后台弹出界面权限,默认是关闭的,需要手动打开。解决这个问题最好的方式大概是加白名单吧,哈哈。

更多相关文章

  1. android WebView(二)缩放
  2. Android开发中Material Design风格设置页面的实践
  3. 移动经分升级到 android4.x 版本后的一个bug与解决方案.
  4. 2D平面中关于矩阵(Matrix)跟图形变换的讲解
  5. Android实现记事本项目完整实例,附源代码
  6. Android(安卓)应用的动画实践--View Animation篇
  7. android webview js交互之自定义错误加载界面(重新刷新)
  8. Flutter学习六之实现一个带筛选的列表页面
  9. Android(安卓)tv 动画效果faq (放大动画 与ScrollView滚动照成 页

随机推荐

  1. Android(安卓)P PackageManagerService
  2. Android搭建客户端连接java构建的服务端
  3. Android内容提供器
  4. Android(安卓)自定义组件之如何实现自定
  5. Android(安卓)Ormlite 学习笔记1 -- 基础
  6. Android(安卓)Chronometer(计时器)
  7. Android(安卓)TextView字体设置
  8. Frida对Android(安卓)app的JS脚本注入方
  9. Android(安卓)Studio使用来自控制台的模
  10. android中gridview的居中问题