当前位置: 首页 > news >正文

Android U 多任务启动分屏——Launcher流程(下分屏 更新中)

前文

Android U 多任务启动分屏——Launcher流程(上分屏)

最近任务onClick事件的监听

在最近任务中每个任务都是一个TaskView,对TaskView操作,就是每个任务的操作。
在这里插入图片描述

代码路径:packages/apps/Launcher3/quickstep/src/com/android/quickstep/views/TaskView.java

    public TaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);//从给定的context获取当前的StatefulActivity实例//绑定TaskView和Activity之间的关系mActivity = StatefulActivity.fromContext(context);//监听当前TaskView的点击事件setOnClickListener(this::onClick);//初始化绘制相关参数mCurrentFullscreenParams = new FullscreenDrawParams(context);//把当前的Activity以及其对应的TaskView传递给DigitalWellBeingToastmDigitalWellBeingToast = new DigitalWellBeingToast(mActivity, this);//判断是否需要启用键盘焦点高亮boolean keyboardFocusHighlightEnabled = FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get()|| DesktopTaskView.DESKTOP_MODE_SUPPORTED;//如果不需要启用键盘焦点高亮,则setWillNotDraw(true),表示这个视图不需要绘制setWillNotDraw(!keyboardFocusHighlightEnabled);//使用TypedArray从XML属性中读取TaskView的自定义属性TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TaskView, defStyleAttr, defStyleRes);//如果启用了键盘焦点高亮,则创建一个BorderAnimator实例。mBorderAnimator = !keyboardFocusHighlightEnabled? null: new BorderAnimator(/* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,/* borderColor= */ ta.getColor(R.styleable.TaskView_borderColor, DEFAULT_BORDER_COLOR),/* borderAnimationParams= */ new BorderAnimator.SimpleParams(/* borderWidthPx= */ context.getResources().getDimensionPixelSize(R.dimen.keyboard_quick_switch_border_width),/* boundsBuilder= */ this::updateBorderBounds,/* targetView= */ this));//回收TypedArray对象以避免内存泄漏。ta.recycle();}private void onClick(View view) {if (getTask() == null) {return;}//是否选择第二个分屏的应用if (confirmSecondSplitSelectApp()) {return;}//运行当前选择的TasklaunchTasks();mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo()).log(LAUNCHER_TASK_LAUNCH_TAP);}

onClick方法中,如果我们选择了第二个分屏的应用那么就进入到分屏流程confirmSecondSplitSelectApp(),这个方法中同样会进行一些判断当前是否进入分屏,还是直接运行当前TasklaunchTasks()

选择下分屏

确定选择下分屏,播放相关动画,调用SytemUI接口进入到真正分屏

确定下分屏task

代码路径:packages/apps/Launcher3/quickstep/src/com/android/quickstep/views/TaskView.java

