美文网首页
一级桌面修改

一级桌面修改

作者: 奥利奥真好吃 | 来源:发表于2018-03-09 11:00 被阅读0次

Android的默认设计中桌面Launcher采用的是抽屉式的二级桌面样式,而在实际中大部分人都在使用的是小米式的一级桌面,我们这里使用Android6.0的源码做一个类似的修改。

首先分析一下怎么做,其它也很简单,无非就是将一级桌面workspace上没有的图标从二级桌面上挪上去,同时删除一级桌面上的“所有程序”菜单。然后要避免和解决的问题是在新的APP添加时,使图标自动添加到IDLE界面,而在长按APP图标时桌面上显示的是卸载而不是删除,同时针对某些APP首次启动会自动生成快捷方式的情况要避免图标的重复。

下面是具体的实现过程(在Android5.1上有类似的整体设计,不过并不完整)
config.xml中增加一个总的控制开关:

<bool name="config_isDisableAllApps">true</bool>

LauncherAppState.java中读取该参数:

public static boolean isDisableAllApps(){
    return sContext.getResources().getBoolean(R.bool.config_isDisableAllApps);
}

DeleteDropTarget.java中确定是否支持删除

    public static boolean supportsDrop(Object info) {
        if(LauncherAppState.isDisableAllApps()){
            if(info instanceof ShortcutInfo){
                ShortcutInfo shortcut=(ShortcutInfo)info;
                return shortcut.itemType!=LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION;
            }else
                return info instanceof LauncherAppWidgetInfo;
        }else{
            return (info instanceof ShortcutInfo)
                    || (info instanceof LauncherAppWidgetInfo)
                    || (info instanceof FolderInfo);
        }
    }

InfoDropTarget.java中确定是否支持查看应用信息

    @Override
    protected boolean supportsDrop(DragSource source, Object info) {
        if(LauncherAppState.isDisableAllApps()){
            if (info instanceof ShortcutInfo){
                ShortcutInfo shortcut=(ShortcutInfo)info;
                return shortcut.itemType==LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION;
            }else{
                return false;
            }
        }else{
            return source.supportsAppInfoDropTarget() && supportsDrop(getContext(), info);
        }
    }

UninstallDropTarget.java中确定是否支持卸载

    @Override
    protected boolean supportsDrop(DragSource source, Object info) {
        //zyl add 20180201
        if(LauncherAppState.isDisableAllApps()){
            if(info instanceof ShortcutInfo){
                ShortcutInfo shortcut=(ShortcutInfo)info;
                if(Utilities.isSystemApp(getContext(), shortcut.getIntent()))
                    return false;
                else
                    return shortcut.itemType==LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION;
            }else{
                return false;
            }
        }else{
            return supportsDrop(getContext(), info);
        }    
    }

Hotseat.java中删除中间的“所有程序”

    public boolean isAllAppsButtonRank(int rank) {
        //zyl modify 20180228
        if(LauncherAppState.isDisableAllApps())
            return false;
        else
            return rank == mAllAppsButtonRank;
    }
    void resetLayout() {
        mContent.removeAllViewsInLayout();
        //zyl add 20180228
        if(!LauncherAppState.isDisableAllApps()){
            // 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);
        }

InvariantDeviceProfile.java中重新选择新的workspace的xml文件并且删除针对Hotseat中图标个数的合法性检查

    //zyl add 20180228
    private boolean hasDA=LauncherAppState.isDisableAllApps();
        
    //zyl modify 20180228
    if (hs % 2 == 0&&!hasDA) {
       throw new RuntimeException("All Device Profiles must have an odd number of hotseat spaces");
    }

    ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles() {
        ArrayList<InvariantDeviceProfile> predefinedDeviceProfiles = new ArrayList<>();
        // width, height, #rows, #columns, #folder rows, #folder columns,
        // iconSize, iconTextSize, #hotseat, #hotseatIconSize, defaultLayoutId.
        
        //zyl modify 20180228
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Super Short Stubby",
                255, 300,     2, 3, 2, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_3x3));
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Shorter Stubby",
                255, 400,     3, 3, 3, 3, 3, 48, 13, 3, 48, R.xml.default_workspace_3x3));
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Short Stubby",
                275, 420,     3, 4, 3, 4, 4, 48, 13, hasDA?4:5, 48, R.xml.default_workspace_4x4));
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Stubby",
                255, 450,     3, 4, 3, 4, 4, 48, 13, hasDA?4:5, 48, R.xml.default_workspace_4x4));
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus S",
                296, 491.33f, 4, 4, 4, 4, 4, 48, 13, hasDA?4:5, 48, R.xml.default_workspace_4x4));
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 4",
                359, 567,     4, 4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, hasDA?4:5, 56, R.xml.default_workspace_4x4));
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 5",
                335, 567,     4, 4, 4, 4, 4, DEFAULT_ICON_SIZE_DP, 13, hasDA?4:5, 56, R.xml.default_workspace_4x4));
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Large Phone",
                406, 694,     5, 5, 4, 4, 4, 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
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 7",
                575, 904,     5, 6, 4, 5, 4, 72, 14.4f,  7, 60, R.xml.default_workspace_5x6));
        // Larger tablet profiles always have system bars on the top & bottom
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("Nexus 10",
                727, 1207,    5, 6, 4, 5, 4, 76, 14.4f,  7, 76, R.xml.default_workspace_5x6));
        predefinedDeviceProfiles.add(new InvariantDeviceProfile("20-inch Tablet",
                1527, 2527,   7, 7, 6, 6, 4, 100, 20,  7, 72, R.xml.default_workspace_5x6));
        return predefinedDeviceProfiles;
    }

