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功能分析,分析的很彻底

Android Launcher 在底部导航栏添加一个“☰”按钮,点击弹出全部应用

如果我按下“全部清除”按钮,为啥我的前台服务会停止