当前位置: 首页 > article >正文

安卓framework美化手势导航侧滑返回UI

文章目录

  • 手势导航的侧滑返回效果图
    • 原生效果如下:
    • 要实现的功能,:
  • 实现代码
    • 1. 初始化代码
    • 2. 修改绘制的代码,进行箭头与退出UI的显示
    • 3. 拖动的时候手指上下移动时,箭头ui跟着移动
  • 以下是一些其他可以美化安卓右滑手势拖动 UI 的方法:
    • 视觉效果方面
    • 形状和布局方面

安卓原生手势导航的侧滑返回效果很单一, 就一个箭头, 大部分手机厂商都会定制这块

手势导航的侧滑返回效果图

原生效果如下:

在这里插入图片描述

要实现的功能,:

  1. 美化箭头
  2. 显示一个动态的凸出画面
  3. 画面跟随手指位置上下滑动
    如下图
    在这里插入图片描述

实现代码

主要修改
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java

1. 初始化代码

//初始化代码
private float mLastY;
private Paint mWavePaint;
private Path mBezierPath;
private Paint mArrowPaint;
mBezierPath = new Path();
mWavePaint = new Paint();
mWavePaint.setAntiAlias(true);
mWavePaint.setStrokeWidth(dp(1.5f));
mWavePaint.setStyle(Paint.Style.FILL);
mWavePaint.setColor(mProtectionColor);

mArrowPaint = new Paint();
mArrowPaint.setStrokeWidth(mArrowThickness);
mArrowPaint.setStrokeCap(Paint.Cap.ROUND);
mArrowPaint.setAntiAlias(true);
mArrowPaint.setColor(Color.WHITE);
mArrowPaint.setStyle(Paint.Style.STROKE);
mArrowPaint.setStrokeJoin(Paint.Join.ROUND);

mLastY用于记录上次手势UI显示的坐标, 在手指按下的瞬间, 更新mLastY的值.

