androidQ(10.0) Launcher3 修改PageIndicator为小圆点

修改workspace最后一列图标长按ArrowPopup显示位置不对bug

bug现象图

error

修正效果图

righticon

解决办法

packages\apps\Launcher3\src\com\android\launcher3\popup\ArrowPopup.java

    protected void orientAboutObject() {
        measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        int width = getMeasuredWidth();

		....
		 //cczheng add
		 if (x > 1000) {
            x = 835;
            mIsLeftAligned = false;
        }
        setX(x);
        Log.d("ArrowPopup"," setX x="+x);
        if (Gravity.isVertical(mGravity)) {
            return;
        }
		....
}

orientAboutObject 方法中 setX() 之前重新修正 x 坐标即可,具体分析思路看下面

思路分析图

UB1Rje.png

AllAppContainer 中最后一列图标长按显示是ok的,到了workspace中显示就错位了,仔细观察发现 y 值是对的,

加日志打印对比

workspace 容器中
音乐APP
2020-05-16 08:21:39.552 1669-1669/com.android.launcher3 E/PopupContainerWithArrow: shortcutCount=0
2020-05-16 08:21:39.572 1669-1669/com.android.launcher3 I/ArrowPopup:  MeasureSpec x=1045  y=462
2020-05-16 08:21:39.572 1669-1669/com.android.launcher3 D/ArrowPopup:  setX x=1045
2020-05-16 08:21:39.572 1669-1669/com.android.launcher3 I/ArrowPopup:  arrowLp.gravity=80 lp.bottomMargin=168 arrowLp.bottomMargin=101
2020-05-16 08:21:39.580 1669-1669/com.android.launcher3 E/PopupContainerWithArrow: showForIcon=
2020-05-16 08:21:39.600 1669-1669/com.android.launcher3 I/ArrowPopup:  set Gravity.CENTER_HORIZONTAL
2020-05-16 08:21:39.601 1669-1669/com.android.launcher3 D/ArrowPopup:  INVISIBLE mArrow503
浏览器APP
2020-05-16 08:28:51.636 1669-1669/com.android.launcher3 I/ArrowPopup:  MeasureSpec x=825  y=462
2020-05-16 08:28:51.636 1669-1669/com.android.launcher3 D/ArrowPopup:  setX x=825
2020-05-16 08:28:51.636 1669-1669/com.android.launcher3 I/ArrowPopup:  arrowLp.gravity=80 lp.bottomMargin=168 arrowLp.bottomMargin=101

AllAppContainer 容器中
信息APP
2020-05-16 08:22:08.903 1669-1669/com.android.launcher3 E/PopupContainerWithArrow: shortcutCount=0
2020-05-16 08:22:08.916 1669-1669/com.android.launcher3 I/ArrowPopup:  MeasureSpec x=899  y=76
2020-05-16 08:22:08.917 1669-1669/com.android.launcher3 D/ArrowPopup:  setX x=899
2020-05-16 08:22:08.917 1669-1669/com.android.launcher3 I/ArrowPopup:  arrowLp.gravity=80 lp.bottomMargin=554 arrowLp.bottomMargin=487
2020-05-16 08:22:08.926 1669-1669/com.android.launcher3 E/PopupContainerWithArrow: showForIcon=
设置APP
2020-05-16 08:33:06.663 1669-1669/com.android.launcher3 E/PopupContainerWithArrow: shortcutCount=3
2020-05-16 08:33:06.692 1669-1669/com.android.launcher3 I/ArrowPopup:  MeasureSpec x=899  y=201
2020-05-16 08:33:06.692 1669-1669/com.android.launcher3 D/ArrowPopup:  setX x=899
2020-05-16 08:33:06.692 1669-1669/com.android.launcher3 E/ArrowPopup:  arrowLp.gravity=48 lp.topMargin=231 arrowLp.topMargin=194
2020-05-16 08:33:06.698 1669-1669/com.android.launcher3 E/PopupContainerWithArrow: showForIcon=