由于我们修改了在一级桌面上支持查看应用信息,而默认的是从二级桌面拖动到一级桌面上方的信息栏进行查看,这里因为动画的原因会造成图标卡死在信息栏上,我们需要在Workspace.java中消除有关的动画

public void onDropCompleted(final View target, final DragObject d,
            final boolean isFlingToDelete, final boolean success) {
        if (LauncherLog.DEBUG) {
            LauncherLog.d(TAG, "onDropCompleted: target = " + target + ", d = " + d
                    + ", isFlingToDelete = " + isFlingToDelete + ", mDragInfo = "
                    + mDragInfo + ", success = " + success);
        }
        //zyl add 20180228
        if(LauncherAppState.isDisableAllApps()){
            if(target instanceof InfoDropTarget){
                mDragController.cancelDrag();
                return;
            }
        }
        ...
}

如果有APP请求添加新的快捷方式,我们要排除重复的情况,修改InstallShortcutReceiver.java,添加一个判断的方法

    //zyl add 20180228
    public static boolean verifyShortcut(PendingInstallShortcutInfo pendingInfo){
        String installPackageName,installClassName; 
        try{            
            installPackageName=pendingInfo.getShortcutInfo().getIntent().getComponent().getPackageName();       
            installClassName=pendingInfo.getShortcutInfo().getIntent().getComponent().getClassName();   
        }catch(NullPointerException ex){        
            Log.i(TAG,"NullPointerException");  
            return false;           
        }                   
        String mPackageName,mClassName; 
        ShortcutInfo mShortCut;             
        Intent mIntent;             
        LauncherAppState app = LauncherAppState.getInstance();      
        synchronized (app.getModel().sBgLock) {     
            for(ItemInfo minfo:LauncherModel.sBgItemsIdMap){    
                if (minfo instanceof ShortcutInfo) {    
                    Log.i(TAG,"iteminfo="+minfo);   
                    mShortCut=(ShortcutInfo)minfo;      
                    mIntent=mShortCut.getIntent();      
                    mPackageName=mIntent.getComponent().getPackageName();   
                    mClassName=mIntent.getComponent().getClassName();           
                    if(installPackageName.equals(mPackageName)&&installClassName.equals(mClassName)){       
                        return true;                
                    }               
                }           
            }               
        }
        return false;
    }

在 static void flushInstallQueue(Context context) 方法中做判断

    //zyl add 20180228
    if(LauncherAppState.isDisableAllApps()){
        if(verifyShortcut(pendingInfo))
            return;
    }

最关键的是将Workspace上没有的APP添加上去,修改LauncherModel.java中LoaderTask部分,在加载完所有应用后进行判断,实际上我们并不是不执行加载二级桌面的操作,只是不显示

            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();
                
                //zyl add 20180228
                if(LauncherAppState.isDisableAllApps()){
                    verifyApplications();
                }
            }

添加新的方法verifyApplications()

        //zyl add 20180228
        private void verifyApplications() {
                final Context context = mApp.getContext();

                // Cross reference all the applications in our apps list with items in the workspace
                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
                            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);
                }
        }

