android 11 Launcher3去掉抽屉

Posted Wang丶Yan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 去掉抽屉模式修改完成。有什么问题可以给我留言。 

Android系统之路(初识MTK) ------Android11.0去掉Hotseat快捷栏的应用名称

Android11.0去掉Hotseat快捷栏的应用名称

今天因为在复测昨天的一个monkey压测并且还没测完,所以打算记录最近做系统开发的一些心得和经验,也记录一下自己的系统开发历程

修改前效果:

修改后的效果:

需要修改的文件列表(注意:各个版本或平台可能要修改的文件不一样,作者源码为非原生,均属于MTK平台)

/packages/apps/Launcher3/src/com/android/launcher3/popup/PopupContainerWithArrow.java

这里修改的作用是拖拽之后仍旧生效,普通的修改也就是桌面初次加载的地方可以修改addInScreen或者CellLayout的addViewIntoLayout方法,具体方法名可以查下源码,笔者记不太清了

--- a/packages/apps/

以上是关于android 11 Launcher3去掉抽屉的主要内容,如果未能解决你的问题,请参考以下文章

Android Launcher 去掉全部应用界面的搜索框

Android系统之路(初识MTK) ------Android11.0去掉Hotseat快捷栏的应用名称

Android系统之路(初识MTK) ------Android11.0去掉Hotseat快捷栏的应用名称

Android系统之路(初识MTK) ------Android11.0去掉Hotseat快捷栏的应用名称

Android 6.0 隐藏Launcher3

Android 手机桌面图标出现白边