猿创征文|Android 11.0禁止抽屉式上滑显示app列表页

目录

1.概述

2.禁止抽屉式上滑显示app列表页的核心代码

3.禁止抽屉式上滑显示app列表页核心功能分析以及功能实现

3.1 AbstractStateChangeTouchController.java关于手势上滑弹出抽屉式的相关功能分析

3.2 PortraitStatesTouchController.java关于竖屏显示拖拽app列表的相关方法

3.3 LandscapeEdgeSwipeController.java关于横屏上滑显示app的相关功能分析


1.概述

在产品开发中,Launcher3中定制的功能也是特别多的,有功能需求要求禁止抽屉式上滑显示app列表页,也就是去掉抽屉式功能,这就需要分析上滑功能怎么 实现的,然后禁用相关代码就可以了

2.禁止抽屉式上滑显示app列表页的核心代码

packages/apps/Launcher3/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
packages/apps/Launcher3/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
packages/apps/Launcher3/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java

3.禁止抽屉式上滑显示app列表页核心功能分析以及功能实现

3.1 AbstractStateChangeTouchController.java关于手势上滑弹出抽屉式的相关功能分析

      public abstract class AbstractStateChangeTouchController
         implements TouchController, SingleAxisSwipeDetector.Listener {
 
     // Progress after which the transition is assumed to be a success in case user does not fling
     public static final float SUCCESS_TRANSITION_PROGRESS = 0.5f;
 
     /**
      * Play an atomic recents animation when the progress from NORMAL to OVERVIEW reaches this.
      */
     public static final float ATOMIC_OVERVIEW_ANIM_THRESHOLD = 0.5f;
     protected final long ATOMIC_DURATION = getAtomicDuration();
 
     protected final Launcher mLauncher;
     protected final SingleAxisSwipeDetector mDetector;
     protected final SingleAxisSwipeDetector.Direction mSwipeDirection;
 
     private boolean mNoIntercept;
     private boolean mIsLogContainerSet;
     protected int mStartContainerType;
 
     protected LauncherState mStartState;
     protected LauncherState mFromState;
     protected LauncherState mToState;
     protected AnimatorPlaybackController mCurrentAnimation;
     protected PendingAnimation mPendingAnimation;
 
     private float mStartProgress;
     // Ratio of transition process [0, 1] to drag displacement (px)
     private float mProgressMultiplier;
     private float mDisplacementShift;
     private boolean mCanBlockFling;
     private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
 
     protected AnimatorSet mAtomicAnim;
     // True if we want to resume playing atomic components when mAtomicAnim completes.
     private boolean mScheduleResumeAtomicComponent;
     private AutoPlayAtomicAnimationInfo mAtomicAnimAutoPlayInfo;
 
     private boolean mPassedOverviewAtomicThreshold;
      // mAtomicAnim plays the atomic components of the state animations when we pass the threshold.
      // However, if we reinit to transition to a new state (e.g. OVERVIEW -> ALL_APPS) before the
      // atomic animation finishes, we only control the non-atomic components so that we don't
      // interfere with the atomic animation. When the atomic animation ends, we start controlling
      // the atomic components as well, using this controller.
      private AnimatorPlaybackController mAtomicComponentsController;
      private LauncherState mAtomicComponentsTargetState = NORMAL;
  
      private float mAtomicComponentsStartProgress;
  
      public AbstractStateChangeTouchController(Launcher l, SingleAxisSwipeDetector.Direction dir) {
          mLauncher = l;
          mDetector = new SingleAxisSwipeDetector(l, this, dir);
          mSwipeDirection = dir;
      }
  
      protected long getAtomicDuration() {
          return 200;
      }

     /**
       * Returns the state to go to from fromState given the drag direction. If there is no state in
       * that direction, returns fromState.  拖拽方向以及显示内容
       */
      protected abstract LauncherState getTargetState(LauncherState fromState,
              boolean isDragTowardPositive);
     //展示当前动画
      protected abstract float initCurrentAnimation(@AnimationFlags int animComponents);
  
      /**
       * Returns the container that the touch started from when leaving NORMAL state.
       */
      protected abstract int getLogContainerTypeForNormalState(MotionEvent ev);
      // 开始从底部拖拽显示动画
         @Override
      public void onDragStart(boolean start, float startDisplacement) {
          mStartState = mLauncher.getStateManager().getState();
          mIsLogContainerSet = false;
  
          if (mCurrentAnimation == null) {
              mFromState = mStartState;
              mToState = null;
              cancelAnimationControllers();
              reinitCurrentAnimation(false, mDetector.wasInitialTouchPositive());
              mDisplacementShift = 0;
          } else {
              mCurrentAnimation.pause();
              mStartProgress = mCurrentAnimation.getProgressFraction();
  
              mAtomicAnimAutoPlayInfo = null;
              if (mAtomicComponentsController != null) {
                  mAtomicComponentsController.pause();
              }
          }
          mCanBlockFling = mFromState == NORMAL;
          mFlingBlockCheck.unblockFling();
          // Must be called after all the animation controllers have been paused
          if (mToState == ALL_APPS || mToState == NORMAL) {
              mLauncher.getAllAppsController().onDragStart(mToState == ALL_APPS);
          }
      }
  
      @Override
      public boolean onDrag(float displacement) {
          float deltaProgress = mProgressMultiplier * (displacement - mDisplacementShift);
          float progress = deltaProgress + mStartProgress;
          updateProgress(progress);
          boolean isDragTowardPositive = mSwipeDirection.isPositive(
                  displacement - mDisplacementShift);
          if (progress <= 0) {
              if (reinitCurrentAnimation(false, isDragTowardPositive)) {
                  mDisplacementShift = displacement;
                  if (mCanBlockFling) {
                      mFlingBlockCheck.blockFling();
                  }
              }
          } else if (progress >= 1) {
              if (reinitCurrentAnimation(true, isDragTowardPositive)) {
                  mDisplacementShift = displacement;
                  if (mCanBlockFling) {
                      mFlingBlockCheck.blockFling();
                  }
              }
          } else {
              mFlingBlockCheck.onEvent();
          }
  
          return true;
      }
}


