android10 launcher修改簡(jiǎn)單記錄

首先要對(duì)hotseat等位置有一定的了解。


https://blog.csdn.net/baidu_41672657/article/details/83383137

首先改橫屏是修改device/qcom/xxx/system.prop文件中的。
persist.panel.orientation=270,一開始是persist.panel.orientation=0。
這個(gè)數(shù)值可以通過(guò)adb直接修改,重啟后生效。

setprop persist.panel.orientation 270

關(guān)于adb調(diào)屏幕的命令還有

adb shell settings put system show_touches 1
adb shell settings put system pointer_location 1

是打開Show taps和Pointer location([顯示點(diǎn)按操作反饋]和[指針位置])。

修改點(diǎn)如下。
1.由于是豎屏橫用,所以需要修改hotseat 位置,讓其居于底部。修改hotseat_transpose_layout_with_orientation的值,由true改成false。

//packages/apps/Launcher3/res/values/config.xml
 <!-- Hotseat -->
-    <bool name="hotseat_transpose_layout_with_orientation">true</bool>
+    <bool name="hotseat_transpose_layout_with_orientation">false</bool>

2.需要強(qiáng)制所有app橫屏,在updateRotationUnchecked中增加返回true的部分,修改如下。

//frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
      *         UNFREEZE THE SCREEN.
      */
     boolean updateRotationUnchecked(boolean forceUpdate) {
+        if (true) {
+            return true;
+        }
+
         ScreenRotationAnimation screenRotationAnimation;
         if (!forceUpdate) {
             if (mDeferredRotationPauseCount > 0) {

3.需調(diào)整navigationbar位置。系統(tǒng)設(shè)置為橫屏顯示后,橫屏后 navigationBar默認(rèn)在左邊。需修改DisplayPolicy中的navigationBarPosition函數(shù),屏蔽判斷部分,使其直接返回NAV_BAR_BOTTOM。

//frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java

    @NavigationBarPosition
    int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) {
       /* if (navigationBarCanMove() && displayWidth > displayHeight) {
            if (displayRotation == Surface.ROTATION_270) {
                return NAV_BAR_LEFT;
            } else if (displayRotation == Surface.ROTATION_90) {
                return NAV_BAR_RIGHT;
            }
        }*/
        return NAV_BAR_BOTTOM;
    }

4.配置hotseat 位置居于底部后,allapp界面部分改變了,本身是4x4的布局,現(xiàn)在圖標(biāo)變小填充并且不再是4x4。需修改availableHeightPx 和availableWidthPx 部分。

//packages/apps/Launcher3/src/com/android/launcher3/DeviceProfile.java
    public DeviceProfile(Context context, InvariantDeviceProfile inv,
            Point minSize, Point maxSize,
            int width, int height, boolean isLandscape, boolean isMultiWindowMode) {

        this.inv = inv;
        this.isLandscape = isLandscape;
        this.isMultiWindowMode = isMultiWindowMode;

        // Determine sizes.
        widthPx = width;
        heightPx = height;
        if (isLandscape) {
/*            availableWidthPx = maxSize.x;
            availableHeightPx = minSize.y;*/
            availableWidthPx = minSize.x;
            availableHeightPx = maxSize.y;
        } else {
            availableWidthPx = minSize.x;
            availableHeightPx = maxSize.y;
        }

5.workspace區(qū)域添加的圖標(biāo)顯示不全。具體修改如下。

//packages/apps/Launcher3/src/com/android/launcher3/CellLayout.java
public class CellLayout extends ViewGroup implements Transposable {
         if (mFixedCellWidth < 0 || mFixedCellHeight < 0) {
             int cw = DeviceProfile.calculateCellWidth(childWidthSize, mCountX);
-            int ch = DeviceProfile.calculateCellHeight(childHeightSize, mCountY);
+            int ch = childHeightSize;//DeviceProfile.calculateCellHeight(childHeightSize, mCountY);
             if (cw != mCellWidth || ch != mCellHeight) {
                 mCellWidth = cw;
                 mCellHeight = ch;


6.去掉all apps 界面搜索應(yīng)用欄,需修改AllAppsContainerViewAllAppsTransitionController。
AllAppsContainerView 中增加mSearchContainer.setVisibility(View.GONE);
AllAppsTransitionController中注釋掉mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);

//packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java

public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
         mSearchContainer = findViewById(R.id.search_container_all_apps);
         mSearchUiManager = (SearchUiManager) mSearchContainer;
         mSearchUiManager.initialize(this);
+
+        mSearchContainer.setVisibility(View.GONE);
+
     }

//packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsTransitionController.java
public class AllAppsTransitionController implements StateHandler, OnDeviceProfil
         setter.setViewAlpha(mAppsView.getScrollBar(), hasContent ? 1 : 0, allAppsFade);
         mAppsView.getFloatingHeaderView().setContentVisibility(hasHeaderExtra, hasContent, setter,
                 allAppsFade);
-        mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);
+        //mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);

7.去掉Google 搜索。注釋掉bindAndInitFirstWorkspaceScreenqsb部分。

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

    public void bindAndInitFirstWorkspaceScreen(View qsb) {
        if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
            return;
        }
        // Add the first page
        CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, 0);
        // Always add a QSB on the first screen.
/*        if (qsb == null) {
            // In transposed layout, we add the QSB in the Grid. As workspace does not touch the
            // edges, we do not need a full width QSB.
            qsb = LayoutInflater.from(getContext())
                    .inflate(R.layout.search_container_workspace,firstPage, false);
        }

        CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, firstPage.getCountX(), 1);
        lp.canReorder = false;
        if (!firstPage.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true)) {
            Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout");
        }*/
    }

8.國(guó)內(nèi)基本上都是去掉Android原生的抽屜式的,修改部分基本參考這個(gè)。太長(zhǎng)了就不寫了。
android10.0(Q) Launcher3 去掉抽屜

9.修改hotseat。hotseat一般默認(rèn)是4個(gè),布局為4x1。
現(xiàn)需增加為8個(gè),布局改成4x2。

①首先修改device_profiles.xml,這個(gè)文件存在于go\res\xml和res\xml文件夾??梢远几囊幌?,因?yàn)閱为?dú)編譯launcher模塊和全編的話使用的是 不同的device_profiles.xml。

