联系管理员

开通文章发布权限

扫码 添加微信
微信图片
电话: QQ:1602036736

RK3566 Android13 首页UI布局优化

硬件平台

RK3566
Android13
Kernel5.10

实现参考

  1. 安卓开发- 安卓13 Launcher3 主页布局修改-CSDN博客

  2. 【安卓13】谷歌原生桌面launcher3源码修改,修改桌面布局(首屏应用、小部件、导航栏、大屏设备任务栏) - 小李不背锅 - 博客园

  3. Android 13 Hotseat定制化修改——001 hotseat布局方向​ 一.背景 由于需求是 - 掘金

  4. Launcher添加hotseat图标布局_android11.0 launcher3 高端定制之 hotseat 增加 allapp 图标-CSDN博客

  5. 安卓开发- 安卓13 Launcher3 Hotseat、导航栏相关修改-CSDN博客

  6. Android13 Launcher3修改Workspace布局(layout) - 技术栈

UI效果

优化前
图片#B #S #R #60% #auto

优化后
图片#B #S #R #60% #auto

移植补丁

packages_apps_Launcher3.patch

diff --git a/res/xml/default_workspace_6x5.xml b/res/xml/default_workspace_6x5.xml
index b078cfd7f8..c1084ab422 100644
--- a/res/xml/default_workspace_6x5.xml
+++ b/res/xml/default_workspace_6x5.xml
@@ -18,16 +18,53 @@
 
     <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
     <!-- Mail Calendar Gallery Store Internet Camera -->
+    <!-- 录音机 -->
     <resolve
         launcher:container="-101"
         launcher:screen="0"
         launcher:x="0"
         launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
-        <favorite launcher:uri="mailto:" />
+		<favorite
+           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.soundrecorder/.SoundRecorder;end" />
     </resolve>
-
+    <!-- 相册 -->
     <resolve
+        launcher:container="-101"
+        launcher:screen="1"
+        launcher:x="1"
+        launcher:y="0" >
+		<favorite
+           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.gallery3d/.app.GalleryActivity;end" />
+    </resolve>
+	<!-- 相机 -->
+    <resolve
+        launcher:container="-101"
+        launcher:screen="2"
+        launcher:x="2"
+        launcher:y="0" >
+		<favorite
+           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.camera2/com.android.camera.CameraLauncher;end" />
+    </resolve>
+	<!-- 时钟 -->
+    <resolve
+        launcher:container="-101"
+        launcher:screen="4"
+        launcher:x="4"
+        launcher:y="0" >
+		<favorite
+           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.deskclock/.DeskClock;end" />
+    </resolve>
+    <!-- 音乐 -->
+    <resolve
+        launcher:container="-101"
+        launcher:screen="5"
+        launcher:x="5"
+        launcher:y="0" >
+		<favorite
+           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.music/.MusicBrowserActivity;end" />
+    </resolve>
+
+    <!-- <resolve
         launcher:container="-101"
         launcher:screen="1"
         launcher:x="1"
@@ -63,7 +100,7 @@
         <favorite launcher:uri="http://www.example.com/" />
     </resolve>
 
-    <!-- Resolve camera intent if GoogleCamera is not available e.g. on emulator -->
+
     <resolve
         launcher:container="-101"
         launcher:screen="5"
@@ -71,6 +108,6 @@
         launcher:y="0" >
         <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
         <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
-    </resolve>
+    </resolve> -->
 
 </favorites>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index c9a44a1be0..bf9a6c1d72 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -164,7 +164,7 @@
         launcher:name="6_by_5"
         launcher:numRows="5"
         launcher:numColumns="6"
