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

news2024/9/20 18:50:36

文章目录

  • 手势导航的侧滑返回效果图
    • 原生效果如下:
    • 要实现的功能,:
  • 实现代码
    • 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.coloradmin.cn/o/2118466.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「电商运营」高客单和低客单产品及选品的运营区别

高客单和低客单产品在运营重点和选品方向上存在明显的差异。在实际运营中&#xff0c;需要根据产品的特点和市场需求&#xff0c;制定合适的运营策略和选品方向&#xff0c;以实现产品的成功运营和盈利。 一、高客单产品运营重点 1、目标客户精准定位 由于高客单产品价格较高…

深度解析Unix系统的基本概念及优缺点和原理

介绍 Unix系统是一种多用户、多任务、分时操作系统&#xff0c;起源于20世纪70年代初&#xff0c;由贝尔实验室开发。它具有强大的命令行接口和层次结构的文件系统&#xff0c;支持多种处理器架构&#xff0c;广泛应用于工程应用和科学计算等领域。 基本概念 一、Unix系统的起…

以实时,见未来——DolphinDB 2024 年度峰会圆满举办

2024年9月6日&#xff0c;“以实时&#xff0c;见未来”—— DolphinDB 2024 年度峰会在杭州圆满落下帷幕。本次峰会由主会场与三个专题分会场组成&#xff0c;众多金融机构领导与专家、行业领袖、高校与研究机构学者等近300位嘉宾共襄盛举&#xff0c;一同探讨数智化浪潮下金融…

乐鑫无线WiFi芯片模组,家电设备智能联网新体验,启明云端乐鑫代理商

在当今这个数字化飞速发展的时代&#xff0c;智能家居和物联网(IoT)设备已经成为我们生活中不可或缺的一部分。随着技术的进步&#xff0c;我们对于设备联网的需求也在不断提升。 智能家居、智能门锁、智能医疗设备等&#xff0c;这些设备通过联网实现了数据的实时传输和远程控…

【AI绘画】Midjourney光影控制详解

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;为什么要学习光影控制光影控制的作用 &#x1f4af;强化主题hard lighting&#xff08;硬光 &#xff09;soft lighting&#xff08;软光/柔光&#xff09;测试 &…

C++进阶——多态

什么是多态&#xff1f;通俗来说&#xff0c;就是多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生不同的状态。 举个栗子&#xff1a;比如买票这个行为&#xff0c;当普通人买票时&#xff0c;是全价买票&#xff1b;学生买票时&#xf…

数据库进阶:2.索引

1.数据库中的索引 1.1索引的概念 介绍&#xff1a;索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构&#xff08;有序&#xff09;。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#x…

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天&#xff0c;AI绘图作为一种新兴技术&#xff0c;不仅改变了艺术创作的方式&#xff0c;也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式&#xff0c;帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具&#x…

第四届“长城杯”网络安全大赛 暨京津冀网络安全技能竞赛(初赛) 全方向 题解WriteUp

战队名称&#xff1a;TeamGipsy 战队排名&#xff1a;18 SQLUP 题目描述&#xff1a;a website developed by a novice developer. 开题&#xff0c;是个登录界面。 账号admin&#xff0c;随便什么密码都能登录 点击头像可以进行文件上传 先简单上传个木马试试 测一下&…

保姆级别带你了解个股场外期权的交易买卖流程

今天期权懂带你了解保姆级别带你了解个股场外期权的交易买卖流程。个股场外期权的交易方式主要包括电话或电子邮件协商、中介平台撮合、电子交易系统、合约签订和定制化服务。 场外个股期权交易买卖流程 第一&#xff0c;个人想要参与交易个股场外期权需要通过合法的金融机构…

最新篇 接口测试工具Postman 企业常规面试题出炉~(附答案)

面试题目录 说下你对Postman的了解&#xff1f; Postman你在工作中使用流程是什么样的&#xff1f; Postman 你使用了哪些功能&#xff1f; Postman 里面如何管理测试环境&#xff1f; Postman如何设置关联&#xff1f;postman参数化有哪几种方式&#xff1f; 在postman中&…

