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

Android 10.0 Launcher3拖拽图标进入hotseat自适应布局功能实现一

1.前言

在10.0的系统rom定制化开发中,在对于launcher3的一些开发定制中,在对hotseat的一些开发中,需要实现动态hotseat居中
的功能,就是在拖拽图标进入和拖出hotseat,都可以保持hotseat居中的功能,接下来分析下相关功能实现
具体如图:


2.Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心类

packages\apps\Launcher3\src\com\android\launcher3\Hotseat.java

3.Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心功能分析和实现

Launcher顾名思义,就是桌面的意思,也是android系统启动后第一个启动的应用程序,
:Launcher3负责管理和展示用户手机桌面上的各个应用程序图标。它通过GridView或者LinearLayout等布局管理器将
图标进行排列,并支持滑动、放大缩小等手势操作
Hotseat也是属于在导航栏底部的BubbleTextView的布局,只是不显示app图标

3.1 Hotseat.java相关添加背景功能分析

在实现Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心功能中,通过上述的分析得知,
首选需要给Hotseat添加背景功能,然后需要根据hotseat的数量多少来设置hotseat的宽度高度等
相关参数,这样就实现了第一步的hotseat的居中显示功能,

public class Hotseat extends CellLayout implements LogContainerProvider, Insettable, Transposable {@ViewDebug.ExportedProperty(category = "launcher")public boolean mHasVerticalHotseat;private final HotseatController mController;public Hotseat(Context context) {this(context, null);}public Hotseat(Context context, AttributeSet attrs) {this(context, attrs, 0);}public Hotseat(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mController = LauncherAppMonitor.getInstance(context).getHotseatController();}public HotseatController getController() {return mController;}/* Get the orientation specific coordinates given an invariant order in the hotseat. */public int getCellXFromOrder(int rank) {return mHasVerticalHotseat ? 0 : rank;}public int getCellYFromOrder(int rank) {return mHasVerticalHotseat ? (getCountY() - (rank + 1)) : 0;}public void resetLayout(boolean hasVerticalHotseat) {removeAllViewsInLayout();mHasVerticalHotseat = hasVerticalHotseat;InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;if (hasVerticalHotseat) {setGridSize(1, idp.numHotseatIcons);} else {setGridSize(idp.numHotseatIcons, 1);}//add core start// 添加背景if(idp.numHotseatIcons>0){setBackgroundResource(R.drawable.shape_corner);}//add core end}@Overridepublic void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {target.gridX = info.cellX;target.gridY = info.cellY;targetParent.containerType = LauncherLogProto.ContainerType.HOTSEAT;}@Overridepublic void setInsets(Rect insets) {FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();DeviceProfile grid = mActivity.getWallpaperDeviceProfile();insets = grid.getInsets();if (grid.isVerticalBarLayout()) {lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;if (grid.isSeascape()) {lp.gravity = Gravity.LEFT;lp.width = grid.hotseatBarSizePx + insets.left;} else {lp.gravity = Gravity.RIGHT;lp.width = grid.hotseatBarSizePx + insets.right;}} else {lp.gravity = Gravity.BOTTOM;lp.width = ViewGroup.LayoutParams.MATCH_PARENT;lp.height = grid.hotseatBarSizePx + insets.bottom;}Rect padding = grid.getHotseatLayoutPadding();setPadding(padding.left, padding.top, padding.right, padding.bottom);setLayoutParams(lp);InsettableFrameLayout.dispatchInsets(this, insets);}@Overridepublic boolean onTouchEvent(MotionEvent event) {// Don't let if follow through to workspacereturn true;}@Overridepublic RotationMode getRotationMode() {return Launcher.getLauncher(getContext()).getRotationMode();}
}

在实现Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心功能中,通过上述的分析得知,
在Hotseat中相关源码分析,可以发现由
resetLayout 就是负责布局的 当hotseat 增加减少时都会重新布局
所以在setBackgroundResource(R.drawable.shape_corner);添加背景就可以了