从上面的日志分析得出,每次错位时,x的值都是大于1000,而 AllAppContainer 中最后一列X最大值为 899,

workspace 中倒数第二列X值为825,所以要想最后一列 ArrowPopup 正确显示,X 就得在 825 到 899 之间。

所以重新修正 X 值,当 x > 1000 时,重新赋值为 835(经过几次测试效果得出值)

mIsLeftAligned = false; 用来控制小箭头的位置在 ArrowPopup 居右

对应获取 popup_arrow_horizontal_center_end,同时修改 mArrow X 坐标,反之则在 ArrowPopup 居左

 protected void reorderAndShow(int viewsToFlip) {
        setVisibility(View.INVISIBLE);
        mIsOpen = true;
        getPopupContainer().addView(this);
        orientAboutObject();

        boolean reverseOrder = mIsAboveIcon;
        if (reverseOrder) {
            int count = getChildCount();
            ArrayList<View> allViews = new ArrayList<>(count);
            for (int i = 0; i < count; i++) {
                if (i == viewsToFlip) {
                    Collections.reverse(allViews);
                }
                allViews.add(getChildAt(i));
            }
            Collections.reverse(allViews);
            removeAllViews();
            for (int i = 0; i < count; i++) {
                addView(allViews.get(i));
            }

            orientAboutObject();
        }
        onInflationComplete(reverseOrder);

        // Add the arrow.
        final Resources res = getResources();
        final int arrowCenterOffset = res.getDimensionPixelSize(isAlignedWithStart()
                ? R.dimen.popup_arrow_horizontal_center_start
                : R.dimen.popup_arrow_horizontal_center_end);
        final int halfArrowWidth = res.getDimensionPixelSize(R.dimen.popup_arrow_width) / 2;
        getPopupContainer().addView(mArrow);
        DragLayer.LayoutParams arrowLp = (DragLayer.LayoutParams) mArrow.getLayoutParams();
        Log.e("ArrowPopup","getX() ="+getX()+" arrowCenterOffset="+arrowCenterOffset 
            +" halfArrowWidth="+halfArrowWidth+" getMeasuredWidth()="+getMeasuredWidth());
        if (mIsLeftAligned) {
            Log.i("ArrowPopup"," mIsLeftAligned ="+mIsLeftAligned);
            mArrow.setX(getX() + arrowCenterOffset - halfArrowWidth);
        } else {
            mArrow.setX(getX() + getMeasuredWidth() - arrowCenterOffset - halfArrowWidth);
        }

        if (Gravity.isVertical(mGravity)) {
            // This is only true if there wasn't room for the container next to the icon,
            // so we centered it instead. In that case we don't want to showDefaultOptions the arrow.
            mArrow.setVisibility(INVISIBLE);
        } else {
            ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create(
                    arrowLp.width, arrowLp.height, !mIsAboveIcon));
            Paint arrowPaint = arrowDrawable.getPaint();
            arrowPaint.setColor(Themes.getAttrColor(getContext(), R.attr.popupColorPrimary));
            // The corner path effect won't be reflected in the shadow, but shouldn't be noticeable.
            int radius = getResources().getDimensionPixelSize(R.dimen.popup_arrow_corner_radius);
            arrowPaint.setPathEffect(new CornerPathEffect(radius));
            mArrow.setBackground(arrowDrawable);
            // Clip off the part of the arrow that is underneath the popup.
            if (mIsAboveIcon) {
                mArrow.setClipBounds(new Rect(0, -mArrowOffset, arrowLp.width, arrowLp.height));
            } else {
                mArrow.setClipBounds(new Rect(0, 0, arrowLp.width, arrowLp.height + mArrowOffset));
            }
            mArrow.setElevation(getElevation());
        }

        mArrow.setPivotX(arrowLp.width / 2);
        mArrow.setPivotY(mIsAboveIcon ? arrowLp.height : 0);

        Log.i("ArrowPopup"," arrowLp.width ="+arrowLp.width +"  arrowLp.height="+arrowLp.height);
        Log.d("ArrowPopup"," mArrow.X ="+ mArrow.getX() +"  mArrow.Y="+ mArrow.getY());

        animateOpen();
    }


