IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android12.0(S) Launcher3 去掉抽屉 -> 正文阅读

[移动开发]android12.0(S) Launcher3 去掉抽屉

效果图

bSVnhQ.gif

修改思路

1、增加变量 launcher3.is_full_app,用来动态切换

2、增加两套布局,对应有抽屉和无抽屉

3、去除 allAppsButton

4、将 AllAppsContainerView 中的图标加载到 Workspace

5、新安装的 app 自动添加图标到 Workspace

6、替换 Workspace 图标长按删除选项为取消

7、屏蔽上拉显示抽屉页面手势

8、修改页面指示线为圆点

	modified:   packages/apps/Launcher3/Android.mk
	modified:   packages/apps/Launcher3/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
	modified:   packages/apps/Launcher3/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
	modified:   packages/apps/Launcher3/res/layout/launcher.xml
	modified:   packages/apps/Launcher3/res/values/dimens.xml
	modified:   packages/apps/Launcher3/res/xml/device_profiles.xml
	modified:   packages/apps/Launcher3/src/com/android/launcher3/DeleteDropTarget.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/Hotseat.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/InvariantDeviceProfile.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/LauncherAppState.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/Workspace.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/dragndrop/DragController.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/model/BaseModelUpdateTask.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/model/ItemInstallQueue.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/model/LoaderTask.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/model/PackageUpdatedTask.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
	modified:   packages/apps/Launcher3/src/com/android/launcher3/settings/SettingsActivity.java

上代码

1、在 LauncherAppState 中增加静态方法 isDisableAllApps()

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


public static boolean isDisableAllApps() {
        return true;
    }

2、增加两套布局,对应有抽屉和无抽屉

加载布局文件对应的 xml 为 packages\apps\Launcher3\res\xml\device_profiles.xml

Launcher3 通过获取 minWidthDps 和 minHeightDps 来确定加载哪一个 profile,增加两个 profile 节点

  
+    <!-- cczheng add -->
+    <grid-option
+        launcher:name="4_by_4"
+        launcher:numRows="4"
+        launcher:numColumns="4"
+        launcher:numFolderRows="3"
+        launcher:numFolderColumns="4"
+        launcher:numHotseatIcons="4"
+        launcher:dbFile="launcher_4_by_4.db"
+        launcher:defaultLayoutId="@xml/default_workspace_4x4_no_all_app" >
+
+        <display-option
+            launcher:name="Short Stubby"
+            launcher:minWidthDps="260"
+            launcher:minHeightDps="410"
+            launcher:iconImageSize="48"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
+
+        <display-option
+            launcher:name="Stubby"
+            launcher:minWidthDps="255"
+            launcher:minHeightDps="450"
+            launcher:iconImageSize="48"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
+
+        <display-option
+            launcher:name="Nexus S"
+            launcher:minWidthDps="296"
+            launcher:minHeightDps="491.33"
+            launcher:iconImageSize="48"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
+
+        <display-option
+            launcher:name="Nexus 4"
+            launcher:minWidthDps="359"
+            launcher:minHeightDps="567"
+            launcher:iconImageSize="54"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
+
+        <display-option
+            launcher:name="Nexus 5"
+            launcher:minWidthDps="335"
+            launcher:minHeightDps="567"
+            launcher:iconImageSize="54"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
+    </grid-option>
+    <!-- end -->
+

对应的你需要在 xml 文件下增加 1 个文件, default_workspace_4x4_no_all_app.xml

这样的好处是你可以自定义不同的布局文件加载内容,上面的配置含义简单说一下,分别是最小宽度、最小高度、布局的行和列、文件夹中布局行和列、图标大小、图标文字大小、HotSeat 个数,加载的布局文件

在 InvariantDeviceProfile() 判断是否需要加载 Tablet_no_all_app profile

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

 
+import android.util.Log;
+
 public class InvariantDeviceProfile {
 
     public static final String TAG = "IDP";
@@ -494,26 +496,40 @@ public class InvariantDeviceProfile {
             }
         }
 
