Android 14.0 Launcher3 app图标和hotseat 添加背景(焦点选中背景)

时间:2024-10-12 13:46:01

1.概述

在14.0的系统产品rom定制化开发中,进行Tv设备定制化开发中,配置的有遥控器需要使用遥控器来移动来控制点击功能,所以需要给app 的Icon 和hotseat
添加背景来显示选中状态原生的Launcher的背景没有支持遥控器的焦点事件,所以就需要在Launcher3中给Item 添加默认背景直接焦点样式背景,
接下来就来实现相关功能

2.Launcher3 app图标和hotseat 添加背景(焦点选中背景)的核心类

/packages/apps/Launcher3/src/com/android/launcher3/ShortcutAndWidgetContainer.java

3.Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能分析和实现

功能实现分析:
Launcher顾名思义,就是桌面的意思,也是android系统启动后第一个启动的应用程序,
:Launcher3负责管理和展示用户手机桌面上的各个应用程序图标。它通过GridView或者LinearLayout等布局管理器
图标进行排列,并支持滑动、放大缩小等手势操作
在原生Launcher3中主页面的布局是由Workspace 构造的 每一个页面由一个CellLayout组成,CellLayout还不是真正容纳图标的ViewGroup,每个CellLayout会包含一个ShortcutAndWidgetContainer,这才是真正容纳图标和Widget的ViewGroup。
接下来具体看ShortcutAndWidgetContainer.java 的源码分析问题

3.1 ShortcutAndWidgetContainer.java 的源码关于源码背景分析问题

在实现Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能中,通过上述的分析得知,在ShortcutAndWidgetContainer.java中的上述源码中,这里就是具体定义每个app图标和hotseat等相关控制的核心类,接下来看下相关核心代码

  1. public class ShortcutAndWidgetContainer extends ViewGroup {
  2. static final String TAG = "ShortcutAndWidgetContainer";
  3. ....
  4. public ShortcutAndWidgetContainer(Context context, @ContainerType int containerType) {
  5. super(context);
  6. mActivity = ActivityContext.lookupContext(context);
  7. mWallpaperManager = WallpaperManager.getInstance(context);
  8. mContainerType = containerType;
  9. }
  10. public void setCellDimensions(int cellWidth, int cellHeight, int countX, int countY) {
  11. mCellWidth = cellWidth;
  12. mCellHeight = cellHeight;
  13. mCountX = countX;
  14. }
  15. public View getChildAt(int x, int y) {
  16. final int count = getChildCount();
  17. for (int i = 0; i < count; i++) {
  18. View child = getChildAt(i);
  19. CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
  20. if ((lp.cellX <= x) && (x < lp.cellX + lp.cellHSpan) &&
  21. (lp.cellY <= y) && (y < lp.cellY + lp.cellVSpan)) {
  22. return child;
  23. }
  24. }
  25. return null;
  26. }
  27. @Override
  28. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  29. int count = getChildCount();
  30. int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
  31. int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
  32. setMeasuredDimension(widthSpecSize, heightSpecSize);
  33. for (int i = 0; i < count; i++) {
  34. View child = getChildAt(i);
  35. if (child.getVisibility() != GONE) {
  36. measureChild(child);
  37. }
  38. }
  39. }
  40. public void setupLp(View child) {
  41. CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
  42. if (child instanceof LauncherAppWidgetHostView) {
  43. DeviceProfile profile = mActivity.getWallpaperDeviceProfile();
  44. lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX,
  45. profile.appWidgetScale.x, profile.appWidgetScale.y);
  46. } else {
  47. lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX);
  48. }
  49. }
  50. @Override
  51. protected void onLayout(boolean changed, int l, int t, int r, int b) {
  52. int count = getChildCount();
  53. for (int i = 0; i < count; i++) {
  54. final View child = getChildAt(i);
  55. if (child.getVisibility() != GONE) {
  56. CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
  57. layoutChild(child);
  58. }
  59. }
  60. }
  61. @Override
  62. public boolean onInterceptTouchEvent(MotionEvent ev) {
  63. if (ev.getAction() == ACTION_DOWN && getAlpha() == 0) {
  64. // Dont let children handle touch, if we are not visible.
  65. return true;
  66. }
  67. return super.onInterceptTouchEvent(ev);
  68. }
  69. ....
  70. }

在实现Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能中,通过上述的分析得知,
在ShortcutAndWidgetContainer.java中的上述源码中,是继承自View的自定义布局,所以可以
从源码中可以看出 onMeasure(int widthMeasureSpec, int heightMeasureSpec) 和onLayout(boolean changed, int l, int t, int r, int b) 负责绘制子Item的
所以要想给app 和 hotseat 添加背景 就得在这里添加就好了
所以修改如下:
在measureChild(View child) 中添加背景
编译launcher3 发现功能已经实现了

  1. public void measureChild(View child) {
  2. CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
  3. final DeviceProfile profile = mActivity.getWallpaperDeviceProfile();
  4. if (child instanceof LauncherAppWidgetHostView) {
  5. lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX,
  6. profile.appWidgetScale.x, profile.appWidgetScale.y);
  7. // Widgets have their own padding
  8. } else {
  9. lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX);
  10. // Center the icon/folder
  11. int cHeight = getCellContentHeight();
  12. int cellPaddingY = (int) Math.max(0, ((lp.height - cHeight) / 2f));
  13. int cellPaddingX = mContainerType == CellLayout.WORKSPACE
  14. ? profile.workspaceCellPaddingXPx
  15. : (int) (profile.edgeMarginPx / 2f);
  16. child.setPadding(cellPaddingX, cellPaddingY, cellPaddingX, 0);
  17. }
  18. int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
  19. int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
  20. child.measure(childWidthMeasureSpec, childheightMeasureSpec);
  21. // 添加背景颜色
  22. child.setBackgroundResource(R.drawable.shape_button);
  23. }

在实现Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能中,通过上述的分析得知,在ShortcutAndWidgetContainer.java中的上述源码中,在实现功能中,需要
添加新的背景布局具体如下
shape_button.xml 为:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android" >
  3. <item android:state_pressed="true">
  4. <shape>
  5. <solid android:color="#CFCFCF"/>
  6. </shape>
  7. </item>
  8. <item android:state_focused="true">
  9. <shape>
  10. <solid android:color="#CFCFCF"/>
  11. </shape>
  12. </item>
  13. <item android:state_selected="true">
  14. <shape>
  15. <solid android:color="#E8E8E8"/>
  16. </shape>
  17. </item>
  18. <item android:state_selected="false">
  19. <shape>
  20. <solid android:color="#00000000"/>
  21. </shape>
  22. </item>
  23. <item android:state_pressed="false">
  24. <shape>
  25. <solid android:color="#00000000"/>
  26. </shape>
  27. </item>
  28. <item android:state_focused="false">
  29. <shape>
  30. <solid android:color="#00000000"/>
  31. </shape>
  32. </item>
  33. </selector>

在实现Launcher3 app图标和hotseat 添加背景(焦点选中背景)核心功能中,通过上述的分析得知,
在ShortcutAndWidgetContainer.java中的上述源码中,通过上述在ShortcutAndWidgetContainer.java中的
measureChild(View child)中添加shape_button.xml背景就可以实现相关功能