android 11 Launcher3去掉抽屉

目录

前言

一、屏蔽上拉手势

二、将所有app加载至workspace

三、所有图标长按移动时顶部“移除”选项去掉

四、workspace中pageview指示横条换为圆点指示



前言

鉴于目前国内各大消费类手机都支持launcher左右滑动的这种标准桌面,google代码中为提供抽屉模式与标准模式的切换,所以我们在google源码的基础上修改launcher让其支持这种标准桌面。


一、屏蔽上拉手势

代码路径:packages\apps\Launcher3\quickstep\src\com\android\launcher3\uioverrides\touchcontrollers\PortraitStatesTouchController.java
 @Override
    protected boolean canInterceptTouch(MotionEvent ev) {
        //新增代码  屏蔽上拉手势  start
        if (true) {
            return false;
        }
        //新增代码  屏蔽上拉手势  end

        if (mCurrentAnimation != null) {
            if (mFinishFastOnSecondTouch) {
                mCurrentAnimation.getAnimationPlayer().end();
            }

            AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
            if (ev.getY() >= allAppsController.getShiftRange() * allAppsController.getProgress()) {
                // If we are already animating from a previous state, we can intercept as long as
                // the touch is below the current all apps progress (to allow for double swipe).
                return true;
            }
            // Otherwise, make sure everything is settled and don't intercept so they can scroll
            // recents, dismiss a task, etc.
            if (mAtomicAnim != null) {
                mAtomicAnim.end();
            }
            return false;
        }
        if (mLauncher.isInState(ALL_APPS)) {
            // In all-apps only listen if the container cannot scroll itself
            if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
                return false;
            }
        } else if (mLauncher.isInState(OVERVIEW)) {
            if (!mOverviewPortraitStateTouchHelper.canInterceptTouch(ev)) {
                return false;
            }
        } else {
            // If we are swiping to all apps instead of overview, allow it from anywhere.
            boolean interceptAnywhere = mLauncher.isInState(NORMAL) && !mAllowDragToOverview;
            // For all other states, only listen if the event originated below the hotseat height
            if (!interceptAnywhere && !isTouchOverHotseat(mLauncher, ev)) {
                return false;
            }
        }
        if (getTopOpenViewWithType(mLauncher, TYPE_ACCESSIBLE | TYPE_ALL_APPS_EDU) != null) {
            return false;
        }
        return true;
    }

二、将所有app加载至workspace

代码路径:

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

  @Override
    public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList appsList) {
       
		//....省略前面代码
        bindApplicationsIfNeeded();
        
        //新增 更新app到WorkSpace  start
        updateToWorkSpace(context,app,appsList);
        //新增 更新app到WorkSpace  end
		
		//....省略后面代码
        
    }
	
	
	//新增如下方法  start
    public void updateToWorkSpace(Context context, LauncherAppState app, AllAppsList appsList) {
        ArrayList<Pair<ItemInfo, Object>> installQueue = new ArrayList<>();
        UserManager mUserManager = context.getSystemService(UserManager.class);
        final List<UserHandle> profiles = mUserManager.getUserProfiles();
        ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo> added = new ArrayList<>();
        LauncherApps mLauncherApps = context.getSystemService(LauncherApps.class);
        for (UserHandle user : profiles) {
            final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
            synchronized (this) {
                for (LauncherActivityInfo info : apps) {
                    for (AppInfo appInfo : appsList.data) {
                           String packageName = info.getComponentName().getPackageName();
						   //Log.d(TAG, "updateToWorkSpace packageName :" + packageName+",appInfo.componentName:"+appInfo.componentName);
                        if (info.getComponentName().equals(appInfo.componentName)) {
                            InstallShortcutReceiver.PendingInstallShortcutInfo
                                    mPendingInstallShortcutInfo
                                    = new InstallShortcutReceiver.PendingInstallShortcutInfo(info, context);
                           //Log.e(TAG,"itemType :"+mPendingInstallShortcutInfo.getItemInfo().first.itemType);
                            added.add(mPendingInstallShortcutInfo);
                            installQueue.add(mPendingInstallShortcutInfo.getItemInfo());

                        }
                    }
                }
            }
        }
		 Log.d(TAG, "installQueue :" + installQueue.size());
        Log.d(TAG, "added.isEmpty() :" + added.isEmpty());
        if (!added.isEmpty()) {

            app.getModel().addAndBindAddedWorkspaceItems(installQueue);
        }
    }
	//新增如下方法  end

 以上代码只是将所有app获取到新增到WorkSpaceItems中,WorkSpaceItems中对于app还做了处理,看下面代码