-        launcher:numSearchContainerColumns="3"
+        launcher:numSearchContainerColumns="5"
         launcher:numFolderRows="3"
         launcher:numFolderColumns="3"
         launcher:numHotseatIcons="6"
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 86c9f1617e..71dce4eacb 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -1502,7 +1502,8 @@ public class DeviceProfile {
      * the hotseat is on the bottom row.
      */
     public boolean isVerticalBarLayout() {
-        return isLandscape && transposeLayoutWithOrientation;
+        //return isLandscape && transposeLayoutWithOrientation;
+        return false;
     }
 
     /**
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index ba492d57e2..5fe0f764db 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -607,6 +607,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
         }
 
         int cellHSpan = mLauncher.getDeviceProfile().inv.numSearchContainerColumns;
+        //liguoyi 251103
+        //格子数从0开始算,这里表示搜索框位置从X轴第0格子,y轴第0个格子算起,x轴占据5(cellHSpan)个格子,y轴占据1个格子
+        // CellLayoutLayoutParams lp = new CellLayoutLayoutParams(0, 0, cellHSpan, 1);
         CellLayoutLayoutParams lp = new CellLayoutLayoutParams(0, 0, cellHSpan, 1);
         lp.canReorder = false;
         if (!firstPage.addViewToCellLayout(
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index b7e6378047..9c880d2fc5 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -62,8 +62,11 @@ public final class FeatureFlags {
      * @deprecated Use {@link BuildConfig#QSB_ON_FIRST_SCREEN} directly
      */
     @Deprecated
+    //251103
+    //显示导航栏
     public static final boolean QSB_ON_FIRST_SCREEN = BuildConfig.QSB_ON_FIRST_SCREEN;
-
+//      取消导航栏
+//    public static final boolean QSB_ON_FIRST_SCREEN = false;
     /**
      * Feature flag to handle define config changes dynamically instead of killing the process.
      *

device_rockchip_rk356x.patch

diff --git a/rk3566_t/rk3566_t.mk b/rk3566_t/rk3566_t.mk
index dc88e76..cec4814 100644
--- a/rk3566_t/rk3566_t.mk
+++ b/rk3566_t/rk3566_t.mk
@@ -39,8 +39,10 @@ PRODUCT_AAPT_PREF_CONFIG := xhdpi
 #
 ## add Rockchip properties
 #
-PRODUCT_PROPERTY_OVERRIDES += ro.sf.lcd_density=320
+PRODUCT_PROPERTY_OVERRIDES += ro.sf.lcd_density=289
 PRODUCT_PROPERTY_OVERRIDES += ro.wifi.sleep.power.down=true
 PRODUCT_PROPERTY_OVERRIDES += persist.wifi.sleep.delay.ms=0
 PRODUCT_PROPERTY_OVERRIDES += persist.bt.power.down=true
 PRODUCT_PROPERTY_OVERRIDES += ro.vendor.hdmirotationlock=true

参数说明

Hotseat
Hotseat的设计目的是为了方便用户快速访问这些高频应用,而无需返回到主屏幕或通过应用抽屉查找。通常在底部显示。在常规的手机桌面中,通常是 电话、联系人、浏览器、相机。

android13-sdk/packages/apps/Launcher3/res/xml/device_profiles.xml 中配置Hotseat相关的属性:

首先观察device_profiles.xml代码,一般大屏(平板)设备会加载6*5的布局,手机设备会加载手机的布局,该文件里定义了4个不同的布局类型,如何确定设备加载哪个布局呢?你可以在桌面长按应用图标,然后观察可以移动多少个格子,然后根据行列数找到要修改的布局位置。比如我设备是加载6 * 5布局
<!--Launcher3/res/xml/device_profiles.xml-->
<?xml version="1.0" encoding="utf-8"?>
<profiles xmlns:launcher="http://schemas.android.com/apk/res-auto" >
    <其他的grid-option布局...>
        
    <grid-option
        launcher:name="6_by_5"
        launcher:numRows="6"
        launcher:numColumns="7"
        launcher:numSearchContainerColumns="5"
        launcher:numFolderRows="3"
        launcher:numFolderColumns="4"
        launcher:numHotseatIcons="5"
        launcher:hotseatColumnSpanLandscape="4"
        launcher:numAllAppsColumns="6"
        launcher:isScalable="true"
        launcher:inlineNavButtonsEndSpacing="@dimen/taskbar_button_margin_6_5"
        launcher:devicePaddingId="@xml/paddings_6x5"
        launcher:dbFile="launcher_6_by_5.db"
        launcher:defaultLayoutId="@xml/default_workspace_6x5"
        launcher:deviceCategory="tablet" >
        <display-option
            launcher:name="Tablet"
            launcher:minWidthDps="900"
            launcher:minHeightDps="820"
            launcher:minCellHeight="120"
            launcher:minCellWidth="102"
            launcher:minCellHeightLandscape="104"
            launcher:minCellWidthLandscape="120"
            launcher:iconImageSize="60"
            launcher:iconTextSize="14"
            launcher:borderSpaceHorizontal="16"
            launcher:borderSpaceVertical="64"
            launcher:borderSpaceLandscapeHorizontal="64"
            launcher:borderSpaceLandscapeVertical="16"
            launcher:horizontalMargin="54"
            launcher:horizontalMarginLandscape="120"
            launcher:allAppsCellWidth="96"
            launcher:allAppsCellHeight="142"
            launcher:allAppsCellWidthLandscape="126"
            launcher:allAppsCellHeightLandscape="126"
            launcher:allAppsIconSize="60"
            launcher:allAppsIconTextSize="14"
            launcher:allAppsBorderSpaceHorizontal="8"
            launcher:allAppsBorderSpaceVertical="16"
            launcher:allAppsBorderSpaceLandscape="16"
            launcher:hotseatBarBottomSpace="76"
            launcher:hotseatBarBottomSpaceLandscape="40"
            launcher:canBeDefault="true" />
    </grid-option>
</profiles>

这里涉及到 Hotseat 设置地方就下面几个:

launcher:numHotseatIcons="5"

设置显示hotseat的应用数量

launcher:hotseatColumnSpanLandscape="4"

在横屏模式下,hotseat占用的列数(竖屏模式下,默认占满,即与桌面上应用的列数一致)

launcher:hotseatBarBottomSpace="76"

竖屏模式下的底部间距

launcher:hotseatBarBottomSpaceLandscape="40"

横屏模式下的底部间距

如何添加相应的Hotseat组件?

组件配置通常位于 android13-sdk/packages/apps/Launcher3/res/xml/ 下的 default_workspace_MxN.xml
其中 M 表示行 N 表示列:一行可以放下 M 个图标,一列可以放下 N 个图标。

例如我测试发现我用的是 default_workspace_6x5.xml ,里面的一个 resolve 节点就对应一个图标。

例如录音机图标:

    <resolve
        launcher:container="-101"
        launcher:screen="0"
        launcher:x="0"
        launcher:y="0" >
		<favorite
           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.soundrecorder/.SoundRecorder;end" />
    </resolve>

launcher:container="-101" 代表唯一hotseat位置。
launcher:screen="0" 表示第一格,下一个图标递增。
launcher:x="0" 表示x坐标,其他的图标递增。
launcher:y="0" 表示y坐标,后续的y坐标也是0。
<favorite
launcher:uri= 后面填应用的intent信息,数据库里面复制出来就可以了

这里又有一个问题,其他应用的 launcher:uri= 参数怎么设置?

点击展开更多
  1. 首先打开机器将要布局的图标手动移动到 hotseat 位置上面。

  2. 然后使用 adb 命令将 data/data/com.android.launcher3/databases 这个文件 pull 出来。这个文件夹是 Luancher 的数据库文件。里面保存了相关应用的图标信息。

  3. 使用 SQLiteStudio 工具打开 pull 出来的 db 文件。打开 Tables 下的表格就可以看到图标信息了。

图片#B #S #R #60% #auto

一个完整的

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">

    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
    <!-- Mail Calendar Gallery Store Internet Camera -->
    <!-- 录音机 -->
    <resolve
        launcher:container="-101"
        launcher:screen="0"
        launcher:x="0"
        launcher:y="0" >
		<favorite
           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.soundrecorder/.SoundRecorder;end" />
    </resolve>
    <!-- 相册 -->
    <resolve
        launcher:container="-101"
        launcher:screen="1"
        launcher:x="1"
        launcher:y="0" >
		<favorite
           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.gallery3d/.app.GalleryActivity;end" />
    </resolve>
	<!-- 相机 -->
    <resolve
        launcher:container="-101"
        launcher:screen="2"
        launcher:x="2"
        launcher:y="0" >
		<favorite
           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.camera2/com.android.camera.CameraLauncher;end" />
    </resolve>
	<!-- 时钟 -->
    <resolve
        launcher:container="-101"
        launcher:screen="4"
        launcher:x="4"
        launcher:y="0" >
		<favorite
           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.deskclock/.DeskClock;end" />
    </resolve>
    <!-- 音乐 -->
    <resolve
        launcher:container="-101"
        launcher:screen="5"
        launcher:x="5"
        launcher:y="0" >
		<favorite
           launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.android.music/.MusicBrowserActivity;end" />
    </resolve>

</favorites>

如果你发现设置后显示不全,那你要确保 device_profiles.xml 的 launcher:numHotseatIcons="X",这个 X 要设置成为你要显示的hotseat个数。

hotseat布局方向修改

参考:Android 13 Hotseat定制化修改——001 hotseat布局方向​ 一.背景 由于需求是 - 掘金

直接修改 DeviceProfile 类中的 isVerticalBarLayout 方法让其全局修改成横屏(false)或者竖屏(true),如下是修改成横屏方式。

横屏(false)则 hotseat 是显示在屏幕下方
竖屏(true)则hotseat 是显示在屏幕侧方

packages_apps_Launcher3.patch

diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 86c9f1617e..71dce4eacb 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -1502,7 +1502,8 @@ public class DeviceProfile {
      * the hotseat is on the bottom row.
      */
     public boolean isVerticalBarLayout() {
-        return isLandscape && transposeLayoutWithOrientation;
+        //return isLandscape && transposeLayoutWithOrientation;
+        return false;
     }
 
     /**

取消谷歌搜索栏

如果要取消搜索栏则直接在 FeatureFlags.java 中的 FeatureFlags 类里设置 QSB_ON_FIRST_SCREEN 为 false。

 

packages_apps_Launcher3.patch

diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index b7e6378047..9c880d2fc5 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -62,8 +62,11 @@ public final class FeatureFlags {
      * @deprecated Use {@link BuildConfig#QSB_ON_FIRST_SCREEN} directly
      */
     @Deprecated
+    //251103
+    //显示导航栏
     public static final boolean QSB_ON_FIRST_SCREEN = BuildConfig.QSB_ON_FIRST_SCREEN;
-
+//      取消导航栏
+//    public static final boolean QSB_ON_FIRST_SCREEN = false;
     /**
      * Feature flag to handle define config changes dynamically instead of killing the process.
      *

谷歌搜索栏位置/大小设置

  1. 修改 Launcher3\res\xml\device_profiles.xml 这里 launcher:numSearchContainerColumns="5" 修改谷歌搜索框占据5个格子(横屏总共7个格子

<--这个行数可以根据自己想要的效果修改,比如我就改了7*6布局,67--/>	
	<grid-option
        launcher:name="6_by_5"
        launcher:numRows="6" 
        launcher:numColumns="7"
        launcher:numSearchContainerColumns="5"
        launcher:numFolderRows="3"
        launcher:numFolderColumns="4"
        launcher:numHotseatIcons="0"
        launcher:hotseatColumnSpanLandscape="2"
        launcher:numAllAppsColumns="6"
        launcher:isScalable="true"
        launcher:inlineNavButtonsEndSpacing="@dimen/taskbar_button_margin_6_5"
        launcher:devicePaddingId="@xml/paddings_6x5"
        launcher:dbFile="launcher_6_by_5.db"
        launcher:defaultLayoutId="@xml/default_workspace_6x5"
        launcher:deviceCategory="tablet" >
  1. 谷歌搜索框的位置在workspace.java里面修改,在该类里面查找这个方法:bindAndInitFirstWorkspaceScreen,定位到这里

public void bindAndInitFirstWorkspaceScreen() {
        if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
            return;
        }

        // Add the first page
        CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, getChildCount());
        // Always add a first page pinned widget on the first screen.
        if (mFirstPagePinnedItem == null) {
            // In transposed layout, we add the first page pinned widget in the Grid.
            // As workspace does not touch the edges, we do not need a full
            // width first page pinned widget.
            mFirstPagePinnedItem = LayoutInflater.from(getContext())
                    .inflate(R.layout.search_container_workspace, firstPage, false);
        }

        int cellHSpan = mLauncher.getDeviceProfile().inv.numSearchContainerColumns;
        //格子数从0开始算,这里表示搜索框位置从X轴第2格子,y轴第3个格子算起,x轴占据5(cellHSpan)个格子,y轴占据1个格子
        CellLayoutLayoutParams lp = new CellLayoutLayoutParams(1, 2, cellHSpan, 1);
        lp.canReorder = false;
        if (!firstPage.addViewToCellLayout(
                mFirstPagePinnedItem, 0, R.id.search_container_workspace, lp, true)) {
            Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout");
            mFirstPagePinnedItem = null;
        }
    }
  1. 还要在LoaderCursor.java的checkItemPlacement()方法中修改搜索框对位置的占用效果:

// Launcher3/src/com/android/launcher3/model/LoaderCursor.java
/**
 * check & update map of what's occupied; used to discard overlapping/invalid items
 */
protected boolean checkItemPlacement(ItemInfo item) {
    int containerIndex = item.screenId;
	// ...

    if (!occupied.containsKey(item.screenId)) {
        GridOccupancy screen = new GridOccupancy(countX + 1, countY + 1);
        if (item.screenId == Workspace.FIRST_SCREEN_ID && FeatureFlags.QSB_ON_FIRST_SCREEN) {
            int spanX = mIDP.numSearchContainerColumns;
            int spanY = 1;
            // 这里需要跟WorkSpace.java中设置的搜索框位置保持一致
            screen.markCells(1, 2, spanX, spanY, true);
        }
        occupied.put(item.screenId, screen);
    }
    final GridOccupancy occupancy = occupied.get(item.screenId);

    // Check if any workspace icons overlap with each other
    if (occupancy.isRegionVacant(item.cellX, item.cellY, item.spanX, item.spanY)) {
        occupancy.markCells(item, true);
        return true;
    } else {
        Log.e(TAG, "Error loading shortcut " + item
                + " into cell (" + containerIndex + "-" + item.screenId + ":"
                + item.cellX + "," + item.cellX + "," + item.spanX + "," + item.spanY
                + ") already occupied");
        return false;
    }
}

如果只修改WorkSpace、而没有修改LoaderCursor中的代码,那么搜索框原本的布局(默认位置是x=0,y=0)占用效果会一直存在,导致后面一些应用或者组件无法放置在首页的首行位置。

 

评论

快捷导航

把好文章收藏到微信

打开微信,扫码查看

关闭

还没有账号?立即注册