+        Log.d("Launcher3.profiles", "minWidthPx="+minWidthPx + "  minHeightPx="+minHeightPx);
         float width = dpiFromPx(minWidthPx, displayInfo.densityDpi);
         float height = dpiFromPx(minHeightPx, displayInfo.densityDpi);
+        Log.i("Launcher3.profiles", "width="+width + "  height="+height);
+        //cczheng add
+        if (LauncherAppState.isDisableAllApps()) {
+            Log.e("Launcher3.profiles", "load no all app profiles");
+            //对应 device_profiles.xml 中 Tablet_no_all_app 的值
+            width = 260.0f;
+            height = 410.0f;
+        }
+        final float widthFix = width;
+        final float heightFix = height;
+        //end
 
         // Sort the profiles based on the closeness to the device size
         Collections.sort(points, (a, b) ->
-                Float.compare(dist(width, height, a.minWidthDps, a.minHeightDps),
-                        dist(width, height, b.minWidthDps, b.minHeightDps)));
+                Float.compare(dist(widthFix, heightFix, /*width, height,*/ a.minWidthDps, a.minHeightDps),
+                        dist(widthFix, heightFix, /*width, height,*/ b.minWidthDps, b.minHeightDps)));
 
         GridOption closestOption = points.get(0).grid;
         float weights = 0;
 
         DisplayOption p = points.get(0);