  public void resetLayout(boolean hasVerticalHotseat) {removeAllViewsInLayout();mHasVerticalHotseat = hasVerticalHotseat;InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;if (hasVerticalHotseat) {setGridSize(1, idp.numHotseatIcons);} else {setGridSize(idp.numHotseatIcons, 1);}// 添加背景if(idp.numHotseatIcons>0){setBackgroundResource(R.drawable.shape_corner);}}shape_corner.xml<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><!--背景颜色--><solid android:color="#FFFAFA" /><!--角的半径--><corners android:radius="10dp"/><!--边框颜色--><stroke android:width="1dp" android:color="#00000000" />
</shape>public void setInsets(Rect insets) {FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();DeviceProfile grid = mActivity.getWallpaperDeviceProfile();insets = grid.getInsets();//竖屏布局if (grid.isVerticalBarLayout()) {lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;if (grid.isSeascape()) {lp.gravity = Gravity.LEFT;lp.width = grid.hotseatBarSizePx + insets.left;} else {lp.gravity = Gravity.RIGHT;lp.width = grid.hotseatBarSizePx + insets.right;}} else {//modify core start// 横屏布局// 平板开发项目 固定横屏,所以要在这里设置参数// 设置宽高  左边底部的间距InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;int hotseatNums = idp.numHotseatIcons;lp.width = hotseatNums*grid.hotseatBarSizePx+(hotseatNums+1)*dip2px(15.0f);lp.height = grid.hotseatBarSizePx + insets.bottom;if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){lp.leftMargin = (int)((1080-lp.width)/2);}else{lp.leftMargin = (int)((1920-lp.width)/2);}lp.gravity = Gravity.BOTTOM;//modify core end}Rect padding = grid.getHotseatLayoutPadding();// 设置padding 布局setPadding(0, padding.top, 0,0);setLayoutParams(lp);InsettableFrameLayout.dispatchInsets(this, insets);}

在实现Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心功能中,通过上述的分析得知,
在Hotseat中相关源码分析,
而setInset() 负责设置绘制布局 的参数 这里设置hotseat的宽高等参数布局
其实只需要修改lp的参数就行了 然后hotseat 会根据长宽等参数 来具体布局每一个hotseat的具体坐标
根据横竖屏来确定lp.leftMargin的值,就可以保证居中显示

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • pytorch 笔记:torch.optim(基类的基本操作)
  • 【Mode Management】ECU上下电过程CanSM为什么会多次设置CandTrcv和CanController模式
  • MySQL学习作业二
  • 计算机组成原理面试知识点总结1
  • git使用以及理解
  • CSPVD 智慧工地安全帽安全背心检测开发包
  • 代码随想录学习 day54 图论 Bellman_ford 队列优化算法(又名SPFA) 学习
  • WebKit 引擎:CSS 悬停效果的魔法师
  • “论系统安全架构设计及其应用”,写作框架,软考高级论文,系统架构设计师论文
  • Grafana :利用Explore方式实现多条件查询
  • python基础语法 007 文件操作-2文件支持模式文件的内置函数
  • 数据库基础与安装MYSQL数据库
  • 解决云服务器CPU占用率接近100%问题
  • 二叉树基础及实现(一)
  • Java 写一个可以持续发送消息的socket服务端
  • [NodeJS] 关于Buffer
  • CentOS从零开始部署Nodejs项目
  • es6
  • Java编程基础24——递归练习
  • Java多线程(4):使用线程池执行定时任务
  • Laravel 实践之路: 数据库迁移与数据填充
  • Netty 4.1 源代码学习:线程模型
  • Python语法速览与机器学习开发环境搭建
  • React Transition Group -- Transition 组件
  • Vim Clutch | 面向脚踏板编程……
  • Vue2 SSR 的优化之旅
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 基于web的全景—— Pannellum小试
  • 坑!为什么View.startAnimation不起作用?
  • 深入浏览器事件循环的本质
  • 网页视频流m3u8/ts视频下载
  • 微信小程序--------语音识别(前端自己也能玩)
  • 写代码的正确姿势
  • Linux权限管理(week1_day5)--技术流ken
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #systemverilog# 之 event region 和 timeslot 仿真调度(十)高层次视角看仿真调度事件的发生
  • $(function(){})与(function($){....})(jQuery)的区别
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (Oracle)SQL优化技巧(一):分页查询
  • (备忘)Java Map 遍历
  • (第61天)多租户架构(CDB/PDB)
  • (二)学习JVM —— 垃圾回收机制
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (分布式缓存)Redis持久化
  • (六)Flink 窗口计算
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (十二)Flink Table API
  • (学习日记)2024.02.29:UCOSIII第二节
  • ***检测工具之RKHunter AIDE
  • .Net Core 笔试1
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET应用架构设计:原则、模式与实践 目录预览