代码路径:

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

 @Override
    public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
        if (mItemList.isEmpty()) {
            return;
        }

        final ArrayList<ItemInfo> addedItemsFinal = new ArrayList<>();
        final IntArray addedWorkspaceScreensFinal = new IntArray();

        synchronized (dataModel) {
            IntArray workspaceScreens = dataModel.collectWorkspaceScreens();

            List<ItemInfo> filteredItems = new ArrayList<>();
            for (Pair<ItemInfo, Object> entry : mItemList) {
                ItemInfo item = entry.first;
                if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
                        item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
                    // Short-circuit this logic if the icon exists somewhere on the workspace
                    if (shortcutExists(dataModel, item.getIntent(), item.user)) {
                        continue;
                    }

                    // b/139663018 Short-circuit this logic if the icon is a system app
                    //注释掉 该端代码  start
                   /* if (PackageManagerHelper.isSystemApp(app.getContext(), item.getIntent()) ) {
                        continue;
                    }*/
                    //注释掉 该端代码  end
					
					
					//...省略代码
                }

                //...省略代码
            }

           //...省略代码
        }
        
    }

三、所有图标长按移动时顶部“移除”选项去掉

1.去掉“移除”按钮

代码路径:

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

修改如下:

  @Override
    protected boolean supportsDrop(ItemInfo info) {
       // 将 return true 修改为 return false;
        return false;
    }

2.DropTargetBar在去掉了“移除”按钮后,系统应用长按拖动会奔溃,我们需要在无按钮时DropTargetBar测量及绘制时重新给定宽和高

代码路径:

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

  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        if (getVisibleButtonsCount()>0){//新增显示的button数量判断,大于0才重新计算每个按钮的宽和高
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);
            if (mIsVertical) {
                int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
                int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);

                for (ButtonDropTarget button : mDropTargets) {
                    if (button.getVisibility() != GONE) {
                        button.setTextVisible(false);
                        button.measure(widthSpec, heightSpec);
                    }
                }
            } else {
                int visibleCount = getVisibleButtonsCount();
                int availableWidth = width / visibleCount;
                boolean textVisible = true;
                for (ButtonDropTarget buttons : mDropTargets) {
                    if (buttons.getVisibility() != GONE) {
                        textVisible = textVisible && !buttons.isTextTruncated(availableWidth);
                    }
                }

                int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
                int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
                for (ButtonDropTarget button : mDropTargets) {
                    if (button.getVisibility() != GONE) {
                        button.setTextVisible(textVisible);
                        button.measure(widthSpec, heightSpec);
                    }
                }
            }
            setMeasuredDimension(width, height);
        }else{//新增显示的button数量判断,小于0给默认高度48
            int width = MeasureSpec.getSize(heightMeasureSpec);
            int height = 48;
            setMeasuredDimension(width, height);
        }

    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (getVisibleButtonsCount()>0) {  //新增显示的button数量判断,大于0才绘制
            if (mIsVertical) {
                int gap = getResources().getDimensionPixelSize(R.dimen.drop_target_vertical_gap);
                int start = gap;
                int end;

                for (ButtonDropTarget button : mDropTargets) {
                    if (button.getVisibility() != GONE) {
                        end = start + button.getMeasuredHeight();
                        button.layout(0, start, button.getMeasuredWidth(), end);
                        start = end + gap;
                    }
                }
            } else {
                int visibleCount = getVisibleButtonsCount();
                int frameSize = (right - left) / visibleCount;

                int start = frameSize / 2;
                int halfWidth;
                for (ButtonDropTarget button : mDropTargets) {
                    if (button.getVisibility() != GONE) {
                        halfWidth = button.getMeasuredWidth() / 2;
                        button.layout(start - halfWidth, 0,
                                start + halfWidth, button.getMeasuredHeight());
                        start = start + frameSize;
                    }
                }
            }
        }
    }