Qt/C++ Mysql数据库用户登录分配软件(源码分享)

功能简介&#xff1a; 这是一个基于 Qt/C 实现的简单 MySQL 用户权限管理系统&#xff0c;能够通过控制台交互输入进行数据库连接、用户创建、权限分配以及用户查询的自动化操作。用户可以通过该软件登录到 MySQL 服务器&#xff0c;选择数据库&#xff0c;并根据需求创建新用…

拍摄录制剪辑太麻烦?一键生成3D文旅视频的AI神器来了!

AI正在改变世界。 从Chat GPT的横空出世到大语言模型的爆发&#xff0c;AI开始融入人们的生活&#xff0c;人类与AI的对话无处不在&#xff1b; Midjournery等文生图工具&#xff0c;让“神笔马良”走进现实&#xff0c;每个人都能用AI创作出生动的图片&#xff1b; Sora更是…

引入sqlite作为云盒和硬盒子驱动的日志记录功能

1.下载源码 wget https://www.sqlite.org/2024/sqlite-autoconf-3460100.tar.gz 2.解压安装与引用 注意&#xff1a;不能将源码下载到Windows和虚拟机的共享文件夹下&#xff0c;自动构建的时候会导致一系列的问题 ./configure CCgcc --prefix/usr/lib

VMware虚拟机上安装openfileresa开源的NAS存储管理解决方案和ISCSI共享磁盘存储

目录 文章目录 目录说明下载安装镜像创建虚拟机安装 openfileresa 操作系统重新启动系统使用 root 用户登录使用内置的用户 openfiler 登录 创建 ISCSI 的共享存储1、添加存储硬盘2、查看添加的磁盘3、对硬盘分区4、创建卷组(Volume Group)5、创建数据卷(Volume)6、启动 ISCSI …

解决 蚁剑AntSword 连接后 ,命令回显 有问题 (ret=127) 的方法

在渗透测试过程中&#xff0c;我们在 连接上蚁剑 后&#xff0c;想要 进行 命令执行查看一些信息&#xff0c; 发现无论输入任何指令&#xff0c;返回的信息 只有 ret127&#xff0c;要解决这种问题&#xff0c;为大家提供一个解决方案。 蚁剑 软件&#xff0c;命令回显 只有…

深入了解以太坊

1. 以太坊编程语言和操作码 以太坊中智能合约的代码以高级语言编写&#xff0c;如 Serpent、LLL、Solidity 或 Viper,并可转换为 EVM 可以理解的字节码&#xff0c;以便执行。 Solidity 是为以太坊开发的高级语言之一&#xff0c;它具有类似 JavaScript 的语法&#xff0c;可以…

【踩坑】Vue3项目正常跑动后页面空白问题

近期踩了个坑&#xff0c;Vue3搭建的项目能够正常跑动&#xff0c;但是页面却是空白的&#xff0c;控制台也不报错&#xff0c;只留下一行警告&#xff1a; 发现是 router 入口文件&#xff08;一般是在 router 文件夹下的 index 里面&#xff09;的写法和 vite 版本不匹配的问…

AI算力池化技术在银行业的最佳实践荣获“科学普及达人奖”

纵观半个多世纪以来的金融行业发展历史&#xff0c;每一次技术升级与商业模式变革依赖科技赋能与理念创新的有力支撑&#xff0c;以人工智能为代表的新技术给金融机构了带来巨大效益。 近日&#xff0c;由中国人民银行科技司指导、北京金融科技产业联盟支持、《金融电子化》杂…

AlmaLinux 9 上配置静态 IP 地址

在 Rocky Linux 9 中&#xff0c;密钥文件的新默认存储位置在 /etc/NetworkManager/system-connections 中 cd /etc/NetworkManager/system-connections默认dhcp配置 ~ …