上篇博客是如何把allapp放到workspace中,但是遗留了几个问题:
a.有app变化时,更新workspace;
b.隐藏allapp;
c.去掉长按时的删除选项。
这篇博客会解决这几个问题:
src/com/android/launcher3/model/PackageUpdatedTask.java -> execute():
......
final ArrayList addedOrModified = new ArrayList<>();
addedOrModified.addAll(appsList.added);
appsList.added.clear();
addedOrModified.addAll(appsList.modified);
appsList.modified.clear();
//更新begin
ArrayList.PendingInstallShortcutInfo> items = new ArrayList<>();
synchronized (this) {
for (AppInfo ai : addedOrModified) {
Intent data = ai.getIntent();
data.putExtra(Intent.EXTRA_SHORTCUT_INTENT, data);
data.putExtra(Intent.EXTRA_SHORTCUT_ICON, ai.iconBitmap);
data.putExtra(Intent.EXTRA_SHORTCUT_NAME, ai.title);
InstallShortcutReceiver.PendingInstallShortcutInfo info = new InstallShortcutReceiver.PendingInstallShortcutInfo(
data, ai.user, context);
items.add(info);
}
}
if (!items.isEmpty()) {
app.getModel().addAndBindAddedWorkspaceItems(
new InstallShortcutReceiver.LazyShortcutsProvider(context.getApplicationContext(), items));
}
//更新end
final ArrayList removedApps = new ArrayList<>(appsList.removed);
appsList.removed.clear();
......
这里比较复杂,我用的方法简单粗暴;首先将展示allapp的地方注释
src/com/android/launcher3/Launcher.java -> showAppsView():
/**
* Shows the apps view.
*/
public void showAppsView(boolean animated, boolean updatePredictedApps) {
// markAppsViewShown();
// if (updatePredictedApps) {
// tryAndUpdatePredictedApps();
// }
// showAppsOrWidgets(State.APPS, animated);
}
把方法内的代码全部注释;但是还没结束,因为这个时候你会发现在launcher中上滑还是能调出allapp的,于是又查看touch事件的调用地方,最终找到了是在AllAppsTransitionController.java这个类里面
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);
//把调用的地方注释 bengin
// setProgress(shift / mShiftRange);
//把调用的地方注释 end
return true;
}
做完这两步,allapp终于不出现了,但是这个时候还有问题,因为HotSeat上面一点,还有有一个向上的箭头,并且在launcher的onResume状态时,HotSeat和这个箭头会一起做一个向上跳动的动画;
这个肯定也是要去掉的,于是又去找动画的代码,用Hierarchy View工具找到箭头的View是PageIndicatorLineCaret.java,于是以这个为切入点,找了很久都没有找到地方,这个时候果断出去抽了根烟,抽烟的过程中猛然想起这个动画的效果应该是用BounceInterpolator来做的(这里装个13 ^_^),于是在代码中查找,发现在AllAppsTransitionController.java这个类中有showDiscoveryBounce()这个方法
public void showDiscoveryBounce() {
// cancel existing animation in case user locked and unlocked at a super human speed.
cancelDiscoveryAnimation();
// assumption is that this variable is always null
mDiscoBounceAnimation = AnimatorInflater.loadAnimator(mLauncher,
R.animator.discovery_bounce);
mDiscoBounceAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
mIsTranslateWithoutWorkspace = true;
preparePull(true);
}
@Override
public void onAnimationEnd(Animator animator) {
finishPullDown();
mDiscoBounceAnimation = null;
mIsTranslateWithoutWorkspace = false;
}
});
mDiscoBounceAnimation.setTarget(this);
mAppsView.post(new Runnable() {
@Override
public void run() {
if (mDiscoBounceAnimation == null) {
return;
}
mDiscoBounceAnimation.start();
}
});
}
查看调用的地方,是在
src/com/android/launcher3/Launcher.java -> onResume():
将调用的地方注释:
......
if (shouldShowDiscoveryBounce()) {
//注释 begin
// mAllAppsController.showDiscoveryBounce();
//注释 end
}
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onResume();
}
......
最后把箭头去掉,因为调用地方比较多,我就直接把Imageview的图片设置为空了
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);
}
终于把这个搞定了!
现在所有应用都已经在workspace中了,并且allapp也已经隐藏,但是长按workspace中的APP会发现,可以 移除,这个肯定不是我们需要的,我们需要的是卸载
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;
}
......
}
到这里就基本可以了。
但是还有遗留问题:
a.HotSeat中出现过的APP在Workspace仍然有;
b.HotSeat可以创建文件夹
革命尚未成功,苦逼的程序员晚上继续研究!