四、workspace中pageview指示横条换为圆点指示

1.布局文件替换

代码路径:

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

<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2007 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.
-->
<com.android.launcher3.LauncherRootView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:launcher="http://schemas.android.com/apk/res-auto"
    android:id="@+id/launcher"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <com.android.launcher3.dragndrop.DragLayer
        android:id="@+id/drag_layer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:importantForAccessibility="no">

        <!-- The workspace contains 5 screens of cells -->
        <!-- DO NOT CHANGE THE ID -->
        <com.android.launcher3.Workspace
            android:id="@+id/workspace"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:theme="@style/HomeScreenElementTheme"
            launcher:pageIndicator="@+id/page_indicator" />

        <!-- DO NOT CHANGE THE ID -->
        <include
            android:id="@+id/hotseat"
            layout="@layout/hotseat" />

        <include
            android:id="@+id/overview_panel"
            layout="@layout/overview_panel" />


        <!-- 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.PageIndicatorDots-->
        <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_gravity="bottom|center_horizontal"
            android:theme="@style/HomeScreenElementTheme" />

        <include
            android:id="@+id/drop_target_bar"
            layout="@layout/drop_target_bar" />

        <include
            android:id="@+id/scrim_view"
            layout="@layout/scrim_view" />

        <include
            android:id="@+id/apps_view"
            layout="@layout/all_apps"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </com.android.launcher3.dragndrop.DragLayer>

</com.android.launcher3.LauncherRootView>

2.WorkSpace继承修改

public class Workspace extends PagedView<WorkspacePageIndicator>
        implements DropTarget, DragSource, View.OnTouchListener,
        DragController.DragListener, Insettable, StateHandler<LauncherState>,
        WorkspaceLayoutManager
修改为
public class Workspace extends PagedView<PageIndicatorDots>  
        implements DropTarget, DragSource, View.OnTouchListener,
        DragController.DragListener, Insettable, StateHandler<LauncherState>,
        WorkspaceLayoutManager

3.修改左右滑动圆点指示的动画

代码路径:packages\apps\Launcher3\quickstep\src\com\android\launcher3\QuickstepAppTransitionManagerImpl.java

 /**
     * Content is everything on screen except the background and the floating view (if any).
     *
     * @param isAppOpening True when this is called when an app is opening.
     *                     False when this is called when an app is closing.
     * @param trans Array that contains the start and end translation values for the content.
     */
    private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening,
            float[] trans) {
        AnimatorSet launcherAnimator = new AnimatorSet();
        Runnable endListener;

        float[] alphas = isAppOpening
                ? new float[] {1, 0}
                : new float[] {0, 1};

        if (mLauncher.isInState(ALL_APPS)) {
           //省略代码...
        } else if (mLauncher.isInState(OVERVIEW)) {
            //省略代码...
        } else {
            //省略代码...

            // Pause page indicator animations as they lead to layer trashing.
            //注释该行代码
           // mLauncher.getWorkspace().getPageIndicator().pauseAnimations();

            endListener = () -> {
                currentPage.setTranslationY(0);
                hotseat.setTranslationY(0);
				
                currentPage.setLayerType(View.LAYER_TYPE_NONE, null);
                hotseat.setLayerType(View.LAYER_TYPE_NONE, null);
				
                
                mDragLayerAlpha.setValue(1f);
				//mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();修改为 mLauncher.getWorkspace().getPageIndicator().stopAllAnimations();
                mLauncher.getWorkspace().getPageIndicator().stopAllAnimations();
            };
        }
        return new Pair<>(launcherAnimator, endListener);
    }