// device_profiles.xml
<profiles xmlns:launcher="http://schemas.android.com/apk/res-auto" >

    <grid-option
        launcher:name="4_by_4"
        launcher:numRows="4"
        launcher:numColumns="4"
        launcher:numFolderRows="4"
        launcher:numFolderColumns="4"
        launcher:numHotseatIcons="4"
        launcher:defaultLayoutId="@xml/default_workspace_4x4" >

        <display-option
            launcher:name="Go Device"
            launcher:minWidthDps="296"
            launcher:minHeightDps="491.33"
            launcher:iconImageSize="60"
            launcher:iconTextSize="14.0"
            launcher:canBeDefault="true" />

    </grid-option>

</profiles>

launcher:numHotseatIcons="4"改成launcher:numHotseatIcons="8"

②然后修改default_workspace_4x4.xml文件。增加resolve數(shù)據(jù)。Hotseat的launcher:screen與workspace中不同,并不代表屏幕位置,而是代表插入的位置。
修改后如下所示。

<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) -->
    <!-- Dialer, Messaging, Browser, Camera -->
    <resolve
        launcher:container="-101"
        launcher:screen="0"
        launcher:x="0"
        launcher:y="0" >
        <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
        <favorite launcher:uri="tel:123" />
        <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;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.APP_MESSAGING;end" />
        <favorite launcher:uri="sms:" />
        <favorite launcher:uri="smsto:" />
        <favorite launcher:uri="mms:" />
        <favorite launcher:uri="mmsto:" />
    </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.APP_BROWSER;end" />
        <favorite launcher:uri="http://www.example.com/" />
    </resolve>
       <resolve
           launcher:container="-101"
           launcher:screen="3"
           launcher:x="3"
           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
        launcher:container="-101"
        launcher:screen="0"
        launcher:x="0"
        launcher:y="1" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_CONTACTS;end" />
    </resolve>
    <resolve
        launcher:container="-101"
        launcher:screen="1"
        launcher:x="1"
        launcher:y="1" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_DeskClock;end" />
    </resolve>
    <resolve
        launcher:container="-101"
        launcher:screen="2"
        launcher:x="2"
        launcher:y="1" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" />
    </resolve>
    <resolve
        launcher:container="-101"
        launcher:screen="3"
        launcher:x="3"
        launcher:y="1" >
        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_CALENDAR;end" />
    </resolve>
    <!-- Bottom row -->
