Launcher3去掉抽屉模式

目前接收到一个需求,因为是小屏手机,需要修改为4宫格模式,去掉抽屉,将所有应用展示在一级页面。

1、加入开关

Launcher3\src\com\android\launcher3\LauncherAppState.java

添加一个方法

 public static boolean isDisableAllApps() {
        return true;
    }

2、allapp键的加载

 在hotseat里面去掉allapp键的加载 ,屏蔽isallappsbuttonrank()占用allapp位置。

1)不再占用allapp位置

2)在加载workspace时,会留出hotseat的第三个位置给allapp按钮,若不取消该位置的占用,在hotseat加载时会留出空位。

hotseat的初始化在Launcher3\src\com\android\launcher3\InvariantDeviceProfile.java中的

isAllAppsButtonRank()中。在6.0中,这个方法是在HotSeat.java中

public boolean isAllAppsButtonRank(int rank) {
        if (LauncherAppState.isDisableAllApps()) {
            return false;
        }
        return rank == getAllAppsButtonRank();
    }

3)在HoSeat里面去掉AllApp键的布局加载

Launcher3\src\com\android\launcher3\HotSeat.java –>resetLayout():

void resetLayout() {
        mContent.removeAllViewsInLayout();
        //添加判断
        if (LauncherAppState.isDisableAllApps()) {
            return;
        }

        if (!FeatureFlags.NO_ALL_APPS_ICON) {
            // Add the Apps button
            Context context = getContext();
            DeviceProfile grid = mLauncher.getDeviceProfile();
            int allAppsButtonRank = grid.inv.getAllAppsButtonRank();
        ......
}

4)将所有应用放到第一层

Launcher3\src\com\android\launcher3\model\LoaderTask.java ->run()

 // second step
 if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps");
      loadAllApps();
      /*launcher single-deck start*/
      //添加查找APP
      if (LauncherAppState.isDisableAllApps()) {
          loadAllApplications();
      }
       /*launcher single-deck end*/

在这个地方调用loadAllApplications是因为,只有当应用数据加载完全后,我们才能将所有应用绑定到第一层中。

新增loadAllApplications方法

private void loadAllApplications() {
	final Context context = mApp.getContext();
    final List profiles = mUserManager.getUserProfiles();
    Log.d("wangjin","LoaderTask loadAllApplications");
    for (UserHandle user : profiles) {
        final List apps = mLauncherApps.getActivityList(null, user);
        Log.d("wangjin","LoaderTask");
        ArrayList added = new ArrayList();
        synchronized (this) {
            for (LauncherActivityInfo app : apps) {
				 InstallShortcutReceiver.PendingInstallShortcutInfo pendingInstallShortcutInfo =  new InstallShortcutReceiver.PendingInstallShortcutInfo(app,context);
                 added.add(pendingInstallShortcutInfo);
                 Log.d("wangjin"," LoaderTask app ===== " + app);
                 }
            }
        if (!added.isEmpty()) {
             Log.d("wangjin","LoaderTask added = " + added);
             mApp.getModel().addAndBindAddedWorkspaceItems(new InstallShortcutReceiver.LazyShortcutsProvider(context.getApplicationContext(), added));
            }
    }
}

上面的代码考虑到多用户,拿到应用数据后,使用addAndBindAddedWorkspaceItems添加item。同时需要注意,需要将需要把InstallShortcutReceiver.PendingInstallShortcutInfo和InstallShortcutReceiver.LazyShortcutsProvider改为public。

按照上述修改后,仍然没有达到效果,发现AddWorkspaceItemsTask.java中的execute()方法没有执行,原因是BaseModelUpdateTask.java中run()中的判断问题,导致没有执行。

Launcher3/src/com/android/launcher3/model/BaseModelUpdateTask.java ->run中将return注释掉

    public final void run() {
        if (!mModel.isModelLoaded()) {
            if (DEBUG_TASKS) {
                Log.d(TAG, "Ignoring model task since loader is pending=" + this);
            }
            // Loader has not yet run.
            //return;
        }
        execute(mApp, mDataModel, mAllAppsList);
    }

3、有app变化时更新workspace