4.修改PageIndicatorDots

代码路径:packages\apps\Launcher3\src\com\android\launcher3\pageindicators\PageIndicatorDots.java

PageIndicatorDots 实现Insettable

整体代码如下:

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;
    private static final long ANIMATION_DURATION = 150;

    private static final int ENTER_ANIMATION_START_DELAY = 300;
    private static final int ENTER_ANIMATION_STAGGERED_DELAY = 150;
    private static final int ENTER_ANIMATION_DURATION = 400;

    // This value approximately overshoots to 1.5 times the original size.
    private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f;

    private static final RectF sTempRect = new RectF();

    private static final Property<PageIndicatorDots, Float> CURRENT_POSITION
            = new Property<PageIndicatorDots, Float>(float.class, "current_position") {
        @Override
        public Float get(PageIndicatorDots obj) {
            return obj.mCurrentPosition;
        }

        @Override
        public void set(PageIndicatorDots obj, Float pos) {
            obj.mCurrentPosition = pos;
            obj.invalidate();
            obj.invalidateOutline();
        }
    };

    private final Paint mCirclePaint;
    private final float mDotRadius;
    private final int mActiveColor;
    private final int mInActiveColor;
    private final boolean mIsRtl;

    private int mNumPages;
    private int mActivePage;

    /**
     * The current position of the active dot including the animation progress.
     * For ex:
     * 0.0  => Active dot is at position 0
     * 0.33 => Active dot is at position 0 and is moving towards 1
     * 0.50 => Active dot is at position [0, 1]
     * 0.77 => Active dot has left position 0 and is collapsing towards position 1
     * 1.0  => Active dot is at position 1
     */
    private float mCurrentPosition;
    private float mFinalPosition;
    private ObjectAnimator mAnimator;

    private float[] mEntryAnimationRadiusFactors;
    //wangyan
    private Launcher mLauncher;

    public PageIndicatorDots(Context context) {
        this(context, null);
    }

    public PageIndicatorDots(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PageIndicatorDots(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCirclePaint.setStyle(Style.FILL);
        mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2;
        setOutlineProvider(new MyOutlineProver());

        //选中与未选中的颜色修改
        mActiveColor = Color.parseColor("#ffffff");///Themes.getColorAccent(context);
        mInActiveColor = Color.parseColor("#c6c5c5");  //Themes.getAttrColor(context, android.R.attr.colorControlHighlight);

        mIsRtl = Utilities.isRtl(getResources());
        //wangyan
        mLauncher = Launcher.getLauncher(context);
    }

    //新增实现方法 start
    @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) {
            if (mIsRtl) {
                currentScroll = totalScroll - currentScroll;
            }
            int scrollPerPage = totalScroll / (mNumPages - 1);

            //wangyan
            if (scrollPerPage == 0) {
                return;
            }
            int pageToLeft = currentScroll / scrollPerPage;
            int pageToLeftScroll = pageToLeft * scrollPerPage;
            int pageToRightScroll = pageToLeftScroll + scrollPerPage;

            float scrollThreshold = SHIFT_THRESHOLD * scrollPerPage;
            if (currentScroll < pageToLeftScroll + scrollThreshold) {
                // scroll is within the left page's threshold
                animateToPosition(pageToLeft);
            } else if (currentScroll > pageToRightScroll - scrollThreshold) {
                // scroll is far enough from left page to go to the right page
                animateToPosition(pageToLeft + 1);
            } else {
                // scroll is between left and right page
                animateToPosition(pageToLeft + SHIFT_PER_ANIMATION);
            }
        }
    }

    //....省略部分代码
}

至此android 11 Launcher3 去掉抽屉模式修改完成。有什么问题可以给我留言。 

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值