<!--    <resolve-->
<!--        launcher:screen="0"-->
<!--        launcher:x="0"-->
<!--        launcher:y="-1" >-->
<!--        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />-->
<!--        <favorite launcher:uri="mailto:" />-->
<!--    </resolve>-->

<!--    <resolve-->
<!--        launcher:screen="0"-->
<!--        launcher:x="1"-->
<!--        launcher:y="-1" >-->
<!--        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />-->
<!--        <favorite launcher:uri="#Intent;type=images/*;end" />-->
<!--    </resolve>-->

<!--    <resolve-->
<!--        launcher:screen="0"-->
<!--        launcher:x="3"-->
<!--        launcher:y="-1" >-->
<!--        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />-->
<!--        <favorite launcher:uri="market://details?id=com.android.launcher" />-->
<!--    </resolve>-->

</favorites>

并且要注意,缺少category的要在對(duì)應(yīng)的apk中添加。例如我的DeskClock,AndroidManifest.xml缺少
<category android:name="android.intent.category.APP_DeskClock"/>,要加進(jìn)去。

③屏蔽檢驗(yàn)部分代碼。
LoaderCursor中的checkItemPlacement會(huì)判斷hotseat的一行是否填充,如果填充了就不能再進(jìn)行填充了。這里會(huì)影響數(shù)據(jù)庫(kù)的數(shù)據(jù)生成,因此要屏蔽部分代碼。將hotseatOccupancy內(nèi)的代碼屏蔽。

//packages/apps/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) {
..........
            if (hotseatOccupancy != null) {
               /* if (hotseatOccupancy.cells[(int) item.screenId][0]) {
                    Log.e(TAG, "Error loading shortcut into hotseat " + item
                            + " into position (" + item.screenId + ":" + item.cellX + ","
                            + item.cellY + ") already occupied");
                    return false;
                } else {
                    hotseatOccupancy.cells[item.screenId][0] = true;
                    return true;
                }*/
            } 
..........
}


}

還有就是如果單獨(dú)編譯launcher的情況下,如果修改default_workspace_4x4文件中hotseat的個(gè)數(shù)的話,重新編譯后,要?jiǎng)h除設(shè)備上launcher的數(shù)據(jù)庫(kù),否則重新安裝的時(shí)候數(shù)據(jù)庫(kù)不會(huì)更新。
打開Android studio中的Device File Explorer,找到launcher.db這個(gè)文件。
路徑是/data/user/0/com.android.launcher3/databases/launcher.db

可通過(guò)cmd控制臺(tái),刪除launcher.db。另外,部分時(shí)候也需要查看launcher.db這個(gè)數(shù)據(jù)庫(kù)??赏ㄟ^(guò)sqlitestudio打開.db文件。
通過(guò)查看.db文件,hotseat數(shù)據(jù)為8個(gè),接下來(lái)的問(wèn)題就是修改其顯示。

image.png

④修改hotseat的高度。
首先要修改GridOccupancy 的行數(shù)。
將checkItemPlacement中的final GridOccupancy occupancy = new GridOccupancy(mIDP.numHotseatIcons, 1);
修改為final GridOccupancy occupancy = new GridOccupancy(mIDP.numHotseatIcons/2, 2);