Launcher3/com/android/launcher3/model/PackageUpdatedTask.java -> execute():

        addedOrModified.addAll(appsList.added);
		
		final List profiles = UserManagerCompat.getInstance(context).getUserProfiles();
		ArrayList added = new ArrayList();
		for (UserHandle user : profiles) {
			final List apps = LauncherAppsCompat.getInstance(context).getActivityList(null, user);
			
			synchronized (this) {
				for (LauncherActivityInfo info : apps) {
						for (AppInfo appInfo : appsList.added) {
							if(info.getComponentName().equals(appInfo.componentName)){
								InstallShortcutReceiver.PendingInstallShortcutInfo mPendingInstallShortcutInfo =  new InstallShortcutReceiver.PendingInstallShortcutInfo(info,context);
								added.add(mPendingInstallShortcutInfo);
							}
						}
				}
			}
		}
        if (!added.isEmpty()) {
			Log.d("wangjin","PackageUpdatedTask.java ------------------------");
            app.getModel().addAndBindAddedWorkspaceItems(new InstallShortcutReceiver.LazyShortcutsProvider(context.getApplicationContext(), added));
        }
		
        appsList.added.clear();

这里添加的代码和LoaderTask.java中一样,重新加载app数据。

4、隐藏allapp

1)将展示allapp的地方注释

src/com/android/launcher3/Launcher.java -> showAppsView():

    public void showAppsView(boolean animated, boolean updatePredictedApps) {
		/**/
    }

2)去掉上滑唤出抽屉手势

src/com/android/launcher3/allapps/AllAppsTransitionController.java -> onDrag():

    @Override
    public boolean onDrag(float displacement, float velocity) {
        if (mAppsView == null) {
            return false;   // early termination.
        }

        mContainerVelocity = velocity;

        float shift = Math.min(Math.max(0, mShiftStart + displacement), mShiftRange);
        //把调用的地方注释掉 begin
        //setProgress(shift / mShiftRange);
        //把调用的地方注释掉 end
        return true;
    }

3)移除Launcher向上跳动动画

在HotSeat上面一点,有一个向上的箭头,在Launcher的onResume状态时,HotSeat和箭头会一起做一个向上跳动的动画。

动画效果是用BounceInterpolator,在AllAppsTransitionController.java这个类中有showDiscoveryBounce()这个方法

查看调用的地方,是在 
src/com/android/launcher3/Launcher.java -> onResume(): 
将调用的地方注释:

        if (shouldShowDiscoveryBounce()) {
            //mAllAppsController.showDiscoveryBounce();
        }

4)去掉箭头

src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java -> onFinishInflate()

@Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mAllAppsHandle = (ImageView) findViewById(R.id.all_apps_handle);
//修改 begin
//        mAllAppsHandle.setImageDrawable(getCaretDrawable());
        mAllAppsHandle.setImageDrawable(null);
//修改 end
        mAllAppsHandle.setOnClickListener(mLauncher);
        mAllAppsHandle.setOnFocusChangeListener(mLauncher.mFocusHandler);
        mLauncher.setAllAppsButton(mAllAppsHandle);
    }

5、将长按移除修改为删除

此时所有应用都已经在workspcae中,allapp也已经隐藏,但是长按图标出现的是移除而不是卸载

Launcher3/src/com/android/launcher3/DeleteDropTarget.java 

   @Override
    protected boolean supportsDrop(DragSource source, ItemInfo info) {
//添加判断 begin
        if (info instanceof ShortcutInfo || info instanceof FolderInfo) {
            return false;
        }
//添加判断 end
        return true;
    }

src/com/android/launcher3/popup/PopupContainerWithArrow.java -> showForIcon():

public static PopupContainerWithArrow showForIcon(BubbleTextView icon) {
        Launcher launcher = Launcher.getLauncher(icon.getContext());
        if (getOpen(launcher) != null) {
            // There is already an items container open, so don't open this one.
            icon.clearFocus();
            return null;
        }
        ItemInfo itemInfo = (ItemInfo) icon.getTag();
//修改类型 begin
        itemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
//修改类型 end
        if (!DeepShortcutManager.supportsShortcuts(itemInfo)) {
            return null;
        }
        ......
}

参考资料:

https://blog.csdn.net/qq_30552095/article/details/80494770

https://blog.csdn.net/yxdspirit/article/details/84634454

你可能感兴趣的:(源码分析,Android之路)