美文网首页Android知识
Launcher3 5.1 客制化定制问题修改(更新7.0MTK

Launcher3 5.1 客制化定制问题修改(更新7.0MTK

作者: Exception_Cui | 来源:发表于2016-12-28 16:35 被阅读3489次
    本文全部是基于将双层界面修改成单层桌面的问题

    最近客户提出要客制化定制Launcher3
    对最近的修改做个笔记

    1.修改默认壁纸

    替换 frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.jpg即可(注意找到对应的分辨率)

    2.将双层桌面改成单层桌面

    LauncherAppState.java

        public static boolean isDisableAllApps() {
          ...
          return true 即可
        }
    
    

    3.删除谷歌搜索

    Launcher.java

     public View getQsbBar() {
      ...
       return null; 即可
      }
    

    注意上面会隐藏谷歌搜索,但是还会占着位置
    想要不占位置
    DeviceProfile.java

    private void updateIconSize(float scale, int drawablePadding, Resources resources,
                                    DisplayMetrics dm) {      
       ...   
         // Search Bar
      ...
            searchBarSpaceHeightPx = getSearchBarTopOffset()
                    + resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
        
             将searchBarSpaceHeightPx=0;即可 
    }
    

    Launcher里面好多东西都是动态计算的,所以这里计算为0就行

    4.修改主屏幕大小位置 (即图标 几*几)

    DynamicGrid.java

    public DynamicGrid(Context context, Resources resources,
                           int minWidthPx, int minHeightPx,
                           int widthPx, int heightPx,
                           int awPx, int ahPx) {
            DisplayMetrics dm = resources.getDisplayMetrics();
            ArrayList<DeviceProfile> deviceProfiles =
                    new ArrayList<DeviceProfile>();
            boolean hasAA = !LauncherAppState.isDisableAllApps();
            DEFAULT_ICON_SIZE_PX = pxFromDp(DEFAULT_ICON_SIZE_DP, dm);
            // Our phone profiles include the bar sizes in each orientation
            deviceProfiles.add(new DeviceProfile("Super Short Stubby",
                    255, 300,  2, 3,  48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4));
            deviceProfiles.add(new DeviceProfile("Shorter Stubby",
                    255, 400,  3, 3,  48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4));
           
             /*chc edit*/     
            (客户要求2 * 2  ,找到对应的屏幕大小  修改 parameters 第4,5个即可 )     
            parameters  6:可以调整Icon的大小
            parameters  8:控制hotseatd的数量
            parameters  9:控制hotseatd的Icon大小
           deviceProfiles.add(new DeviceProfile("Short Stubby",
                    275, 420,  2, 2,  70, 23, (hasAA ? 3 : 3), 53, R.xml.default_workspace_4x4));
          /*chc end */      
    
    
            deviceProfiles.add(new DeviceProfile("Stubby",
                    255, 450,  2, 3,  48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4));
            deviceProfiles.add(new DeviceProfile("Nexus S",
                    296, 491.33f,  4, 4,  48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4));
            /// M: add 294 X 460 profile
            deviceProfiles.add(new DeviceProfile("294 X 460",
                    294, 460,  3, 3,  50, 25, (hasAA ? 5 : 5), 59, R.xml.default_workspace_4x4));
            deviceProfiles.add(new DeviceProfile("Nexus 4",
                    335, 567,  4, 4,  DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4));
            deviceProfiles.add(new DeviceProfile("Nexus 5",
                    359, 567,  4, 4,  DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4));
            deviceProfiles.add(new DeviceProfile("Large Phone",
                    406, 694,  5, 5,  64, 14.4f,  5, 56, R.xml.default_workspace_5x5));
            // The tablet profile is odd in that the landscape orientation
            // also includes the nav bar on the side
            deviceProfiles.add(new DeviceProfile("Nexus 7",
                    575, 904,  5, 6,  72, 14.4f,  7, 60, R.xml.default_workspace_5x6));
            // Larger tablet profiles always have system bars on the top & bottom
            deviceProfiles.add(new DeviceProfile("Nexus 10",
                    727, 1207,  5, 6,  76, 14.4f,  7, 64, R.xml.default_workspace_5x6));
            deviceProfiles.add(new DeviceProfile("20-inch Tablet",
                    1527, 2527,  7, 7,  100, 20,  7, 72, R.xml.default_workspace_4x4));
            mMinWidth = dpiFromPx(minWidthPx, dm);
            mMinHeight = dpiFromPx(minHeightPx, dm);
            mProfile = new DeviceProfile(context, deviceProfiles,
                    mMinWidth, mMinHeight,
                    widthPx, heightPx,
                    awPx, ahPx,
                    resources);
        }
    

    5.禁止hotseat里面的Icon拖动,并且禁止形成文件夹

    Launcher.java

    public boolean onLongClick(View v) {
            ...
            CellLayout.CellInfo longClickCellInfo = null;
            View itemUnderLongClick = null;
            if (v.getTag() instanceof ItemInfo) {
                ItemInfo info = (ItemInfo) v.getTag();
                longClickCellInfo = new CellLayout.CellInfo(v, info);;
                itemUnderLongClick = longClickCellInfo.cell;
                resetAddInfo();
            }   
            /*chc add */     在此处进行判断是否在hotseat进行长按   
            boolean isHotseatbutten=false;
            if(longClickCellInfo!=null){
                isHotseatbutten= longClickCellInfo.container==-100? false:true;   //每一个Icon都有一个container的属性
    //hostSeat:是-101  其他的是-100 
    
            }
            if(isHotseatbutten){
                return false;
            }
            /*chc end*/             
             final boolean inHotseat = isHotseatLayout(v);  //不知为何原因 此isHotseatLayout(v)并不能判断时候在hotseat区域 
             ...
        
            return true;
        }
    

    禁止文件夹的形成
    Workspace.java

    boolean createUserFolderIfNecessary(View newView, long container, CellLayout target,
                int[] targetCell, float distance, boolean external, DragView dragView,
                Runnable postAnimationRunnable) {
        ...
        /*chc add*/
            if(container==-101){
               return false;
            }
            /*chc end*/  
        ...
    }
    

    6.将文件夹修改为4宫格

    FolderIcon.java

    1:修改圆形成为正方形
    FolderIcon.xml

    <com.android.launcher3.FolderIcon
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:focusable="true" >
        <ImageView
            android:id="@+id/preview_background"
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:antialias="true"
            android:src="@drawable/portal_ring_inner_holo"/> <!--将src换成正方形图标即可-->
    

    2.修改缩略图为2*2

     // The number of icons to display in the
        private static final int NUM_ITEMS_IN_PREVIEW = 4;  //此处为文件夹显示缩略图的数量
     // The amount of vertical spread between items in the stack [0...1]
        private static final float PERSPECTIVE_SHIFT_FACTOR = 1.20f;  //值越大 缩略图越小
    
    
        private PreviewItemDrawingParams computePreviewItemDrawingParams(int index,
                PreviewItemDrawingParams params) {
                  /*chc add */
                    int index_order = index;
                    final int previewPadding = FolderRingAnimator.sPreviewPadding;
                   /*chc end*/
    
            // We want to imagine our coordinates from the bottom left, growing up and to the
            // right. This is natural for the x-axis, but for the y-axis, we have to invert things.
            float transY = mAvailableSpaceInPreview - (offset + scaledSize + scaleOffsetCorrection);
            float transX = offset + scaleOffsetCorrection;
            
             
            /*chc add */     在此处计算图标的位置 , 下面是自己计算图标的位置
                transX=1 * previewPadding +2;
                transY=mAvailableSpaceInPreview - (mBaselineIconSize*2 + scaleOffsetCorrection)+previewPadding;
            if(index_order==1){
                transX=mBaselineIconSize+previewPadding*3;
                transY=mAvailableSpaceInPreview - (mBaselineIconSize*2 + scaleOffsetCorrection)+previewPadding;
            }else if(index_order==2){           
                transX=1 * previewPadding +2;
                transY=mAvailableSpaceInPreview - (mBaselineIconSize + scaleOffsetCorrection)+previewPadding*2;
            }else if(index_order==3){
                transX=mBaselineIconSize+previewPadding*3;
                transY=mAvailableSpaceInPreview - (mBaselineIconSize + scaleOffsetCorrection)+previewPadding*2;
            }
            
            /*chc end*/
            
            return params;
        }
    
    
      public FolderRingAnimator(Launcher launcher, FolderIcon folderIcon) {
             ....
                    sSharedOuterRingDrawable = res.getDrawable(R.drawable.bg_rect);
                    sSharedInnerRingDrawable = res.getDrawable(R.drawable.bg_rect);
                    sSharedFolderLeaveBehind = res.getDrawable(R.drawable.bg_rect);  //此处替换文件夹托动处形成动画的图片 
                
          ...
                }
            }
    
    

    7.Launcher修改成单层删除了google搜索无法显示删除APP按钮

    问题3将google搜索return 成了null, 为了不占位置并且将他的高度修改成了0
    所以导致了APP删除按钮的不显示
    原因是google搜索包含了APP删除的按钮

    所以现将问题3修改回来
    Launcher.java

     public View getQsbBar() {
       ...
          if (widgetId != -1) {
                    if (true) {   //chc  edit isSmallLandTablet()  to  true  这个是判断searchView 的加载模式
                                    // 改成true是默认让他直接加载不要动态加载
                        mQsbView = getLayoutInflater().inflate(R.layout.qsb, mSearchDropTargetBar, false);  
                    ..
                    } else {
                        mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);                                  
                    }
                        ///M.
                    }
      }
    

    修改qsb.xml

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
         android:background="#00000000">  <!--chc eidt  修改背景为透明-->
       <!-- Global search icon -->
       <ImageView
            android:id="@+id/search_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:scaleType="center"
            android:visibility="gone"   <!--chc eidt  隐藏-->
            android:src="@drawable/ic_home_search_normal_holo"
            android:adjustViewBounds="true" />
    
        <!-- Voice search icon -->
        <ImageView
            android:id="@+id/voice_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:scaleType="center"
            android:src="@drawable/ic_home_voice_search_holo"
            android:adjustViewBounds="true"
            android:visibility="gone" <!--chc eidt  隐藏-->
            />
    </LinearLayout>
    

    修改完成删除App按钮可能会有点大
    为了整体美观
    修改问题3的search的高度进行适当调整
    此问题结束

    8.将安装的APP拖动至删除APP按钮 无法显示删除对话框,并且删除后重启有会还原

    原因是将安装的APP 进行删除流程的时候判断成了Weight,所以导致删不了,并且不能弹出删除对话框

    修改Launcher的加载模式进行对安装的APP进行flag标记
    LauncherModel.java

    private boolean loadWorkspace(){
     ...
    while (!mStopped && c.moveToNext()) {
    ...
    if (info != null) {
                  //add by chc
             if(intent.getAction() != null && intent.getAction().equals(Intent.ACTION_MAIN)){
         try {
                                           
            final String packageName = intent.getComponent().getPackageName();
            //List<LauncherActivityInfoCompat> app = mLauncherApps.getActivityList(packageName, user);
            PackageInfo pi = manager.getPackageInfo(packageName, 0);
            if (!pi.applicationInfo.enabled) {
                // If we return null here, the corresponding item will be removed from the launcher
                // db and will not appear in the workspace.
                //return null;
                }
                                      
            final int appFlags = manager.getApplicationInfo(packageName, 0).flags;
            if ((appFlags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) {
                    info.flags |= AppInfo.DOWNLOADED_FLAG;                        
                if ((appFlags & android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
                        info.flags |= AppInfo.UPDATED_SYSTEM_APP_FLAG;
                    }
                }
                //  info.firstInstallTime = manager.getPackageInfo(packageName, 0).firstInstallTime;
        } catch (NameNotFoundException e) {
            Log.d(TAG, "getPackInfo failed for componentName " + intent.getComponent());
                //return null;
        }
    }
       // chc  add end
    }
    
    }
    

    DeleteDropTarget.java
    这里面是对删除的流程,在这里判断是否是安装的App,如果是安装的 就调用startApplicationUninstallActivity()进行删除

    private void completeDrop(DragObject d) {
        if (isAllAppsApplication(d.dragSource, item)) {
        }
        ...
        else if (isWorkspaceOrFolderApplication(d)) {
         / /chc add if the dragview is install app that this methed will uninstalled else the shutcut delete it 
                 if(item.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT){
                     ShortcutInfo shortcut = (ShortcutInfo) item;
                     final UserHandleCompat user = shortcut.user;
                     final ComponentName componentName = shortcut.intent.getComponent();
                     mLauncher.startApplicationUninstallActivity(componentName, shortcut.flags, user);
                   }else{
                       LauncherModel.deleteItemFromDatabase(mLauncher, item);
                   }
                  //chc add end 
        }
    
    }
    
    

    此问题到此结束

    9.将hotSeat中间图标变大 两边的缩小

    CellLayout.java

     public boolean addViewToCellLayout(View child, int index, int childId, LayoutParams params,
                boolean markCells) {
           ...
            child.setScaleX(getChildrenScale());
            child.setScaleY(getChildrenScale());
            /*chc add */
            if(mIsHotseat){
                Log.d("cuihangchao","childId"+childId);
                if(lp.cellX!=1){
                 child.setScaleX(0.8f);
                    child.setScaleY(0.8f);
                }
            }
            /*chc end*/
    
            // Generate an id for each view, this assumes we have at most 256x256 cells
         ...
            return false;
        }
    

    在此处判断hotseat是否是Hotseat上面的图标
    然后根据ID, 将需要变动的进行响应的缩放
    这样修改完成之后还有坑
    会将大图标拖动到小图标上,或进行大图渲染,无法变成小图。重启后会还原。

    最终修改方案
    ShortcutAndWidgetContainer.java

    @Override
        protected void dispatchDraw(Canvas canvas) {
            @SuppressWarnings("all") // suppress dead code warning
            final boolean debug = false;
           /*chc add */
            for (int i = getChildCount() - 1; i >= 0; i--) {
                    final View child = getChildAt(i);           
                    final CellLayout.LayoutParams lps = (CellLayout.LayoutParams) child.getLayoutParams();
                    if(mIsHotseatLayout){   
                    if(lps.cellX!=1){
                        child.setScaleX(0.7f);
                        child.setScaleY(0.7f);
                    }
                }           
            }
            /*chc end*/ 
                                        
            if (debug) {
                // Debug drawing for hit space
                Paint p = new Paint();
                p.setColor(0x6600FF00);
                for (int i = getChildCount() - 1; i >= 0; i--) {
                    final View child = getChildAt(i);
                    final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
    
                    canvas.drawRect(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height, p);
                }
            }
            super.dispatchDraw(canvas);
        }
    

    拖动的时候会不停的进入此方法,
    所以在此方法里面进行判断,
    将不会影响到渲染的效果

    改这个问题的时候踩了好多的坑。
    哎,踩了好多的坑

    此问题到此结束

    大概上面的修改launcher 的样子


    Launcher3 5.1 客制化定制问题修改(更新7.0MTK和高通的修改)

    MTK 7.0 Launcher3修改单层桌面

    2.1删除Google搜索(packages\apps\Launcher3\res\values\dimens.xml )

     <dimen name="dynamic_grid_search_bar_height">6dp</dimen>  //留下 (卸载 移除 的高度,因为搜索和他们是包含的) 
    

    Launcher.xml(注意找到对应分辨率)

    
     <include
               android:id="@+id/search_drop_target_bar"
               android:background="#00000000"
               layout="@layout/search_drop_target_bar"
           android:visibility="gone"
      /> 
    

    com/android/launcher3/SearchDropTargetBar

     @Override
        public void onDragStart(DragSource source, Object info, int dragAction) {
            animateToState(State.DROP_TARGET, DEFAULT_DRAG_FADE_DURATION);          
              this.setVisibility(View.VISIBLE);  //拖动的时候将自己显示
              mQSB.setVisibility(View.GONE); //将QSB隐藏
             
        }
    
    
     @Override
        public void onDragEnd() {
            if (!mDeferOnDragEnd) {
                animateToState(State.SEARCH_BAR, DEFAULT_DRAG_FADE_DURATION);
            } else {
                mDeferOnDragEnd = false;
            }
           this.setVisibility(View.GONE);  //拖动结束的时候将自己隐藏
        }
    
     public void enableAccessibleDrag(boolean enable) {
            if (mQSB != null) {
                mQSB.setVisibility(View.GONE);  //直接将qsb自己隐藏,
            }
            mInfoDropTarget.enableAccessibleDrag(enable);
            mDeleteDropTarget.enableAccessibleDrag(enable);
            mUninstallDropTarget.enableAccessibleDrag(enable);
        }
    
    
    
    

    删除移除按钮,单层桌面不需要移除
    com/android/launcher3/DeleteDropTarget

    @Override
        protected boolean supportsDrop(DragSource source, Object info) {
              if (info instanceof ShortcutInfo) {
                    ShortcutInfo item = (ShortcutInfo) info;            
                    return item.itemType !=           LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION;
                }
                      
              return info instanceof LauncherAppWidgetInfo;
        
            //return source.supportsDeleteDropTarget() && supportsDrop(info);
        }
    到此,搜索就移除了,但是不影响拖动可卸载的应用进行卸载
    

    2.2 将所有的应用加载到Workspace

    /*chc add*/ 
        public void customBindWorkspaceItems() {
                final Context context = mApp.getContext();
                ArrayList<ItemInfo> tmpInfos;
                ArrayList<ItemInfo> added = new ArrayList<ItemInfo>();
                synchronized (sBgLock) {
                    for (AppInfo app : mBgAllAppsList.data) {
                        tmpInfos = getItemInfoForComponentName(app.componentName, app.user);
                        if (tmpInfos.isEmpty()) {
                            // We are missing an application icon, so add this to the workspace
                            if(app.itemType!=LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) { //不进行加载xml配置的Item
                                Log.d("Cuihangchao","app.title="+app.title);
                               added.add(app);
                            }
                            // This is a rare event, so lets log it
                            Log.e(TAG, "Missing Application on load: " + app);
                        }
                    }
                    if (!added.isEmpty()) {
                        addAndBindAddedWorkspaceItems(context,added);  //添加到Workspace
                    }
                }
        
        }
    
    
    LoaderTask的run()进行添加 
    
     public void run() {
                synchronized (mLock) {
              ...
                keep_running: {
                    if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace");
                    loadAndBindWorkspace();
    
                    if (mStopped) {
                        LauncherLog.d(TAG, "LoadTask break in the middle, this = " + this);
                        break keep_running;
                    }
    
                    waitForIdle();
    
                    // second step
                    if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps");
                    loadAndBindAllApps();
    
                    customBindWorkspaceItems();//chc add
                }
      3.新的应用安装增加到workspace
    
      PackageUpdatedTask 的run
      
      ...
    public void run() {
                synchronized (mLock) {
         if (added != null) {
                    
            final ArrayList<ItemInfo> addedInfos = new ArrayList<ItemInfo>(added); //chc add
                    addAndBindAddedWorkspaceItems(context, addedInfos);//chc add
                    
                    addAppsToAllApps(context, added);
                    for (AppInfo ai : added) {
                        addedOrUpdatedApps.put(ai.componentName, ai);
                    }
                }
    ...
    }
    
    到此,所有的应用都会加载到Workspace上面,不影响预制XML里面的应用进行重复加载    
    

    2.3删除Allapp按钮

    void resetLayout() {
            mContent.removeAllViewsInLayout();
    
            if(false){  //chc add 大家可以自己定义宏
                // Add the Apps button
                Context context = getContext();
    
                LayoutInflater inflater = LayoutInflater.from(context);
                TextView allAppsButton = (TextView)
                        inflater.inflate(R.layout.all_apps_button, mContent, false);
                Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon);
    
                mLauncher.resizeIconDrawable(d);
                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));
                allAppsButton.setOnKeyListener(new HotseatIconKeyEventListener());
                if (mLauncher != null) {
                    mLauncher.setAllAppsButton(allAppsButton);
                    allAppsButton.setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
                    allAppsButton.setOnClickListener(mLauncher);
                    allAppsButton.setOnLongClickListener(mLauncher);
                    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(mAllAppsButtonRank);
                int y = getCellYFromOrder(mAllAppsButtonRank);
                CellLayout.LayoutParams lp = new CellLayout.LayoutParams(x,y,1,1);
                lp.canReorder = false;
                mContent.addViewToCellLayout(allAppsButton, -1, allAppsButton.getId(), lp, true);
            }
        }
    //修复Bug。快速扔图标 图标变灰,并且不消失
      DragController.java
    
    public boolean onTouchEvent(MotionEvent ev) {
      ...
    case MotionEvent.ACTION_UP:
                // Ensure that we've processed a move event at the current pointer location.
                handleMoveEvent(dragLayerX, dragLayerY);
                mHandler.removeCallbacks(mScrollRunnable);
    
                if (mDragging) {
                    //PointF vec = isFlingingToDelete(mDragObject.dragSource);  //检测是否是扔图标,                         
    
                    PointF vec=null;// 删除扔图标操作,
                    if (!DeleteDropTarget.supportsDrop(mDragObject.dragInfo)) {
                        vec = null;
                    }
                    Log.d("Cuihangchao","vec="+vec);
                    if (vec != null) {
                        dropOnFlingToDeleteTarget(dragLayerX, dragLayerY, vec);
                    } else {
                        drop(dragLayerX, dragLayerY);
                    }
                }
                endDrag();
    ...
    }
      
    
    

    到此,7.0的Launcher3就改成单层的了

    附8.1修改https://blog.csdn.net/qq_30552095

    此文会持续更新,有做Launcher的朋友可以参考参考

    相关文章

      网友评论

        本文标题:Launcher3 5.1 客制化定制问题修改(更新7.0MTK

        本文链接:https://www.haomeiwen.com/subject/dqbyvttx.html