Pip スモール ウィンドウ モードからフル スクリーン モードへのソース コード分析 - Android フレームワーク車両自動車携帯電話システム開発

PipMenuView で「展開」ボタンをクリックします

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 を開始します。これにより、次のようにコア コードを非表示にするアニメーションが開始されます:
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 と境界を設定し、小さなウィンドウのタスクに対してアニメーションのズームイン アクションを実行します。


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 */);
 
        });
    }

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/learnframework/article/details/130868375