//packages/apps/Launcher3/src/com/android/launcher3/model/LoaderCursor.java
    protected boolean checkItemPlacement(ItemInfo item) {
..........
            if (hotseatOccupancy != null) {
               /* if (hotseatOccupancy.cells[(int) item.screenId][0]) {
                    Log.e(TAG, "Error loading shortcut into hotseat " + item
                            + " into position (" + item.screenId + ":" + item.cellX + ","
                            + item.cellY + ") already occupied");
                    return false;
                } else {
                    hotseatOccupancy.cells[item.screenId][0] = true;
                    return true;
                }*/
            } else {
                final GridOccupancy occupancy = new GridOccupancy(mIDP.numHotseatIcons/2, 2);
..........

            }
..........

}

setGridSize(idp.numHotseatIcons, 1);修改為 setGridSize(idp.numHotseatIcons/2, 2);
修改后如下。

// packages/apps/Launcher3/src/com/android/launcher3/Hotseat.java
    public void resetLayout(boolean hasVerticalHotseat) {
        removeAllViewsInLayout();
        mHasVerticalHotseat = hasVerticalHotseat;
        InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;
        if (hasVerticalHotseat) {
            setGridSize(1, idp.numHotseatIcons);
        } else {
            setGridSize(idp.numHotseatIcons/2, 2);
        }
    }

這樣就占了2層。
然后修改hotseat高度。
由于是橫條,所以需要將DeviceProfile中的hotseatBarSizePx = ResourceUtils.pxFromDp(inv.iconSize, dm) + (isVerticalBarLayout()修改為hotseatBarSizePx = ResourceUtils.pxFromDp(inv.iconSize *2, dm) + (isVerticalBarLayout()
因?yàn)閟etInsets中有一句lp.height = grid.hotseatBarSizePx + insets.bottom;,也就是說(shuō)Hotseat的height 取決于hotseatBarSizePx 。

// packages/apps/Launcher3/src/com/android/launcher3/Hotseat.java
    @Override
    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.MATCH_PARENT;
            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);
    }

⑤在addInScreen之前屏蔽掉x和y對(duì)于hotseat的特殊計(jì)算,這里計(jì)算會(huì)導(dǎo)致hotaset里的圖標(biāo)的y坐標(biāo)永遠(yuǎn)為0,導(dǎo)致只能顯示一行。

    int getCellYFromOrder(int rank) {
        return mHasVerticalHotseat ? (getCountY() - (rank + 1)) : 0;
    }

mHasVerticalHotseat是表示hotseat是否為豎條,由于我這里是橫條所以一直會(huì)返回0.從getCellXFromOrder也可以看出hotseat未修改的源碼的x是根據(jù)rank,這里是screenId去賦值的。

    int getCellXFromOrder(int rank) {
        return mHasVerticalHotseat ? 0 : rank;
    }

這里要屏蔽掉對(duì)x和y的特殊計(jì)算,讓其根據(jù)default_workspace_4x4.xml中的 launcher:xlauncher:y的值去對(duì)快捷圖標(biāo)的x和y進(jìn)行賦值,而不是根據(jù)launcher:screen。
修改后如下。

//packages/apps/Launcher3/src/com/android/launcher3/WorkspaceLayoutManager.java
    default void addInScreenFromBind(View child, ItemInfo info) {
        int x = info.cellX;
        int y = info.cellY;
        /*if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
            int screenId = info.screenId;
            x = getHotseat().getCellXFromOrder(screenId);
            y = getHotseat().getCellYFromOrder(screenId);
        }*/
        addInScreen(child, info.container, info.screenId, x, y, info.spanX, info.spanY);
    }

參考鏈接:

Android10.0 MTK 平板橫屏方案修改(強(qiáng)制app橫屏 + 開機(jī)logo/動(dòng)畫+關(guān)機(jī)充電橫屏 + RecoveryUI 橫屏)

android10.0(Q) Launcher3 去掉抽屜

Android10.0 MTK 平臺(tái) Launcher3 修改定制

Android 8.1 MTK平臺(tái) 強(qiáng)制第三方 APP 橫屏(微信、今日頭條等)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容