另外既然只有一级桌面,那当一个APP被卸载后,我们一般希望图标会自动排列,而不是空出来,我们添加一个算法来修改数据库

    //zyl add 20180228
    private void changeItemFromDatabase(Context context,final ArrayList<ItemInfo> items){
        int cellX=0, cellY=0;
        int screenId;   
        for (ItemInfo item : items){
            screenId=(int)item.screenId;  
            LauncherAppState app = LauncherAppState.getInstance();
            InvariantDeviceProfile profile = app.getInvariantDeviceProfile();
            final int xCount = (int) profile.numColumns;
            ArrayList<ItemInfo> changeditems =new ArrayList<ItemInfo>();       
            for (ItemInfo i : sBgWorkspaceItems){
                if (i.container == LauncherSettings.Favorites.CONTAINER_DESKTOP){   
                    if(screenId == i.screenId && i.cellY>=item.cellY ){  
                        if(i.cellY==item.cellY && i.cellX>item.cellX){
                            cellX = i.cellX-1;
                            cellY = i.cellY;
                        }else if(i.cellY>item.cellY){
                                if(i.cellX==0){
                                    cellX = xCount-1;
                                    cellY = i.cellY-1;
                                }else{
                                    cellX = i.cellX -1;
                                    cellY = i.cellY;
                                }
                        }else{
                            cellX = i.cellX;
                            cellY = i.cellY;
                        }
                        i.cellX = cellX; 
                        i.cellY = cellY;
                        changeditems.add(i);    
                    }
                }
            }
            moveItemsInDatabase(context, changeditems, item.container, screenId);  
        }       
    }

还是LauncherModel.java,PackageUpdatedTask中做修改

          if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) {
                for (String pn : removedPackages) {
                    //zyl add 20180228
                    if(LauncherAppState.isDisableAllApps()){
                        changeItemFromDatabase(context,getItemsByPackageName(pn,mUser));
                    }
                    deletePackageFromDatabase(context, pn, mUser);
                }
                ...

此外,我们顺便将workspace上边距减小(删除QSB后Idle上方留白过多),修改DeviceProfile.java的getWorkspacePadding方法

            ...
            } else {
                // Pad the top and bottom of the workspace with search/hotseat bar sizes
                padding.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left,
                        2*edgeMarginPx,//zyl modify 20180228    
                        desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.right,
                        paddingBottom);
            }
            ...

同时调整参数文件dimens.xml

    <dimen name="dynamic_grid_search_bar_height">25dp</dimen> <!--zyl modify 20180228-->
    <!-- We want 46dp extra for the tall search bar. -->
    <dimen name="dynamic_grid_search_bar_height_tall">94dp</dimen>
    <dimen name="qsb_internal_padding_top">0dp</dimen>  <!--zyl modify 20180228-->
    <dimen name="qsb_internal_padding_bottom">0dp</dimen>   <!--zyl modify 20180228-->

这样我们的一级桌面就成形了,不会有其它什么问题。

相关文章

  • 一级桌面修改

    Android的默认设计中桌面Launcher采用的是抽屉式的二级桌面样式,而在实际中大部分人都在使用的是小米式的...

  • windows开启及连接远程桌面

    桌面 -> 此电脑 图标右键 -> 属性 远程设置 远程桌面 -> 修改为允许远程连接到此计算机 修改远程桌面连接...

  • 修改windows远程桌面服务监听端口

    可以使用reg命令修改windows注册表内容,本文以修改windows远程桌面服务监听端口为例。修改远程桌面服务...

  • 修改桌面路径

    刚开始用“怎么把桌面改为其他盘”来搜索,出现的都是在regedit里修改桌面路径,但根本就修改不成功。后来重新用“...

  • ubuntu安装之后的一些事

    1、修改软件源 这里使用桌面版的修改方式,设置步骤如下:System Settings —> Software&U...

  • Android源码发开记录-持续更新

    记录一些做过容易忘的源码修改开发记录,排名不分前后。 ●系统UI修改,包括SystemUI 1、修改桌面壁纸:a)...

  • 如何配置Mac的Host

    桌面——前往——前往文件夹—输入:/etc/hosts 双击修改,OK了!

  • 替换windows桌面与普通U盘禁止连接

    因公司业务需要,需要替换windows桌面为自己程序,并且禁止普通U盘连接电脑。 替换windows桌面 修改注册...

  • Mybatis中使用二级缓存

    一级缓存默认存在 一级缓存是SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,comm...

  • iOS 添加垃圾代码

    修改垃圾代码的输出路径,可以在自己的桌面上

网友评论

      本文标题:一级桌面修改

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