3.2 PortraitStatesTouchController.java关于竖屏显示拖拽app列表的相关方法

 /**
  * Touch controller for handling various state transitions in portrait UI.
  */
 public class PortraitStatesTouchController extends AbstractStateChangeTouchController {
 
     private static final String TAG = "PortraitStatesTouchCtrl";
 
     /**
      * The progress at which all apps content will be fully visible when swiping up from overview.
      */
     protected static final float ALL_APPS_CONTENT_FADE_THRESHOLD = 0.08f;
 
     /**
      * The progress at which recents will begin fading out when swiping up from overview.
      */
     private static final float RECENTS_FADE_THRESHOLD = 0.88f;
 
     private final PortraitOverviewStateTouchHelper mOverviewPortraitStateTouchHelper;
 
     private final InterpolatorWrapper mAllAppsInterpolatorWrapper = new InterpolatorWrapper();
 
     private final boolean mAllowDragToOverview;
 
     // If true, we will finish the current animation instantly on second touch.
     private boolean mFinishFastOnSecondTouch;
 
     public PortraitStatesTouchController(Launcher l, boolean allowDragToOverview) {
         super(l, SingleAxisSwipeDetector.VERTICAL);
         mOverviewPortraitStateTouchHelper = new PortraitOverviewStateTouchHelper(l);
         mAllowDragToOverview = allowDragToOverview;
     }
  @Override
     protected boolean canInterceptTouch(MotionEvent ev) {
         if (mCurrentAnimation != null) {
             if (mFinishFastOnSecondTouch) {
                 mCurrentAnimation.getAnimationPlayer().end();
             }
 
             AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
             if (ev.getY() >= allAppsController.getShiftRange() * allAppsController.getProgress()) {
                  // If we are already animating from a previous state, we can intercept as long as
                  // the touch is below the current all apps progress (to allow for double swipe).
                  return true;
              }
              // Otherwise, make sure everything is settled and don't intercept so they can scroll
              // recents, dismiss a task, etc.
              if (mAtomicAnim != null) {
                  mAtomicAnim.end();
              }
              return false;
          }
          if (mLauncher.isInState(ALL_APPS)) {
              // In all-apps only listen if the container cannot scroll itself
              if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
                  return false;
              }
          } else if (mLauncher.isInState(OVERVIEW)) {
              if (!mOverviewPortraitStateTouchHelper.canInterceptTouch(ev)) {
                  return false;
              }
          } else {
              // If we are swiping to all apps instead of overview, allow it from anywhere.
              boolean interceptAnywhere = mLauncher.isInState(NORMAL) && !mAllowDragToOverview;
              // For all other states, only listen if the event originated below the hotseat height
              if (!interceptAnywhere && !isTouchOverHotseat(mLauncher, ev)) {
                  return false;
              }
          }
          if (getTopOpenViewWithType(mLauncher, TYPE_ACCESSIBLE | TYPE_ALL_APPS_EDU) != null) {
              return false;
          }
          return true;
      }
      // 获取上滑拖拽显示app列表
      @Override
      protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
          if (TestProtocol.sDebugTracing) {
              Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS, "PortraitStatesTouchController.getTargetState");
          }
          if (fromState == ALL_APPS && !isDragTowardPositive) {
              // Should swipe down go to OVERVIEW instead?
              if (TestProtocol.sDebugTracing) {
                  Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS,
                          "PortraitStatesTouchController.getTargetState 1");
              }
              if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(mLauncher)) {
                  // Don't allow swiping down to overview.
                  return NORMAL;
              }
              return TouchInteractionService.isConnected() ?
                      mLauncher.getStateManager().getLastState() : NORMAL;
          } else if (fromState == OVERVIEW) {
              if (TestProtocol.sDebugTracing) {
                  Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS,
                          "PortraitStatesTouchController.getTargetState 2");
              }
              LauncherState positiveDragTarget = ALL_APPS;
              if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(mLauncher)) {
                  // Don't allow swiping up to all apps.
                  positiveDragTarget = OVERVIEW;
              }
              return isDragTowardPositive ? positiveDragTarget : NORMAL;
          } else if (fromState == NORMAL && isDragTowardPositive) { // 从底部上滑拖拽时,返回ALL_APPS列表展示出来
              if (TestProtocol.sDebugTracing) {
                  Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS,
                          "PortraitStatesTouchController.getTargetState 3");
              }
              int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
              return mAllowDragToOverview && TouchInteractionService.isConnected()
                      && (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0
                      ? OVERVIEW : ALL_APPS;
          }
          return fromState;
      }
  }