@Override
public void onMotionEvent(MotionEvent event) {
    if (mVelocityTracker == null) {
        mVelocityTracker = VelocityTracker.obtain();
    }
    mVelocityTracker.addMovement(event);
    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
            mDragSlopPassed = false;
            resetOnDown();
            mStartX = event.getX();
            mStartY = event.getY();
            mLastY = mStartY; // 手势按下时,重新赋值mLastY

2. 修改绘制的代码,进行箭头与退出UI的显示

添加的UI基于贝塞尔曲线实现的

@Override
protected void onDraw(Canvas canvas) {
    float pointerPosition = mCurrentTranslation - mArrowThickness / 2.0f;
    /*
       canvas.save();
       canvas.translate(
       mIsLeftPanel ? pointerPosition : getWidth() - pointerPosition,
       (getHeight() * 0.5f) + mVerticalTranslation);

    // Let's calculate the position of the end based on the angle
    float x = (polarToCartX(mCurrentAngle) * mArrowLength);
    float y = (polarToCartY(mCurrentAngle) * mArrowLength);
    Path arrowPath = calculatePath(x,y);
    if (mShowProtection) {
    canvas.drawPath(arrowPath, mProtectionPaint);
    }

    canvas.drawPath(arrowPath, mPaint);
    canvas.restore();
    */

    float height = getHeight();
    float maxWidth = getWidth();
    float centerY = height / 2;
    float progress = currentWidth / maxWidth;
    if (progress == 0) {
        return;
    }
    float footX = mIsLeftPanel ? 0 : getWidth();
    mWavePaint.setAlpha((int) (200 * progress));
    float bezierWidth = mIsLeftPanel ? currentWidth / 2 : (getWidth() - currentWidth / 2);
    mBezierPath.reset();
    mBezierPath.moveTo(footX, 0);

      // 使用常量代替重复计算的分数值
    final float quarterHeight = height / 4f;
    final float threeEighthsHeight = height * 3f / 8;
    final float fiveEighthsHeight = height * 5f / 8;
    final float threeQuartersHeight = height * 3f / 4;

    mBezierPath.cubicTo(footX, quarterHeight, bezierWidth, threeEighthsHeight, bezierWidth, centerY);
    mBezierPath.cubicTo(bezierWidth, fiveEighthsHeight, footX, threeQuartersHeight, footX, height);

    canvas.drawPath(mBezierPath, mWavePaint);

    mArrowPaint.setAlpha((int) (255 * progress));

    // 画箭头
    float arrowLeft = mIsLeftPanel? currentWidth / 6 : getWidth() - currentWidth / 6;
    float arrowEnd = arrowLeft + mArrowLength * progress;
    float[] lines = {arrowEnd, centerY - mArrowLength, arrowLeft, centerY,
            arrowLeft, centerY, arrowEnd, centerY + mArrowLength};
    canvas.drawLines(lines, mArrowPaint);
}

3. 拖动的时候手指上下移动时,箭头ui跟着移动

private void handlemoveevent(motionevent event) {
    float x = event.getx();
    float y = event.gety();

    if ((x - mstartx)<0){
        // 忽略左滑
        return;
    }

    // .....
    // 拖动的时候手指上下移动时,箭头ui跟着移动
    float movey = event.gety() - mlasty;
    if (movey != 0) {
        mlasty = event.gety();
        mlayoutparams.y += movey;
        // 更新位置
        mwindowmanager.updateviewlayout(this, mlayoutparams);
    }
}

以下是一些其他可以美化安卓右滑手势拖动 UI 的方法:

视觉效果方面

  1. 添加渐变颜色:
    在绘制拖动 UI 的画笔(Paint)上设置渐变效果。例如,使用线性渐变(LinearGradient)或者径向渐变(RadialGradient)。这样在拖动过程中,颜色可以从一种过渡到另一种,增加视觉丰富度。
  2. 增加光影效果:
    使用不同的阴影绘制技巧。比如,在拖动元素的下方绘制一个半透明的、模糊的阴影,模拟出元素浮于界面之上的效果。可以通过设置 Paint 的阴影属性或者使用专门的图形处理库来实现更复杂的阴影效果。
  3. 粒子效果:
    当进行右滑拖动时,在拖动元素的周围产生一些粒子(如发光的小点、星尘等)。这些粒子可以随机运动、逐渐消失,给用户带来更加生动的交互体验。可以通过自定义粒子类和动画来实现。
    动画效果方面
  4. 弹性动画:
    当拖动接近最大距离或者释放拖动时,让拖动 UI 元素表现出弹性效果。例如,使用弹性插值器(如 OvershootInterpolator)来使元素在动画过程中超出目标位置然后再回弹,增加交互的趣味性。

形状和布局方面

  1. 复杂形状设计:
    设计更加复杂的拖动 UI 形状,不仅仅局限于常见的几何形状或者贝塞尔曲线。例如,设计一个类似花瓣形状、或者具有独特艺术风格的形状,通过路径绘制(Path)来实现。
  2. 嵌套布局:
    在拖动 UI 元素内部使用嵌套的布局和元素。比如,在一个主要的拖动形状内部包含一些小的装饰元素、图标或者文字,这些内部元素可以有自己独立的动画和交互效果。
    作者:帅得不敢出门

http://www.kler.cn/news/302669.html

相关文章:

  • OpenAI O1:人工智能推理能力的新里程碑
  • 快讯丨深蓝L07将于9月20日正式上市
  • 【视频教程】遥感云大数据在灾害、水体与湿地领域典型案例实践及GPT模型应用
  • 【从问题中去学习k8s】k8s中的常见面试题(夯实理论基础)(二十七)
  • 自测的重要性
  • 如何分辨IP地址是否能够正常使用
  • DFS算法专题(二)——穷举vs暴搜vs深搜vs回溯vs剪枝【OF决策树】
  • 2024网络安全人才实战能力白皮书安全测试评估篇
  • Python中列表、元组、字典和集合的详细解释
  • 用Java实现人工智能
  • Linux 安装神州通用数据库 ShenTong7.0.8_342.92_linux64
  • 大数据集群搭建以及使用过程中几个实用的shell脚本
  • Django 创建好的模块怎么在后台显示
  • 锐捷交换机常用命令
  • 李沐深度学习 自制数据集
  • Iptables命令常用命令
  • C#中的闭包
  • 2024.9.13 Python与图像处理新国大EE5731课程大作业,SIFT 特征和描述符,单应性矩阵透视变换
  • redis常见的数据类型?
  • 解决:Module build failed (from ./node_modules/sass-loader/dist/cjs.js)问题
  • 秋招突击——9/10、9\11——算法练习——携程笔试练习——2024年秋招第一批笔试
  • 数据库的实施过程分析
  • 【白话树】之 树的基本知识、存储结构和二叉树转换
  • RabbitMQ创建交换机和队列——配置类 注解
  • Idea 创建 Maven项目的时候卡死
  • 体育数据API纳米足球数据API:足球数据接口文档API示例⑫
  • 【解决方案】双系统中修复ubuntu引导
  • 【算法】-单调队列
  • 数据库系统 第43节 数据库复制
  • LabVIEW回转马达试验系统