個(gè)人新聞?lì)惥W(wǎng)站模板營(yíng)銷(xiāo)策略包括哪些內(nèi)容
在 Flutter Android 應(yīng)用中實(shí)現(xiàn)畫(huà)中畫(huà)功能
畫(huà)中畫(huà)(Picture-in-Picture, PiP)模式允許您的應(yīng)用在一個(gè)固定在屏幕角落的小窗口中運(yùn)行,同時(shí)用戶可以與其他應(yīng)用進(jìn)行交互。本指南將介紹如何在 Flutter Android 應(yīng)用中實(shí)現(xiàn)畫(huà)中畫(huà)功能,包括其局限性和解決方案。
項(xiàng)目地址
flutter_pip
前提條件
-
需要 Android 8.0 (API level 26) 或更高版本才能完全支持畫(huà)中畫(huà)功能
-
基本的 Flutter 插件開(kāi)發(fā)知識(shí)
-
基本的 Android 開(kāi)發(fā)知識(shí)
實(shí)現(xiàn)概述
實(shí)現(xiàn)包含兩個(gè)主要組件:
-
FlutterPipController
: 處理畫(huà)中畫(huà)功能和狀態(tài)管理 -
FlutterPipPlugin
: 橋接 Flutter 和原生 Android 代碼
主要特性
-
畫(huà)中畫(huà)模式支持檢測(cè)
-
自定義寬高比配置
-
平滑過(guò)渡的源矩形提示
-
畫(huà)中畫(huà)狀態(tài)監(jiān)控和回調(diào)
-
非視頻內(nèi)容的交叉淡入淡出動(dòng)畫(huà)
核心實(shí)現(xiàn)
1. 檢查畫(huà)中畫(huà)支持
在使用畫(huà)中畫(huà)之前,我們需要檢查設(shè)備是否支持:
public boolean isSupported() {Activity activity = mActivity.get();if (activity == null) {return false;}// Requires Android 8.0 (API 26) or higherif (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {return false;}final PackageManager pm = activity.getApplicationContext().getPackageManager();return pm != null && pm.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
}
2. 配置畫(huà)中畫(huà)參數(shù)
畫(huà)中畫(huà)模式可以自定義幾個(gè)參數(shù):
public boolean setup(@Nullable Rational aspectRatio,@Nullable Boolean autoEnterEnabled,@Nullable Rect sourceRectHint) {// ... version checks and null checks ...PictureInPictureParams.Builder builder = new PictureInPictureParams.Builder();if (aspectRatio != null) {builder.setAspectRatio(aspectRatio);}if (sourceRectHint != null) {builder.setSourceRectHint(sourceRectHint);}// Disable seamless resize for non-video contentbuilder.setSeamlessResizeEnabled(false);activity.setPictureInPictureParams(builder.build());
}
Flutter 集成限制和解決方案
1. 自動(dòng)進(jìn)入畫(huà)中畫(huà)模式限制
Flutter 不正確地委托 Android 生命周期事件,如 onPause
和 onPiPModeChanged
。這給實(shí)現(xiàn)自動(dòng)進(jìn)入畫(huà)中畫(huà)模式帶來(lái)了挑戰(zhàn)。
限制:
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.S)
public boolean isAutoEnterSupported() {// We could support this on Android 12+, but Flutter limitations prevent itreturn false;
}
解決方案:
我們不依賴(lài)自動(dòng)進(jìn)入畫(huà)中畫(huà)模式,而是提供顯式的方法來(lái)進(jìn)入和退出畫(huà)中畫(huà)模式,這些方法可以從 Flutter 代碼中調(diào)用:
public boolean start() {if (!isSupported() || isActived() || !isPipEnabled()) {return false;}Activity activity = mActivity.get();if (activity == null) {return false;}activity.enterPictureInPictureMode(mParamsBuilder.build());return true;
}
2. 畫(huà)中畫(huà)狀態(tài)變化檢測(cè)
由于 Flutter 不提供畫(huà)中畫(huà)狀態(tài)變化事件,我們實(shí)現(xiàn)了一個(gè)輪詢(xún)機(jī)制來(lái)檢測(cè)狀態(tài)變化。
解決方案:
private void startStateMonitoring() {// Poll every 100ms to check PiP statemCheckStateTask = new Runnable() {@Overridepublic void run() {checkPipState();mHandler.postDelayed(this, CHECK_INTERVAL_MS);}};mHandler.post(mCheckStateTask);
}
3. 畫(huà)中畫(huà)退出處理
Android 不提供直接退出畫(huà)中畫(huà)模式的方法。
解決方案:
public void stop() {if (!isSupported() || !isActived()) {return;}Activity activity = mActivity.get();if (activity == null) {return;}// Move the activity to background instead of truly stopping PiPactivity.moveTaskToBack(false);
}
最佳實(shí)踐
- 資源管理: 始終正確釋放資源:
public void dispose() {stopStateMonitoring();mPipParams = null;mParamsBuilder = null;mHandler = null;mLastPipState = false;mCheckStateTask = null;
}
- 狀態(tài)監(jiān)控: 跟蹤畫(huà)中畫(huà)狀態(tài)變化并通知 Flutter:
private void checkPipState() {boolean currentState = isActived();if (currentState != mLastPipState) {mLastPipState = currentState;notifyPipStateChanged(currentState ? PipState.Started : PipState.Stopped);}
}
- 交叉淡入淡出動(dòng)畫(huà): 對(duì)于非視頻內(nèi)容,禁用無(wú)縫調(diào)整大小:
mParamsBuilder.setSeamlessResizeEnabled(false);
結(jié)論
雖然在 Flutter Android 應(yīng)用中實(shí)現(xiàn)畫(huà)中畫(huà)功能受到 Flutter 處理 Android 生命周期事件的一些限制,但我們可以通過(guò)輪詢(xún)狀態(tài)檢測(cè)和顯式控制方法來(lái)解決這些問(wèn)題。這里提供的解決方案提供了一個(gè)可靠且穩(wěn)定的實(shí)現(xiàn),同時(shí)保持良好的用戶體驗(yàn)。
請(qǐng)記住要在不同的 Android 版本和設(shè)備配置上進(jìn)行全面測(cè)試,因?yàn)楫?huà)中畫(huà)行為在不同的 Android 實(shí)現(xiàn)中可能會(huì)有所不同。
參考
- Android 官方文檔 - 畫(huà)中畫(huà)
PS
這個(gè)項(xiàng)目會(huì)持續(xù)維護(hù)下去,而且已經(jīng)在準(zhǔn)備發(fā)布pub.dev, 目前上面的文檔是AI幫助生成的,有些不太準(zhǔn)確和完善,但基本路線是對(duì)的,后續(xù)會(huì)持續(xù)補(bǔ)充完善。