android T分屏 Launcher RecentsView部分介绍/android framework手机车机系统开发
其他TaskView动画就不进行相关的介绍了,都在这调用堆栈里面,到此时分屏在桌面多任务完成了第一步,把TaskView放到顶部(上屏),接下来要等待用户来手动选择一个下屏app,才可以构成真正意义的分屏。这里createTaskDismissAnimation其实就是上面那个短信应用上半屏幕部分显示的动画构建。点击后会动画进入如下图一样状态,这个短信app放到上面,下面多任务依旧是多任务,位置确
·
1 桌面部分第一阶段动画:
b站免费视频教程讲解:
https://www.bilibili.com/video/BV1wj411o7A9/
桌面点击这个Split top按钮的onClick后触发自己进程的view相关的动画:
点击之后会有相关动画的准备工作:
点击后会动画进入如下图一样状态,这个短信app放到上面,下面多任务依旧是多任务,位置确实变化了
相关动画调用栈:
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)
因为代码太多,只对上半部分的TaskView动画进行相关的说明:
这里createTaskDismissAnimation其实就是上面那个短信应用上半屏幕部分显示的动画构建
/**
* 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"
}
});
}
其他TaskView动画就不进行相关的介绍了,都在这调用堆栈里面,到此时分屏在桌面多任务完成了第一步,把TaskView放到顶部(上屏),接下来要等待用户来手动选择一个下屏app,才可以构成真正意义的分屏。
2 桌面选择点击底部TaskView点击,及相关动画启动
底部点击TaskView触发动画流程相对比较简单:
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;
}
正式调用systemui相关的shell接口进行操作真正的task相关分屏业务:
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)
更多推荐
已为社区贡献52条内容
所有评论(0)