-        if (dist(width, height, p.minWidthDps, p.minHeightDps) == 0) {
+        // if (dist(width, height, p.minWidthDps, p.minHeightDps) == 0) {
+        if (dist(widthFix, heightFix, p.minWidthDps, p.minHeightDps) == 0) {
             return p;
         }
 
         DisplayOption out = new DisplayOption(closestOption);
         for (int i = 0; i < points.size() && i < KNEARESTNEIGHBOR; ++i) {
             p = points.get(i);
-            float w = weight(width, height, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
+            // float w = weight(width, height, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
+            float w = weight(widthFix, heightFix, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
             weights += w;
             out.add(new DisplayOption().add(p).multiply(w));
         }

3、去除 allAppsButton

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

 
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+import static com.android.launcher3.LauncherState.ALL_APPS;
+
+
+
+
 /**
  * View class that represents the bottom row of the home screen.
  */
@@ -50,7 +59,9 @@ public class Hotseat extends CellLayout implements Insettable {
     private final int mQsbHeight;
 
     private final int mTaskbarViewHeight;
-
+       
+       private final Launcher mLauncher;
+       
     public Hotseat(Context context) {
         this(context, null);
     }
@@ -67,7 +78,9 @@ public class Hotseat extends CellLayout implements Insettable {
         addView(mQsb);
 
         mTaskbarViewHeight = context.getResources().getDimensionPixelSize(R.dimen.taskbar_size);
-    }
+
+        mLauncher = Launcher.getLauncher(context);
+       }
 
     /**
      * Returns orientation specific cell X given invariant order in the hotseat
@@ -92,7 +105,55 @@ public class Hotseat extends CellLayout implements Insettable {
         } else {
             setGridSize(dp.numShownHotseatIcons, 1);
         }
+        //cczheng add
+        if (!LauncherAppState.isDisableAllApps()) {
+            addAllAppButton(dp.numShownHotseatIcons);
+        }
+        //end
+    }
+
+    ///cczheng add
+    private void addAllAppButton(int numHotseatIcons){
+        // Add the Apps button
+        Context context = getContext();
+        DeviceProfile grid = mActivity.getDeviceProfile();
+        //int allAppsButtonRank = grid.inv.getAllAppsButtonRank();
+        int allAppsButtonRank = numHotseatIcons / 2;
+        android.util.Log.e("Launcher","addAllAppButton allAppsButtonRank="+allAppsButtonRank);
+
+        LayoutInflater inflater = LayoutInflater.from(context);
+        TextView allAppsButton = (TextView)
+                inflater.inflate(R.layout.all_apps_button, this, false);
+        Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon);
+        d.setBounds(0, 0, grid.iconSizePx, grid.iconSizePx);
+
+        int scaleDownPx = getResources().getDimensionPixelSize(R.dimen.all_apps_button_scale_down);
+        Rect bounds = d.getBounds();
+        d.setBounds(bounds.left, bounds.top + scaleDownPx / 2, bounds.right - scaleDownPx,
+                bounds.bottom - scaleDownPx / 2);
+        allAppsButton.setCompoundDrawables(null, d, null, null);
+
+        allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
+        if (mLauncher != null) {
+            allAppsButton.setOnClickListener((v) -> {
+                if (!mLauncher.isInState(ALL_APPS)) {
+                    //mLauncher.getUserEventDispatcher().logActionOnControl(Action.Touch.TAP,
+                    //        ControlType.ALL_APPS_BUTTON);
+                    mLauncher.getStateManager().goToState(ALL_APPS);
+                }
+            });
+            allAppsButton.setOnFocusChangeListener(mLauncher.mFocusHandler);
+        }
+
+        // Note: We do this to ensure that the hotseat is always laid out in the orientation of
+        // the hotseat in order regardless of which orientation they were added
+        int x = getCellXFromOrder(allAppsButtonRank);
+        int y = getCellYFromOrder(allAppsButtonRank);
+        CellLayout.LayoutParams lp = new CellLayout.LayoutParams(x, y, 1, 1);
+        lp.canReorder = false;
+        addViewToCellLayout(allAppsButton, -1, allAppsButton.getId(), lp, true);
     }
+    //end

4、将 AllAppsContainerView 中的图标加载到 Workspace

packages\apps\Launcher3\src\com\android\launcher3\model\LoaderTask.java

run() 中增加判断,添加 verifyApplications(), 修改 ItemInstallQueue 中 PendingInstallShortcutInfo 为 public

 
+import android.util.Pair;
 /**
  * Runnable for the thread that loads the contents of the launcher:
  *   - workspace icons
@@ -225,6 +226,14 @@ public class LoaderTask implements Runnable {
             List<LauncherActivityInfo> allActivityList = loadAllApps();
             logASplit(logger, "loadAllApps");
 
+            //cczheng add for load all app on workspace
+            if (LauncherAppState.isDisableAllApps()) {
+                android.util.Log.e("Launcher3", "verifyApplications()");
+                verifyApplications();
+            }
+            //end
+
+
             verifyNotStopped();
             mResults.bindAllApps();
             logASplit(logger, "bindAllApps");
@@ -304,6 +313,33 @@ public class LoaderTask implements Runnable {
         TraceHelper.INSTANCE.endSection(traceToken);
     }
 
+     //cczheng add for load all app on workspace
+    private void verifyApplications() {
+        final Context context = mApp.getContext();
+        ArrayList<Pair<ItemInfo, Object>> installQueue = new ArrayList<>();
+        final List<UserHandle> profiles = mUserManager.getUserProfiles();
+        for (UserHandle user : profiles) {
+            final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
+            android.util.Log.i("Launcher3", "apps.size "+apps.size());
+            ArrayList<ItemInstallQueue.PendingInstallShortcutInfo> added = new ArrayList<ItemInstallQueue.PendingInstallShortcutInfo>();
+            synchronized (this) {
+                for (LauncherActivityInfo app : apps) {
+                    ItemInstallQueue.PendingInstallShortcutInfo pendingInstallShortcutInfo
+                     = new ItemInstallQueue.PendingInstallShortcutInfo(app.getComponentName().getPackageName(), app.getUser());
+                    added.add(pendingInstallShortcutInfo);
+                    installQueue.add(pendingInstallShortcutInfo.getItemInfo(context));
+                    android.util.Log.d("Launcher3", "app pkg "+app.getComponentName().getPackageName());
+                }
+            }
+            if (!added.isEmpty()) {
+                android.util.Log.i("Launcher3", "installQueue.size "+installQueue.size());
+                mApp.getModel().addAndBindAddedWorkspaceItems(installQueue);
+            }
+        }
+    }
+    //end
+
+

@@ -230,7 +230,8 @@ public class ItemInstallQueue {
         MODEL_EXECUTOR.post(this::flushQueueInBackground);
     }
 
-    private static class PendingInstallShortcutInfo extends ItemInfo {
+    //cczheng change private to public
+    public static class PendingInstallShortcutInfo extends ItemInfo {
 
         final Intent intent;
 

这个很关键,系统 app 就不创建 icon 了,无抽屉下需要放开

packages\apps\Launcher3\src\com\android\launcher3\model\AddWorkspaceItemsTask.java


@@ -82,9 +82,12 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
                     }
 
                     // b/139663018 Short-circuit this logic if the icon is a system app
-                    if (PackageManagerHelper.isSystemApp(app.getContext(), item.getIntent())) {
-                        continue;
-                    }
+                    //cczheng add this for no drawer need show system app icon
+                    if (!LauncherAppState.isDisableAllApps()) {
+                        if (PackageManagerHelper.isSystemApp(app.getContext(), item.getIntent())) {
+                            continue;
+                        }
+                    }//end
                 }
 
                 if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {

packages\apps\Launcher3\src\com\android\launcher3\model\BaseModelUpdateTask.java

注释 run() 中的 return

@@ -67,7 +67,8 @@ public abstract class BaseModelUpdateTask implements ModelUpdateTask {
                 Log.d(TAG, "Ignoring model task since loader is pending=" + this);
             }
             // Loader has not yet run.
-            return;
+            //return;
+            //cczheng annotaion
         }
         execute(mApp, mDataModel, mAllAppsList);
     }

5、新安装的 app 自动添加图标到 Workspace

packages\apps\Launcher3\src\com\android\launcher3\model\PackageUpdatedTask.java

execute() 中增加判断,添加 updateToWorkSpace()

 
+import android.content.pm.LauncherActivityInfo;
+import android.util.Pair;
+import com.android.launcher3.model.data.AppInfo;
+
+

@@ -358,7 +363,46 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
             }
             bindUpdatedWidgets(dataModel);
         }
+
+        //cczheng add for load new install app on workspace 
+        if (LauncherAppState.isDisableAllApps()) {
+            android.util.Log.e("cczLauncher3", "updateToWorkSpace()");
+            updateToWorkSpace(context, app, appsList);
+        }//end
+
+    }
+
+    //cczheng add for load new install app on workspace
+    public void updateToWorkSpace(Context context, LauncherAppState app , AllAppsList appsList){
+         ArrayList<Pair<ItemInfo, Object>> installQueue = new ArrayList<>();
+        // final List<UserHandle> profiles = UserManagerCompat.getInstance(context).getUserProfiles();
+        UserManager mUserManager = context.getSystemService(UserManager.class);
+        LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
+        final List<UserHandle> profiles = mUserManager.getUserProfiles();
+        ArrayList<ItemInstallQueue.PendingInstallShortcutInfo> added 
+        = new ArrayList<ItemInstallQueue.PendingInstallShortcutInfo>();
+        
+        for (UserHandle user : profiles) {
+            // final List<LauncherActivityInfo> apps = LauncherAppsCompat.getInstance(context).getActivityList(null, user);
+            final List<LauncherActivityInfo> apps = launcherApps.getActivityList(null, user);
+            synchronized (this) {
+                for (LauncherActivityInfo info : apps) {
+                    for (AppInfo appInfo : appsList.data) {
+                        if(info.getComponentName().equals(appInfo.componentName)){
+                            ItemInstallQueue.PendingInstallShortcutInfo mPendingInstallShortcutInfo 
+                            =  new ItemInstallQueue.PendingInstallShortcutInfo(info.getComponentName().getPackageName(), info.getUser());
+                            added.add(mPendingInstallShortcutInfo);
+                            installQueue.add(mPendingInstallShortcutInfo.getItemInfo(context));
+                        }
+                    }
+                }
+            }
+        }
+        if (!added.isEmpty()) {
+            app.getModel().addAndBindAddedWorkspaceItems(installQueue);
+        }
     }
+    //end
 

6、替换 Workspace 图标长按删除选项为取消

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

在 setTextBasedOnDragSource() 、setControlTypeBasedOnDragSource()、onAccessibilityDrop() 中分别增加判断是否需要删除图标

@@ -95,6 +95,14 @@ public class DeleteDropTarget extends ButtonDropTarget {
             mText = getResources().getString(canRemove(item)
                     ? R.string.remove_drop_target_label
                     : android.R.string.cancel);
+             //cczheng add for hide deletedroptarget [S]
+            if (LauncherAppState.isDisableAllApps()) {
+                android.util.Log.e("Launcher3", "hide delete drop target");
+                mText = getResources().getString(isCanDrop(item)
+                            ? R.string.remove_drop_target_label
+                            : android.R.string.cancel);
+            }
+            //cczheng add for hide deletedroptarget [E]
             setContentDescription(mText);
             requestLayout();
         }
@@ -110,6 +118,11 @@ public class DeleteDropTarget extends ButtonDropTarget {
     private void setControlTypeBasedOnDragSource(ItemInfo item) {
         mLauncherEvent = item.id != ItemInfo.NO_ID ? LAUNCHER_ITEM_DROPPED_ON_REMOVE
                 : LAUNCHER_ITEM_DROPPED_ON_CANCEL;
+        //cczheng add for hide deletedroptarget [S]
+        if (LauncherAppState.isDisableAllApps()) {
+            mLauncherEvent = isCanDrop(item) ? LAUNCHER_ITEM_DROPPED_ON_REMOVE
+                : LAUNCHER_ITEM_DROPPED_ON_CANCEL;
+        }//end
     }
 
     @Override
@@ -135,8 +148,11 @@ public class DeleteDropTarget extends ButtonDropTarget {
                 modelWriter.abortDelete();
                 mLauncher.getStatsLogManager().logger().log(LAUNCHER_UNDO);
             };
-            Snackbar.show(mLauncher, R.string.item_removed, R.string.undo,
+            //cczheng add for don't show Snackbar
+            if (!LauncherAppState.isDisableAllApps()){
+                Snackbar.show(mLauncher, R.string.item_removed, R.string.undo,
                     modelWriter::commitDelete, onUndoClicked);
+            }
         }
     }
 
@@ -148,9 +164,18 @@ public class DeleteDropTarget extends ButtonDropTarget {
         // Remove the item from launcher and the db, we can ignore the containerInfo in this call
         // because we already remove the drag view from the folder (if the drag originated from
         // a folder) in Folder.beginDrag()
-        mLauncher.removeItem(view, item, true /* deleteFromDb */);
-        mLauncher.getWorkspace().stripEmptyScreens();
-        mLauncher.getDragLayer()
-                .announceForAccessibility(getContext().getString(R.string.item_removed));
+         //cczheng add if juge is need remove item from workspace
+        if (!LauncherAppState.isDisableAllApps() || isCanDrop(item)) {
+            mLauncher.removeItem(view, item, true /* deleteFromDb */);
+            mLauncher.getWorkspace().stripEmptyScreens();
+            mLauncher.getDragLayer()
+                    .announceForAccessibility(getContext().getString(R.string.item_removed));
+        }//end
+    }
+
+
+    private boolean isCanDrop(ItemInfo item){
+        return !(item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+                item.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
     }
 }

packages\apps\Launcher3\src\com\android\launcher3\dragndrop\DragController.java

drop() 中增加判断,取消当前拖拽操作

 
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.DeleteDropTarget;
+

@@ -525,12 +529,25 @@ public abstract class DragController<T extends ActivityContext>
                     dropTarget.onDrop(mDragObject, mOptions);
                 }
                 accepted = true;
