Android T split-screen Launcher RecentsView part introduction/android framework mobile phone car system development

1 The first stage animation of the desktop part:

Explanation of the free video tutorial at station b:
https://www.bilibili.com/video/BV1wj411o7A9/
insert image description here
Click the onClick of the Split top button on the desktop to trigger the view-related animation of its own process:
insert image description here

After clicking, there will be related animation preparations:
after clicking, the animation will enter the state as shown in the figure below. This SMS app is placed on the top, and the multitasking below is still multitasking, and the position has indeed changed.
insert image description here

Related animation call stack:

createTaskDismissAnimation:2975, RecentsView (com.android.quickstep.views)
createSplitSelectInitAnimation:4022, RecentsView (com.android.quickstep.views)
handleSplitSelectionState:120, RecentsViewStateController (com.android.launcher3.uioverrides)
setStateWithAnimationInternal:96, RecentsViewStateController (com.android.launcher3.uioverrides)
setStateWithAnimation:87, BaseRecentsViewStateController (com.android.launcher3.uioverrides)
setStateWithAnimation:53, BaseRecentsViewStateController (com.android.launcher3.uioverrides)
createAnimationToNewWorkspaceInternal:324, StateManager (com.android.launcher3.statemanager)
goToStateAnimated:259, StateManager (com.android.launcher3.statemanager)
goToState:247, StateManager (com.android.launcher3.statemanager)
goToState:150, StateManager (com.android.launcher3.statemanager)
goToState:143, StateManager (com.android.launcher3.statemanager)
initiateSplitSelect:182, LauncherRecentsView (com.android.quickstep.views)
initiateSplitSelect:1541, TaskView (com.android.quickstep.views)
onClick:132, TaskShortcutFactory$SplitSelectSystemShortcut (com.android.quickstep)
lambda$addMenuOption$1:254, TaskMenuView (com.android.quickstep.views)
run:-1, TaskMenuView$$ExternalSyntheticLambda2 (com.android.quickstep.views)
finishRecentsAnimation:4535, RecentsView (com.android.quickstep.views)
lambda$addMenuOption$2:252, TaskMenuView (com.android.quickstep.views)
run:-1, TaskMenuView$$ExternalSyntheticLambda1 (com.android.quickstep.views)
switchToScreenshot:4961, RecentsView (com.android.quickstep.views)
lambda$addMenuOption$3$com-android-quickstep-views-TaskMenuView:251, TaskMenuView (com.android.quickstep.views)
onClick:-1, TaskMenuView$$ExternalSyntheticLambda5 (com.android.quickstep.views)
performClick:7506, View (android.view)
performClickInternal:7483, View (android.view)
-$$Nest$mperformClickInternal:-1, View (android.view)
run:29335, View$PerformClick (android.view)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7897, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:937, ZygoteInit (com.android.internal.os)

Because there are too many codes, we only explain the animation of the TaskView in the upper half:
here createTaskDismissAnimation is actually the animation construction displayed in the upper half of the screen of the SMS application above.

/**
     * Places an {@link FloatingTaskView} on top of the thumbnail for {@link #mSplitHiddenTaskView}
     * and then animates it into the split position that was desired
     */
    private void createInitialSplitSelectAnimation(PendingAnimation anim) {
    
    
        mOrientationHandler.getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
                mSplitPlaceholderInset, mActivity.getDeviceProfile(),
                mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);

        RectF startingTaskRect = new RectF();
        if (mSplitHiddenTaskView != null) {
    
    
            mSplitHiddenTaskView.setVisibility(INVISIBLE);//把TaskView设置不可见
            //要创建一个TaskView的副本,并且要把这个副本进行相关的动画播放显示在最顶端一个小区域
            mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
                    mSplitHiddenTaskView.getThumbnail(),
                    mSplitHiddenTaskView.getThumbnail().getThumbnail(),
                    mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect);
            mFirstFloatingTaskView.setAlpha(1);
            //根据相关的初始化尺寸来构建对应anim
            mFirstFloatingTaskView.addAnimation(anim, startingTaskRect, mTempRect,
                    true /* fadeWithThumbnail */, true /* isStagedTask */);
        } else {
    
    
         
        }
        anim.addEndListener(success -> {
    
    
            if (success) {
    
    
                mSplitToast.show();
                //动画播放完成后,显示出一个Toast "Tap another app to use split-screen"
            }
        });
    }

Other TaskView animations will not be introduced, and they are all in this call stack. At this time, the first step of split-screen multitasking on the desktop is completed, and the TaskView is placed on the top (upper screen), and the next step is to wait for the user to manually Only by choosing a lower-screen app can a real split-screen be formed.
insert image description here

2 Select the desktop, click the bottom TaskView, and start the related animation