修改PageIndicator为小圆点

效果图

UB4aBF.png

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

+++ b/alps/packages/apps/Launcher3/res/layout/launcher.xml
         <!-- Keep these behind the workspace so that they are not visible when
          we go into AllApps -->
-        <com.android.launcher3.pageindicators.WorkspacePageIndicator
+        <!-- <com.android.launcher3.pageindicators.WorkspacePageIndicator -->
+        <com.android.launcher3.pageindicators.PageIndicatorDots
             android:id="@+id/page_indicator"
             android:layout_width="match_parent"
-            android:layout_height="@dimen/vertical_drag_handle_size"
+            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.WorkspacePageIndicator;
+import com.android.launcher3.pageindicators.PageIndicatorDots;
 import com.android.launcher3.popup.PopupContainerWithArrow;
 import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
 import com.android.launcher3.testing.TestProtocol;
@@ -110,7 +111,8 @@ import java.util.function.Predicate;
  * 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, LauncherStateManager.StateHandler,
         WorkspaceLayoutManager {

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

import com.android.launcher3.Utilities;
 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,8 @@ public class PageIndicatorDots extends View implements PageIndicator {
 
     private float[] mEntryAnimationRadiusFactors;
 
+    private final Launcher mLauncher;
+
     public PageIndicatorDots(Context context) {
         this(context, null);
     }
@@ -117,6 +125,41 @@ public class PageIndicatorDots extends View implements PageIndicator {
         mInActiveColor = Themes.getAttrColor(context, android.R.attr.colorControlHighlight);
 
         mIsRtl = Utilities.isRtl(getResources());
+
+        mLauncher = Launcher.getLauncher(context);
+    }
+
+    //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);
+    }
+
+        /**
+     * Pauses all currently running animations.
+     */
+    public void pauseAnimations() {
+        stopAllAnimations();
+    }
+
+    /**
+     * Force-ends all currently running or paused animations.
+     */
+    public void skipAnimationsToEnd() {
+        stopAllAnimations();
     }
 
     @Override
@@ -126,6 +169,10 @@ public class PageIndicatorDots extends View implements PageIndicator {
                 currentScroll = totalScroll - currentScroll;
             }
             int scrollPerPage = totalScroll / (mNumPages - 1);
+            //add for change WorkspacePageIndicator line to dot
+            if (scrollPerPage == 0) {
+                return;
+            }
             int pageToLeft = currentScroll / scrollPerPage;
             int pageToLeftScroll = pageToLeft * scrollPerPage;
             int pageToRightScroll = pageToLeftScroll + scrollPerPage;




packages/apps/Launcher3/src/com/android/launcher3/states/SpringLoadedState.java

     public void onStateEnabled(Launcher launcher) {
         Workspace ws = launcher.getWorkspace();
         ws.showPageIndicatorAtCurrentScroll();
-        ws.getPageIndicator().setShouldAutoHide(false);
+        // ws.getPageIndicator().setShouldAutoHide(false);
 
         // Prevent any Un/InstallShortcutReceivers from updating the db while we are
         // in spring loaded mode
@@ -96,7 +97,8 @@ public class SpringLoadedState extends LauncherState {
 
     @Override
     public void onStateDisabled(final Launcher launcher) {
-        launcher.getWorkspace().getPageIndicator().setShouldAutoHide(true);
+        // launcher.getWorkspace().getPageIndicator().setShouldAutoHide(true);
 
         // Re-enable any Un/InstallShortcutReceiver and now process any queued items
         InstallShortcutReceiver.disableAndFlushInstallQueue(

猜你喜欢

转载自blog.csdn.net/u012932409/article/details/107443409