+
+                //cczheng add for cancel canceldroptarget handle [S]
+                if (LauncherAppState.isDisableAllApps() && dropTarget instanceof DeleteDropTarget &&
+                        isNeedCancelDrag(mDragObject.dragInfo)) {
+                    cancelDrag();
+                }
+                //cczheng add for cancel canceldroptarget handle [E]
             }
         }
         final View dropTargetAsView = dropTarget instanceof View ? (View) dropTarget : null;
         dispatchDropComplete(dropTargetAsView, accepted);
     }
 
+    //cczheng add
+    private boolean isNeedCancelDrag(ItemInfo item){
+        return (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+                item.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
+    }//end
+
     private DropTarget findDropTarget(int x, int y, int[] dropCoordinates) {
         mDragObject.x = x;
         mDragObject.y = y;

7、屏蔽上拉显示抽屉页面手势

packages\apps\Launcher3\quickstep\src\com\android\launcher3\uioverrides\touchcontrollers\PortraitStatesTouchController.java

canInterceptTouch() 中增加判断是否直接拦截

 
+import com.android.launcher3.LauncherAppState;
+
 /**
  * Touch controller for handling various state transitions in portrait UI.
  */
@@ -78,6 +80,12 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
 
     @Override
     protected boolean canInterceptTouch(MotionEvent ev) {
+        //cczheng add 
+        if (LauncherAppState.isDisableAllApps()){
+            android.util.Log.e("Launcher3", "canInterceptTouch()");
+            return false;
+        }//end
+
         // If we are swiping to all apps instead of overview, allow it from anywhere.
         boolean interceptAnywhere = mLauncher.isInState(NORMAL);
         if (mCurrentAnimation != null) {

8、修改页面指示线为圆点

packages\apps\Launcher3\res\layout\launcher.xml

WorkspacePageIndicator 改为 PageIndicatorDots

 
         <!-- Keep these behind the workspace so that they are not visible when
          we go into AllApps -->
-        <com.android.launcher3.pageindicators.WorkspacePageIndicator
+         <!-- cczheng change WorkspacePageIndicator line to dot  @dimen/workspace_page_indicator_height-->
+        <!-- <com.android.launcher3.pageindicators.WorkspacePageIndicator -->
+        <com.android.launcher3.pageindicators.PageIndicatorDots
             android:id="@+id/page_indicator"
             android:layout_width="match_parent"
-            android:layout_height="@dimen/workspace_page_indicator_height"
+            android:layout_height="4dp"
             android:layout_gravity="bottom|center_horizontal"
             android:theme="@style/HomeScreenElementTheme" />
 

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

+import com.android.launcher3.pageindicators.PageIndicatorDots;
 import com.android.launcher3.popup.PopupContainerWithArrow;
 import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.statemanager.StateManager.StateHandler;
@@ -129,7 +130,8 @@ import java.util.stream.Collectors;
  * Each page contains a number of icons, folders or widgets the user can
  * interact with. A workspace is meant to be used with a fixed width only.
  */
-public class Workspace extends PagedView<WorkspacePageIndicator>
+// public class Workspace extends PagedView<WorkspacePageIndicator>
+public class Workspace extends PagedView<PageIndicatorDots>
         implements DropTarget, DragSource, View.OnTouchListener,
         DragController.DragListener, Insettable, StateHandler<LauncherState>,
         WorkspaceLayoutManager {

packages\apps\Launcher3\src\com\android\launcher3\pageindicators\PageIndicatorDots.java

增加 PageIndicatorDots 继承 Insettable,复写setInsets(), 调整圆点的位置

import com.android.launcher3.util.Themes;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Insettable;
+import android.widget.FrameLayout;
+import android.graphics.Rect;
+import android.view.Gravity;
 
 /**
  * {@link PageIndicator} which shows dots per page. The active page is shown with the current
  * accent color.
  */
-public class PageIndicatorDots extends View implements PageIndicator {
+public class PageIndicatorDots extends View implements PageIndicator, Insettable {
 
     private static final float SHIFT_PER_ANIMATION = 0.5f;
     private static final float SHIFT_THRESHOLD = 0.1f;
@@ -97,6 +103,7 @@ public class PageIndicatorDots extends View implements PageIndicator {
 
     private float[] mEntryAnimationRadiusFactors;
 
+    private final Launcher mLauncher;
     public PageIndicatorDots(Context context) {
         this(context, null);
     }
@@ -117,8 +124,27 @@ public class PageIndicatorDots extends View implements PageIndicator {
         mInActiveColor = Themes.getAttrColor(context, android.R.attr.colorControlHighlight);
 
         mIsRtl = Utilities.isRtl(getResources());
+        mLauncher = Launcher.getLauncher(context);
     }
 
+    //cczheng add for change WorkspacePageIndicator line to dot
+    @Override
+    public void setInsets(Rect insets) {
+        DeviceProfile grid = mLauncher.getDeviceProfile();
+        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
+
+        if (grid.isVerticalBarLayout()) {
+            Rect padding = grid.workspacePadding;
+            lp.leftMargin = padding.left + grid.workspaceCellPaddingXPx;
+            lp.rightMargin = padding.right + grid.workspaceCellPaddingXPx;
+            lp.bottomMargin = padding.bottom;
+        } else {
+            lp.leftMargin = lp.rightMargin = 0;
+            lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+            lp.bottomMargin = grid.hotseatBarSizePx + insets.bottom;
+        }
+        setLayoutParams(lp);
+    }//end
     @Override
     public void setScroll(int currentScroll, int totalScroll) {
         if (mNumPages > 1) {
@@ -126,6 +152,10 @@ public class PageIndicatorDots extends View implements PageIndicator {
                 currentScroll = totalScroll - currentScroll;
             }
             int scrollPerPage = totalScroll / (mNumPages - 1);
+            //cczheng add for change WorkspacePageIndicator line to dot
+            if (scrollPerPage == 0) {
+                return;
+            }//end
             int pageToLeft = currentScroll / scrollPerPage;
             int pageToLeftScroll = pageToLeft * scrollPerPage;
             int pageToRightScroll = pageToLeftScroll + scrollPerPage;

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

     // Request id for any pending activity result
     protected int mPendingActivityRequestCode = -1;
 
-    private ViewGroupFocusHelper mFocusHandler;
+    public ViewGroupFocusHelper mFocusHandler;
 
     private RotationHelper mRotationHelper;
 
@@ -1038,8 +1038,8 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
             mWorkspace.showPageIndicatorAtCurrentScroll();
             mWorkspace.setClipChildren(false);
         }
-        // When multiple pages are visible, show persistent page indicator
-        mWorkspace.getPageIndicator().setShouldAutoHide(!state.hasFlag(FLAG_MULTI_PAGE));
+        // When multiple pages are visible, show persistent page indicator//cczheng
+        //mWorkspace.getPageIndicator().setShouldAutoHide(!state.hasFlag(FLAG_MULTI_PAGE));
 
         mPrevLauncherState = mStateManager.getCurrentStableState();
         if (mPrevLauncherState != state && ALL_APPS.equals(state)

packages\apps\Launcher3\quickstep\src\com\android\launcher3\QuickstepTransitionManager.java

             }
 
             // Pause page indicator animations as they lead to layer trashing.
-            mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
+            // mLauncher.getWorkspace().getPageIndicator().pauseAnimations();//cczheng
 
             endListener = () -> {
                 viewsToAnimate.forEach(view -> {
@@ -540,7 +540,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                 if (scrimEnabled) {
                     mLauncher.getScrimView().setBackgroundColor(Color.TRANSPARENT);
                 }
-                mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
+                // mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();//cczheng
             };
         }
 
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-02-24 15:24:46  更:2022-02-24 15:26:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年9日历 -2024/9/21 15:28:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码