Pip小窗模式到全屏模式源码分析-android framework车载车机手机系统开发

PipMenuView点击Expand按钮

对应b站免费视频教程讲解:
https://www.bilibili.com/video/BV1wj411o7A9/

hideMenu:431, PipMenuView (com.android.wm.shell.pip.phone)
expandPip:558, PipMenuView (com.android.wm.shell.pip.phone)
lambda$new$2:198, PipMenuView (com.android.wm.shell.pip.phone)
$r8$lambda$TVGiqqzKEZGnpVVCecTNWyek8VQ:-1, PipMenuView (com.android.wm.shell.pip.phone)
onClick:-1, PipMenuView$$ExternalSyntheticLambda3 (com.android.wm.shell.pip.phone)
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)

这里发现较为简单,功能就是响应一下onClick,然后启动hideMenu,会启动一个动画进行hide
核心代码如下:
frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java

void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility,
            boolean resize, @AnimationType int animationType) {
        if (mMenuState != MENU_STATE_NONE) {
            cancelDelayedHide();
            if (notifyMenuVisibility) {
                notifyMenuStateChangeStart(MENU_STATE_NONE, resize, null);
            }
            mMenuContainerAnimator = new AnimatorSet();
            ObjectAnimator menuAnim = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
                    mMenuContainer.getAlpha(), 0f);
            menuAnim.addUpdateListener(mMenuBgUpdateListener);
            ObjectAnimator settingsAnim = ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA,
                    mSettingsButton.getAlpha(), 0f);
            ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
                    mDismissButton.getAlpha(), 0f);
            ObjectAnimator enterSplitAnim = ObjectAnimator.ofFloat(mEnterSplitButton, View.ALPHA,
                    mEnterSplitButton.getAlpha(), 0f);
            mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim,
                    enterSplitAnim);
            mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT);
            mMenuContainerAnimator.setDuration(getFadeOutDuration(animationType));
            mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    setVisibility(GONE);
                    if (notifyMenuVisibility) {
                        notifyMenuStateChangeFinish(MENU_STATE_NONE);
                    }
                    if (animationFinishedRunnable != null) {
                        animationFinishedRunnable.run();
                    }
                }
            });
            mMenuContainerAnimator.start();
        }
    }

PipMenuView动画结束后进行对应的WindowMode及bounds设置,还有对小窗的task进行动画放大动作


05-25 17:10:34.142   744   744 I test22  : WindowContainerTransaction setBounds bounds = Rect(0, 0 - 1440, 2960)
05-25 17:10:34.143   744   744 I test22  : applySyncTransaction 
05-25 17:10:34.143   744   744 I test22  : java.lang.Exception
05-25 17:10:34.143   744   744 I test22  : 	at android.window.WindowOrganizer.applySyncTransaction(WindowOrganizer.java:81)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.common.SyncTransactionQueue$SyncCallback.send(SyncTransactionQueue.java:197)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.common.SyncTransactionQueue.queue(SyncTransactionQueue.java:80)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.pip.PipTaskOrganizer.exitPip(PipTaskOrganizer.java:471)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.pip.phone.PipMotionHelper.expandLeavePip(PipMotionHelper.java:364)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.pip.phone.PipMotionHelper.expandLeavePip(PipMotionHelper.java:342)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.pip.phone.PipTouchHandler$PipMenuListener.onPipExpand(PipTouchHandler.java:144)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.pip.phone.PhonePipMenuController$$ExternalSyntheticLambda4.accept(Unknown Source:2)
05-25 17:10:34.143   744   744 I test22  : 	at java.util.ArrayList.forEach(ArrayList.java:1262)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.pip.phone.PhonePipMenuController.onPipExpand(PhonePipMenuController.java:472)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.pip.phone.PipMenuView$$ExternalSyntheticLambda10.run(Unknown Source:2)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.wm.shell.pip.phone.PipMenuView$4.onAnimationEnd(PipMenuView.java:427)
05-25 17:10:34.143   744   744 I test22  : 	at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:600)
05-25 17:10:34.143   744   744 I test22  : 	at android.animation.AnimatorSet.endAnimation(AnimatorSet.java:1301)
05-25 17:10:34.143   744   744 I test22  : 	at android.animation.AnimatorSet.doAnimationFrame(AnimatorSet.java:1086)
05-25 17:10:34.143   744   744 I test22  : 	at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:307)
05-25 17:10:34.143   744   744 I test22  : 	at android.animation.AnimationHandler.-$$Nest$mdoAnimationFrame(Unknown Source:0)
05-25 17:10:34.143   744   744 I test22  : 	at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:86)
05-25 17:10:34.143   744   744 I test22  : 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1229)
05-25 17:10:34.143   744   744 I test22  : 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1239)
05-25 17:10:34.143   744   744 I test22  : 	at android.view.Choreographer.doCallbacks(Choreographer.java:899)
05-25 17:10:34.143   744   744 I test22  : 	at android.view.Choreographer.doFrame(Choreographer.java:827)
05-25 17:10:34.143   744   744 I test22  : 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1214)
05-25 17:10:34.143   744   744 I test22  : 	at android.os.Handler.handleCallback(Handler.java:942)
05-25 17:10:34.143   744   744 I test22  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
05-25 17:10:34.143   744   744 I test22  : 	at android.os.Looper.loopOnce(Looper.java:201)
05-25 17:10:34.143   744   744 I test22  : 	at android.os.Looper.loop(Looper.java:288)
05-25 17:10:34.143   744   744 I test22  : 	at android.app.ActivityThread.main(ActivityThread.java:7897)
05-25 17:10:34.143   744   744 I test22  : 	at java.lang.reflect.Method.invoke(Native Method)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
05-25 17:10:34.143   744   744 I test22  : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:937)

核心代码如下:

 public void exitPip(int animationDurationMs, boolean requestEnterSplit) {
      //省略
        final Rect destinationBounds = getExitDestinationBounds();//获取目标大小,这里推出pip应该到全屏,所以destinationBounds为全屏
        final int direction = syncWithSplitScreenBounds(destinationBounds, requestEnterSplit)
                ? TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
                : TRANSITION_DIRECTION_LEAVE_PIP;

        if (Transitions.ENABLE_SHELL_TRANSITIONS && direction == 
        //省略
        } else {
            final SurfaceControl.Transaction tx =
                    mSurfaceControlTransactionFactory.getTransaction();
            mSurfaceTransactionHelper.scale(tx, mLeash, destinationBounds,
                    mPipBoundsState.getBounds());
            tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height());
            // We set to fullscreen here for now, but later it will be set to UNDEFINED for
            // the proper windowing mode to take place. See #applyWindowingModeChangeOnExit.
            wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN); //设置windowmode为full
            wct.setBounds(mToken, destinationBounds);//设置目标大小为全屏了
            wct.setBoundsChangeTransaction(mToken, tx);
        }
        mPipTransitionState.setTransitionState(PipTransitionState.EXITING_PIP);

        mSyncTransactionQueue.queue(wct);
        mSyncTransactionQueue.runInSync(t -> {
            final Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect(
                    mPictureInPictureParams, destinationBounds);
                    //进行对应的pip到全屏的task窗口动画开启
            final PipAnimationController.PipTransitionAnimator<?> animator =
                    animateResizePip(mPipBoundsState.getBounds(), destinationBounds, sourceHintRect,direction, animationDurationMs, 0 /* startingAngle */);
 
        });
    }

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值