所以在竖屏的时候可以修改为:
  @Override
      protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
          if (TestProtocol.sDebugTracing) {
              Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS, "PortraitStatesTouchController.getTargetState");
          }
          if (fromState == ALL_APPS && !isDragTowardPositive) {
              // Should swipe down go to OVERVIEW instead?
              if (TestProtocol.sDebugTracing) {
                  Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS,
                          "PortraitStatesTouchController.getTargetState 1");
              }
              if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(mLauncher)) {
                  // Don't allow swiping down to overview.
                  return NORMAL;
              }
              return TouchInteractionService.isConnected() ?
                      mLauncher.getStateManager().getLastState() : NORMAL;
          } else if (fromState == OVERVIEW) {
              if (TestProtocol.sDebugTracing) {
                  Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS,
                          "PortraitStatesTouchController.getTargetState 2");
              }
              LauncherState positiveDragTarget = ALL_APPS;
              if (ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(mLauncher)) {
                  // Don't allow swiping up to all apps.
                  positiveDragTarget = OVERVIEW;
              }
              return isDragTowardPositive ? positiveDragTarget : NORMAL;
          } else if (fromState == NORMAL && isDragTowardPositive) { // 从底部上滑拖拽时,返回ALL_APPS列表展示出来
              if (TestProtocol.sDebugTracing) {
                  Log.d(TestProtocol.OVERIEW_NOT_ALLAPPS,
                          "PortraitStatesTouchController.getTargetState 3");
              }
              int stateFlags = SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags();
            -  return mAllowDragToOverview && TouchInteractionService.isConnected()
            -          && (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0
            -          ? OVERVIEW : ALL_APPS;
            +  return mAllowDragToOverview && TouchInteractionService.isConnected()
            +          && (stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0
             +         ? OVERVIEW : NORMAL;
          }
          return fromState;
      }
  }

3.3 LandscapeEdgeSwipeController.java关于横屏上滑显示app的相关功能分析

3.3 LandscapeEdgeSwipeController.java关于横屏上滑显示app的相关功能分析
   /**
   * Touch controller for handling edge swipes in landscape/seascape UI
   */
  public class LandscapeEdgeSwipeController extends AbstractStateChangeTouchController {
  
      private static final String TAG = "LandscapeEdgeSwipeCtrl";
  
      public LandscapeEdgeSwipeController(Launcher l) {
          super(l, SingleAxisSwipeDetector.HORIZONTAL);
      }
  
      @Override
      protected boolean canInterceptTouch(MotionEvent ev) {
          if (mCurrentAnimation != null) {
              // If we are already animating from a previous state, we can intercept.
              return true;
          }
          if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
              return false;
          }
          return mLauncher.isInState(NORMAL) && (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
      }
     // 上滑显示是否app列表 分析得知返回的是NORMAL 所以就不需要修改
      @Override
      protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
          boolean draggingFromNav = mLauncher.getDeviceProfile().isSeascape() == isDragTowardPositive;
          return draggingFromNav ? OVERVIEW : NORMAL;
      }
  }

猜你喜欢

转载自blog.csdn.net/baidu_41666295/article/details/126632267