Clicking the TaskView at the bottom to trigger the animation process is relatively simple:

 private void onClick(View view) {
    
    
        if (confirmSecondSplitSelectApp()) {
    
    
            return;
        }
}
 private boolean confirmSecondSplitSelectApp() {
    
    
        int index = getChildTaskIndexAtPosition(mLastTouchDownPosition);
        TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
        //调用到了RecentsView的confirmSplitSelect方法
        return getRecentsView().confirmSplitSelect(this, container.getTask(),
                container.getIconView(), container.getThumbnailView());
    }

	//方法进行相关的动画准备和启动
     public boolean confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
            TaskThumbnailView thumbnailView) {
    
    
        //省略
        mSplitSelectStateController.setSecondTask(task);//设置底部区域要显示的task
        RectF secondTaskStartingBounds = new RectF();//初始化底部的区域
        Rect secondTaskEndingBounds = new Rect();
        Rect firstTaskStartingBounds = new Rect();//初始化顶部的区域
        Rect firstTaskEndingBounds = mTempRect;
        //获取动画时间
        int duration = mActivity.getStateManager().getState().getTransitionDuration(mActivity,
                false /* isToState */);
        PendingAnimation pendingAnimation = new PendingAnimation(duration);

        int halfDividerSize = getResources()
                .getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
                //获取对应的一个上屏幕区域和下屏幕区域截至区域firstTaskEndingBounds,secondTaskEndingBounds
        mOrientationHandler.getFinalSplitPlaceholderBounds(halfDividerSize,
                mActivity.getDeviceProfile(),
                mSplitSelectStateController.getActiveSplitStagePosition(), firstTaskEndingBounds,
                secondTaskEndingBounds);
		
		//获取当前的上屏幕区域坐标情况放入firstTaskStartingBounds
        mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
        //有了初始区域和结束区域,进行相关的动画配置
        mFirstFloatingTaskView.addAnimation(pendingAnimation,
                new RectF(firstTaskStartingBounds), firstTaskEndingBounds,
                false /* fadeWithThumbnail */, true /* isStagedTask */);

//下屏部分和商品部分类是不再讲解
        mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
                thumbnailView, thumbnailView.getThumbnail(),
                iconView.getDrawable(), secondTaskStartingBounds);
        mSecondFloatingTaskView.setAlpha(1);
        mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
                secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);
          //进行动画结束监听,在动画结束时候才进行launchSplitTasks,即正式调用到systemui和systemserver让赶紧启动真正分屏
        pendingAnimation.addEndListener(aBoolean -> {
    
    
            mSplitSelectStateController.launchSplitTasks(
                    aBoolean1 -> RecentsView.this.resetFromSplitSelectionState());
        });
        if (containerTaskView.containsMultipleTasks()) {
    
    
            // If we are launching from a child task, then only hide the thumbnail itself
            mSecondSplitHiddenView = thumbnailView;
        } else {
    
    
            mSecondSplitHiddenView = containerTaskView;
        }
        mSecondSplitHiddenView.setVisibility(INVISIBLE);//下屏的TaskView要被隐藏
        pendingAnimation.buildAnim().start();//启动正式动画
        return true;
    }

Officially call the shell interface related to systemui to operate the real task-related split-screen business:

launchTasks:201, SplitSelectStateController (com.android.quickstep.util)
launchSplitTasks:124, SplitSelectStateController (com.android.quickstep.util)
lambda$confirmSplitSelect$24$com-android-quickstep-views-RecentsView:4081, RecentsView (com.android.quickstep.views)
accept:-1, RecentsView$$ExternalSyntheticLambda30 (com.android.quickstep.views)
onAnimationEnd:80, AnimatorListeners$EndStateCallbackWrapper (com.android.launcher3.anim)
:-1, Animator$AnimatorListener (android.animation)
endAnimation:1333, ValueAnimator (android.animation)
doAnimationFrame:1575, ValueAnimator (android.animation)
pulseAnimationFrame:1591, ValueAnimator (android.animation)
pulseFrame:1170, AnimatorSet (android.animation)
handleAnimationEvents:1153, AnimatorSet (android.animation)
doAnimationFrame:1053, AnimatorSet (android.animation)
doAnimationFrame:307, AnimationHandler (android.animation)
-$$Nest$mdoAnimationFrame:-1, AnimationHandler (android.animation)
doFrame:86, AnimationHandler$1 (android.animation)
run:1229, Choreographer$CallbackRecord (android.view)
run:1239, Choreographer$CallbackRecord (android.view)
doCallbacks:899, Choreographer (android.view)
doFrame:827, Choreographer (android.view)
run:1214, Choreographer$FrameDisplayEventReceiver (android.view)
handleCallback:942, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loopOnce:201, Looper (android.os)
loop:288, Looper (android.os)
main:7897, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:548, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:937, ZygoteInit (com.android.internal.os)

Guess you like

Origin blog.csdn.net/learnframework/article/details/130901312