/*** @return {@code true} if user is already in split select mode and this tap was to choose the*         second app. {@code false} otherwise*/protected boolean confirmSecondSplitSelectApp() {//获取最后一次点击的Task的索引int index = getLastSelectedChildTaskIndex();//获取该索引对应的Task相关参数TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];//判断TaskIdAttributeContainer对象是否为空if (container != null) {//进入confirmSplitSelect方法判断分屏的后续流程return getRecentsView().confirmSplitSelect(this, container.getTask(),container.getIconView().getDrawable(), container.getThumbnailView(),container.getThumbnailView().getThumbnail(), /* intent */ null,/* user */ null);}return false;}public RecentsView getRecentsView() {return (RecentsView) getParent();}

前文我们分析过,这里的getRecentsView()返回的是当前TaskView的父View,类型强制转换为了RecentsView,而RecentsView抽象类,优先调用的应该是其子类的confirmSplitSelect方法。
getRecentsView()对应的就是com.android.quickstep.views.LauncherRecentsView{b2fe033 V.ED..... ........ 0,0-1440,2960 #7f09022a app:id/overview_panel},即TaskViewViewLauncherRecentsView
LauncherRecentsViewRecentsView的子类之一,但是LauncherRecentsView中没有confirmSplitSelect方法,所以这里调用的是其父类RecentsView中的confirmSplitSelect方法(儿子没有的找父亲要,总之就是找老登爆点金币)。
confirmSplitSelect方法传递的参数this指的就是选择的下分屏task。

动画准备和启动

代码路径:packages/apps/Launcher3/quickstep/src/com/android/quickstep/views/RecentsView.java

    /*** Confirms the selection of the next split task. The extra data is passed through because the* user may be selecting a subtask in a group.** @param containerTaskView If our second selected app is currently running in Recents, this is*                          the "container" TaskView from Recents. If we are starting a fresh*                          instance of the app from an Intent, this will be null.* @param task The Task corresponding to our second selected app. If we are starting a fresh*             instance of the app from an Intent, this will be null.* @param drawable The Drawable corresponding to our second selected app's icon.* @param secondView The View representing the current space on the screen where the second app*                   is (either the ThumbnailView or the tapped icon).* @param intent If we are launching a fresh instance of the app, this is the Intent for it. If*               the second app is already running in Recents, this will be null.* @param user If we are launching a fresh instance of the app, this is the UserHandle for it.*             If the second app is already running in Recents, this will be null.* @return true if waiting for confirmation of second app or if split animations are running,*          false otherwise*/public boolean confirmSplitSelect(TaskView containerTaskView, Task task, Drawable drawable,View secondView, @Nullable Bitmap thumbnail, Intent intent, UserHandle user) {if (canLaunchFullscreenTask()) {return false;}if (mSplitSelectStateController.isBothSplitAppsConfirmed()) {return true;}// Second task is selected either as an already-running Task or an Intentif (task != null) {if (!task.isDockable) {// Task does not support split screenmSplitUnsupportedToast.show();return true;}mSplitSelectStateController.setSecondTask(task);} else {mSplitSelectStateController.setSecondTask(intent, user);}RectF secondTaskStartingBounds = new RectF();Rect secondTaskEndingBounds = new Rect();// TODO(194414938) starting bounds seem slightly off, investigateRect firstTaskStartingBounds = new Rect();Rect firstTaskEndingBounds = mTempRect;boolean isTablet = mActivity.getDeviceProfile().isTablet;SplitAnimationTimings timings = AnimUtils.getDeviceSplitToConfirmTimings(isTablet);PendingAnimation pendingAnimation = new PendingAnimation(timings.getDuration());int halfDividerSize = getResources().getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;mOrientationHandler.getFinalSplitPlaceholderBounds(halfDividerSize,mActivity.getDeviceProfile(),mSplitSelectStateController.getActiveSplitStagePosition(), firstTaskEndingBounds,secondTaskEndingBounds);mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);mFirstFloatingTaskView.addConfirmAnimation(pendingAnimation,new RectF(firstTaskStartingBounds), firstTaskEndingBounds,false /* fadeWithThumbnail */, true /* isStagedTask */);safeRemoveDragLayerView(mSecondFloatingTaskView);mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity, secondView,thumbnail, drawable, secondTaskStartingBounds);mSecondFloatingTaskView.setAlpha(1);mSecondFloatingTaskView.addConfirmAnimation(pendingAnimation, secondTaskStartingBounds,secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);pendingAnimation.setViewAlpha(mSplitInstructionsView, 0, clampToProgress(LINEAR,timings.getInstructionsFadeStartOffset(),timings.getInstructionsFadeEndOffset()));pendingAnimation.addEndListener(aBoolean -> {mSplitSelectStateController.launchSplitTasks(aBoolean1 -> RecentsView.this.resetFromSplitSelectionState());InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);});mSecondSplitHiddenView = containerTaskView;if (mSecondSplitHiddenView != null) {mSecondSplitHiddenView.setThumbnailVisibility(INVISIBLE,mSplitSelectStateController.getSecondTaskId());}InteractionJankMonitorWrapper.begin(this,InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Second tile selected");// Fade out all other views underneath placeholdersObjectAnimator tvFade = ObjectAnimator.ofFloat(this, RecentsView.CONTENT_ALPHA,1, 0);pendingAnimation.add(tvFade, DEACCEL_2, SpringProperty.DEFAULT);pendingAnimation.buildAnim().start();return true;}

http://www.mrgr.cn/news/30207.html

相关文章:

  • 电力电容器、电子电容器的区别
  • shell脚本中的if语句、shell脚本中的if条件语句介绍和使用案例(非常全面)
  • DDoS对策是什么?详细解说DDoS攻击难以防御的理由和对策方法
  • 高等数学 3.3 泰勒公式
  • SpringCloud微服务实现服务降级的最佳实践
  • 数据结构-排序(冒泡,选择,插入,希尔,快排,归并,堆排)
  • 人工智能时代,程序员如何保持核心竞争力?
  • 制作一个rabbitmq-sdk
  • 组态软件之万维组态介绍(web组态、html组态、vue2/vue3组态)
  • 文献分享: SIGMOD-24论文集概览
  • 【Python】从基础到进阶(九):探索Python中的迭代器与生成器
  • 【数据结构初阶】栈接口实现及经典OJ题超详解
  • 【QT】基于HTTP协议的网络应用程序
  • 计算机组成原理——进制与编码
  • 24最新Stable Diffusion之Lora模型训练详细教程
  • 嵌入式八股文(C语言篇)
  • css 横向盒子 不换行 超过出现横向滚动条
  • 【九盾安防】叉车安全解决方案——叉车限速器改善仓库和人身安全
  • 情感计算领域期刊与会议
  • SaltStack部署与应用基础