SystemUI 调整Recents中全部清除按钮位置
Posted 虫师魁拔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SystemUI 调整Recents中全部清除按钮位置相关的知识,希望对你有一定的参考价值。
Recents 即多任务界面,显示最近使用过的APP List的。下面内容都是基于android 11平台修改的。Android 11上,Recents 这一部分代码其实都已经被挪到Launcher3中。由于个人习惯,所以将内容分类作为SystemUI部分记录。
多任务界面主要几个文件:
TaskView.java | app卡片 |
ClearAllButton.java | 全部清除Button |
OverviewActionsView.java | 多任务界面下方View,包含截图等按钮 |
RecentsView.java | 主界面,集成PageView,包含所有TaskView与ClearAllButton |
源码中,RecentsView 默认采用 Rtl 布局的方式(猜测这个设计是不是因为Recents按键一般在右下角,用户右手操作多,点进去RecentsView直接右滑更舒服)。界面整体布局如下图:
默认从左往右滑动,RecentsView 最后一个子View就是 ClearAllButton。我们尝试将 ClearAllButton 放置到 RecentsView 的第一位,做成如下效果。左滑直接可以点击清除,右滑查看历史APP卡片。
第一步,调整子View顺序。在 RecentsView.java 中,addView 时候换下顺序,先加载 ClearAllButton ,再去加载最新打开的 APP 的 TaskView 控件,最后加载历史 TaskView 控件。调整代码:
@@ -408,7 +408,8 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
private boolean mLiveTileOverlayAttached;
// Keeps track of the index where the first TaskView should be
- private int mTaskViewStartIndex = 0;
+ // 全部清除按钮放置在PageView的0位,TaskView 下标应该从1开始
+ private int mTaskViewStartIndex = 1;
private OverviewActionsView mActionsView;
private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener =
@@ -622,7 +623,8 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
if (!(affectingView instanceof TaskView) && !(affectingView instanceof ClearAllButton))
int childCount = getChildCount();
- mTaskViewStartIndex = 0;
+ // 全部清除按钮放置在PageView的0位,TaskView 下标应该从1开始
+ mTaskViewStartIndex = 1;
while (mTaskViewStartIndex < childCount
&& !(getChildAt(mTaskViewStartIndex) instanceof TaskView))
mTaskViewStartIndex++;
@@ -679,13 +681,17 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
@Override
protected void onPageBeginTransition()
super.onPageBeginTransition();
+ // 滑动开始的时候,会把截图按钮设置为禁用状态,防止误点击
+ android.util.Log.i("TA", "onPageBeginTransition true " + OverviewActionsView.DISABLED_SCROLLING);
mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, true);
@Override
protected void onPageEndTransition()
super.onPageEndTransition();
+ // 滑动结束的时候,如果isClearAllHidden为true(即当前不在全部清除按钮界面)。将截图按钮设置为可用状态
if (isClearAllHidden())
+ android.util.Log.i("TA", "onPageEndTransition false " + OverviewActionsView.DISABLED_SCROLLING);
mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, false);
if (getNextPage() > 0)
@@ -782,18 +788,20 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
final int requiredTaskCount = tasks.size();
if (getTaskViewCount() != requiredTaskCount)
- if (indexOfChild(mClearAllButton) != -1)
+ /*if (indexOfChild(mClearAllButton) != -1)
removeView(mClearAllButton);
-
+ */
+ //逐个添加TaskView到PageView
for (int i = getTaskViewCount(); i < requiredTaskCount; i++)
addView(mTaskViewPool.getView());
+ //全部清除Button提前到前面添加,保证是PageView的第0个Child View
+ /*if (requiredTaskCount > 0)
+ addView(mClearAllButton);
+ */
while (getTaskViewCount() > requiredTaskCount)
removeView(getChildAt(getChildCount() - 1));
- if (requiredTaskCount > 0)
- addView(mClearAllButton);
-
// Rebind and reset all task views
@@ -840,9 +848,10 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
public int getTaskViewCount()
int taskViewCount = getChildCount() - mTaskViewStartIndex;
- if (indexOfChild(mClearAllButton) != -1)
+ // mClearAllButton放置在0位了,所以taskViewCount直接 = getChildCount() - mTaskViewStartIndex,不用再--
+ /*if (indexOfChild(mClearAllButton) != -1)
taskViewCount--;
-
+ */
return taskViewCount;
@@ -854,7 +863,7 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
public void resetTaskVisuals()
for (int i = getTaskViewCount() - 1; i >= 0; i--)
TaskView taskView = getTaskViewAt(i);
- if (mIgnoreResetTaskId != taskView.getTask().key.id)
+ if (taskView.getTask() == null || taskView.getTask().key.id != mIgnoreResetTaskId)
taskView.resetViewTransforms();
taskView.setStableAlpha(mContentAlpha);
taskView.setFullscreenProgress(mFullscreenProgress);
@@ -955,6 +964,7 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
return;
mOrientationHandler.getCurveProperties(this, mInsets, mScrollState);
+ mScrollState.maxScroll = mMaxScroll;
mScrollState.scrollFromEdge =
mIsRtl ? mScrollState.scroll : (mMaxScroll - mScrollState.scroll);
@@ -1193,14 +1203,15 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
* is called. Also scrolls the view to this task.
*/
public void showCurrentTask(RunningTaskInfo runningTaskInfo)
- if (shouldAddDummyTaskView(runningTaskInfo))
- boolean wasEmpty = getChildCount() == 0;
- // Add an empty view for now until the task plan is loaded and applied
+ //全部清除Button提前到前面添加,保证是PageView的第0个Child View
+ if (indexOfChild(mClearAllButton) != -1)
+ removeView(mClearAllButton);
+
+ addView(mClearAllButton, 0);
+ if (shouldAddDummyTaskView(runningTaskInfo)) //有新增app
final TaskView taskView = mTaskViewPool.getView();
+ //添加最新的app taskview,是PageView的第1个Child View
addView(taskView, mTaskViewStartIndex);
- if (wasEmpty)
- addView(mClearAllButton);
-
// The temporary running task is only used for the duration between the start of the
// gesture and the task list is loaded and applied
mTmpRunningTask = Task.from(new TaskKey(runningTaskInfo), runningTaskInfo, false);
@@ -1381,6 +1392,8 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
*/
public float scrollFromEdge;
+ public float maxScroll;
+
/**
* Updates linearInterpolation for the provided child position
*/
@@ -2272,7 +2285,7 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
@Override
- protected int computeMinScroll()
+ protected int computeMinScroll() //获取最左边的范围
if (getTaskViewCount() > 0)
if (mDisallowScrollToClearAll)
// We aren't showing the clear all button,
@@ -2283,7 +2296,8 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
return getScrollForPage(mTaskViewStartIndex);
if (mIsRtl)
- return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
+ //获取可以滑动的范围,ClearAllButton换到0位后,最后一个就是 TaskView ,无需+1了
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
return getScrollForPage(mTaskViewStartIndex);
@@ -2291,20 +2305,21 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
@Override
- protected int computeMaxScroll()
+ protected int computeMaxScroll() //获取最右边的范围
if (getTaskViewCount() > 0)
if (mDisallowScrollToClearAll)
// We aren't showing the clear all button,
// so use the rightmost task as the min scroll.
if (mIsRtl)
- return getScrollForPage(mTaskViewStartIndex);
+ return getScrollForPage(0);
return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
if (mIsRtl)
- return getScrollForPage(mTaskViewStartIndex);
+ //获取可以滑动的范围,mTaskViewStartIndex当前是1,所以直接这里写死成0就行
+ return getScrollForPage(0);
- return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
return super.computeMaxScroll();
修改顺序后,会导致 ClearAllButton 是否显示的计算方法不匹配(默认是滑到最左边显示),导致 ClearAllButton 不显示。同时,OverviewActionsView 中截图功能也是根据 ClearAllButton 的状态判断当前能否显示截图。所以需要再调整下 ClearAllButton 的显示计算方法。
@@ -100,13 +102,16 @@ public class ClearAllButton extends Button implements PageCallbacks
float shift = Math.min(scrollState.scrollFromEdge, orientationSize);
float translation = mIsRtl ? (mScrollOffset - shift) : (mScrollOffset + shift);
orientationHandler.setPrimaryAndResetSecondaryTranslate(this, translation);
- mScrollAlpha = 1 - shift / orientationSize;
+ // 这里是左右滑动时候,按照View滑动的距离,确定clearAllbutton是否需要显示
+ mScrollAlpha = scrollState.maxScroll == scrollState.scrollFromEdge ? 1.0f : 0.0f;
updateAlpha();
private void updateAlpha()
final float alpha = mScrollAlpha * mContentAlpha * mVisibilityAlpha;
setAlpha(alpha);
+ // 根据mScrollAlpha(滑动参数)、mContentAlpha(是否存在)、mVisibilityAlpha(是否设置不可见)来确定clearAllbutton是否可见
+ android.util.Log.i("TA", "updateAlpha " + alpha);
setClickable(alpha == 1);
这里新加一个属性 scrollState.maxScroll 表示最大滑动范围值, scrollFromEdge 等于 maxScroll 时,表示滑到最右边了,此时是 ClearAllButton 界面,ClearAllButton 显示。其他界面就不显示了。
计算 ClearAllButton 显示方法上面这种的话,你是必须滑到最右边才行。如果在第一个APP卡片界面,是不显示,看着不太好看,如下图:
以上是关于SystemUI 调整Recents中全部清除按钮位置的主要内容,如果未能解决你的问题,请参考以下文章
Android系统之路(初识MTK) ------Android11.0添加Recents一键清除最近任务按钮
Android系统之路(初识MTK) ------Android11.0添加Recents一键清除最近任务按钮
Android系统之路(初识MTK) ------Android11.0添加Recents一键清除最近任务按钮
Android11 最近任务Recents功能分析,分析的很彻底