Android使用Jetpack WindowManager開發(fā)可折疊設(shè)備(過(guò)程分享)
一、背景
我們?cè)贕oogle開發(fā)者大會(huì)上,看到Jetpack WindowManager和WindowSizeClass這些技術(shù),如下圖。
那這里不得不說(shuō)折疊屏手機(jī)了
- 在其中一個(gè)顯示區(qū)域中運(yùn)行一個(gè)應(yīng)用。
- 同時(shí)運(yùn)行兩個(gè)應(yīng)用,各位于一個(gè)顯示區(qū)域中(在
multi-window
模式下)。 - 可折疊設(shè)備還支持不同的折疊狀態(tài)。折疊狀態(tài)可用來(lái)以不同的方式顯示內(nèi)容
折疊屏手機(jī)有哪些優(yōu)勢(shì)呢?
- 更大的屏幕空間
- 更高的靈活性
- 更好的移動(dòng)性
- 更高的科技含量
隨著人們對(duì)生活品質(zhì)的越來(lái)越高,單屏幕手機(jī)已經(jīng)難以滿足部分需求,折疊屏手機(jī)也越來(lái)越受歡迎,能給用戶帶來(lái)與眾不同的體驗(yàn),Jetpack WindowManager和WindowSizeClass就是折疊屏手機(jī)開發(fā)所需要的技術(shù),有了這些技術(shù),可以幫我們更好的開發(fā)折疊屏。
二、Jetpack WindowManager的簡(jiǎn)單了解
WindowManager的功能,包括對(duì)響應(yīng)式UI的支持、檢測(cè)屏幕變化的回調(diào)適配器以及窗口測(cè)試API。但Jetpack WindowManager還提供了對(duì)新型設(shè)備的支持,如可折疊設(shè)備和Chrome OS等窗口環(huán)境,是一個(gè)現(xiàn)代的、以Kotlin為首的庫(kù),它支持新的設(shè)備形態(tài)因素,并提供 "類似AppCompat "的功能,以構(gòu)建具有響應(yīng)式用戶界面的應(yīng)用程序。
主要的API
新的WindowManager APIs包括以下內(nèi)容。
WindowLayoutInfo:包含了一個(gè)窗口的顯示特征,例如窗口是否包含了折疊或鉸鏈
FoldingFeature:使你能夠監(jiān)測(cè)可折疊設(shè)備的折疊狀態(tài),以確定設(shè)備的姿勢(shì)
WindowMetrics:提供當(dāng)前窗口的指標(biāo)或整體顯示的指標(biāo)
Jetpack WindowManager與安卓系統(tǒng)沒(méi)有捆綁,允許更快地迭代API,以支持快速發(fā)展的設(shè)備市場(chǎng),并使應(yīng)用程序開發(fā)人員能夠采用庫(kù)的更新,而不必等待最新的安卓版本。
三、Jetpack WindowManager的簡(jiǎn)單使用
首先我們需要到官網(wǎng)先下載好Android studio,把開發(fā)環(huán)境搞好。
1)、創(chuàng)建一個(gè)新項(xiàng)目
加入部分依賴
dependencies { ext.windowmanager_version = "1.0.0" implementation "androidx.window:window:$windowmanager_version" androidTestImplementation "androidx.window:window-testing:$windowmanager_version" // Needed to use lifecycleScope to collect the WindowLayoutInfo flow implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0" }
2)、使用 WindowManager
通過(guò) WindowManager 的 WindowInfoTracker 接口訪問(wèn)窗口功能。
打開 MainActivity.kt 源文件并調(diào)用 WindowInfoTracker.getOrCreate(this@MainActivity),以初始化與當(dāng)前 activity 相關(guān)聯(lián)的 WindowInfoTracker 實(shí)例:
import androidx.window.layout.WindowInfoTracker private lateinit var windowInfoTracker: WindowInfoTracker override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity) }
3)、設(shè)置應(yīng)用界面
通過(guò) Jetpack WindowManager,我們能夠獲取窗口指標(biāo)、布局和顯示配置的相關(guān)信息。讓我們?cè)谥?activity 布局中顯示這些信息(針對(duì)每項(xiàng)信息分別使用一個(gè) TextView)。
為此,我們需要一個(gè) ConstraintLayout,其中包含三個(gè) TextView,并在屏幕上居中。
打開 activity_main.xml 文件,然后粘貼以下內(nèi)容:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/constraint_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/window_metrics" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="20dp" tools:text="Window metrics" android:textSize="20sp" app:layout_constraintBottom_toTopOf="@+id/layout_change" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_chainStyle="packed" /> <TextView android:id="@+id/layout_change" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="20dp" tools:text="Layout change" android:textSize="20sp" app:layout_constrainedWidth="true" app:layout_constraintBottom_toTopOf="@+id/configuration_changed" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/window_metrics" /> <TextView android:id="@+id/configuration_changed" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="20dp" tools:text="Using one logic/physical display - unspanned" android:textSize="20sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/layout_change" /> </androidx.constraintlayout.widget.ConstraintLayout>
4)、直觀呈現(xiàn) WindowMetrics 信息
在 MainActivity 的 onCreate 方法中,我們將調(diào)用一個(gè)將在后續(xù)步驟中實(shí)現(xiàn)的函數(shù)。該函數(shù)將用于獲取和顯示 WindowMetrics 信息。首先,在 onCreate 方法中添加 obtainWindowMetrics() 調(diào)用:
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) windowInfoTracker = WindowInfoTracker.getOrCreate(this@MainActivity) obtainWindowMetrics() }
obtainWindowMetrics 方法:
import androidx.window.layout.WindowMetricsCalculator private fun obtainWindowMetrics() { val wmc = WindowMetricsCalculator.getOrCreate() val currentWM = wmc.computeCurrentWindowMetrics(this).bounds.flattenToString() val maximumWM = wmc.computeMaximumWindowMetrics(this).bounds.flattenToString() binding.windowMetrics.text = "CurrentWindowMetrics: ${currentWM}\nMaximumWindowMetrics: ${maximumWM}" }
運(yùn)行該應(yīng)用。根據(jù)您使用的可折疊設(shè)備,將得到不同的結(jié)果。例如,在雙屏設(shè)備模擬器中(如下圖所示),您會(huì)得到與模擬器所鏡像的設(shè)備尺寸對(duì)應(yīng)的 CurrentWindowMetrics。還可以查看應(yīng)用在單屏模式下運(yùn)行時(shí)的指標(biāo):
當(dāng)應(yīng)用跨顯示屏顯示時(shí),窗口指標(biāo)會(huì)發(fā)生變化(如下圖所示),因此它們現(xiàn)在反映的應(yīng)用所用窗口區(qū)域比之前大:
由于該應(yīng)用在單屏和雙屏設(shè)備上始終運(yùn)行并占滿整個(gè)顯示區(qū)域,因此當(dāng)前窗口指標(biāo)和最大窗口指標(biāo)的值相同。
在有水平折疊邊的可折疊設(shè)備模擬器中,這些值在應(yīng)用跨整個(gè)物理顯示屏運(yùn)行時(shí)和在多窗口模式下運(yùn)行時(shí)會(huì)有所不同:
5)、使用 Jetpack WindowManager 進(jìn)行測(cè)試
在任何模擬器或設(shè)備上測(cè)試可折疊設(shè)備的折疊狀態(tài),對(duì)于測(cè)試如何將界面元素放置在 FoldingFeature 周圍是非常有用的。WindowManger 附帶了一個(gè)非常實(shí)用的工件,以用于進(jìn)行插樁測(cè)試。我們來(lái)看看該工件的使用方式。應(yīng)用 build.gradle 文件中,我們不僅添加了主 WindowManager 依賴項(xiàng),還添加了測(cè)試工件:androidx.window:window-testing
window-testing 工件附帶有一個(gè)名為 WindowLayoutInfoPublisherRule 的實(shí)用的新 TestRule,它可以幫助您使用一系列 WindowLayoutInfo 值進(jìn)行測(cè)試。借助 WindowLayoutInfoPublisherRule,您可以按需推送不同的 WindowLayoutInfo 值。
為了使用它,并在此基礎(chǔ)上創(chuàng)建一個(gè)示例以幫助您使用此新工件來(lái)測(cè)試界面,我們將更新由 Android Studio 模板創(chuàng)建的測(cè)試類。將 ExampleInstrumentedTest 類中的所有代碼替換為以下代碼:
import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.window.testing.layout.WindowLayoutInfoPublisherRule import org.junit.Rule import org.junit.rules.RuleChain import org.junit.rules.TestRule import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class MainActivityTest { private val activityRule = ActivityScenarioRule(MainActivity::class.java) private val publisherRule = WindowLayoutInfoPublisherRule() @get:Rule val testRule: TestRule init { testRule = RuleChain.outerRule(publisherRule).around(activityRule) } }
我們來(lái)創(chuàng)建一項(xiàng)測(cè)試,用于檢查相應(yīng)實(shí)現(xiàn)是否正確無(wú)誤。創(chuàng)建一項(xiàng)名為 testText_is_left_of_Vertical_FoldingFeature 的測(cè)試:
@Test fun testText_is_left_of_Vertical_FoldingFeature() { activityRule.scenario.onActivity { activity -> val hinge = FoldingFeature( activity = activity, state = FoldingFeature.State.FLAT, orientation = FoldingFeature.Orientation.VERTICAL, size = 2 ) val expected = TestWindowLayoutInfo(listOf(hinge)) publisherRule.overrideWindowLayoutInfo(expected) } onView(withId(R.id.layout_change)).check( PositionAssertions.isCompletelyLeftOf(withId(R.id.folding_feature)) ) }
我們可以在設(shè)備或模擬器上運(yùn)行測(cè)試,以檢查應(yīng)用的行為是否符合預(yù)期。這個(gè)測(cè)試無(wú)需使用可折疊設(shè)備或模擬器即可運(yùn)行。
四、總結(jié)
可折疊和雙屏設(shè)備不再是實(shí)驗(yàn)性的或未來(lái)主義的--大的顯示區(qū)域和額外的姿勢(shì)具有被證實(shí)的用戶價(jià)值,而且現(xiàn)在有更多的設(shè)備可以供你的用戶使用??烧郫B設(shè)備和雙屏設(shè)備代表了智能手機(jī)的自然進(jìn)化。對(duì)于安卓開發(fā)者來(lái)說(shuō),他們提供了進(jìn)入一個(gè)正在增長(zhǎng)的高端市場(chǎng)的機(jī)會(huì),這也得益于設(shè)備制造商的重新關(guān)注,而我們使用Jetpack WindowManager和WindowSizeClass來(lái)促進(jìn)可折疊手機(jī)的發(fā)展,Google帶來(lái)的開發(fā)工具真的越來(lái)越高效便捷。
到此這篇關(guān)于Android使用Jetpack WindowManager來(lái)開發(fā)可折疊設(shè)備的探索的文章就介紹到這了,更多相關(guān)Android使用Jetpack WindowManager內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
webview添加參數(shù)與修改請(qǐng)求頭的user-agent實(shí)例
這篇文章主要介紹了webview添加參數(shù)與修改請(qǐng)求頭的user-agent實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03Android?Studio中如何修改APP圖標(biāo)和APP名稱
這篇文章主要介紹了Android?Studio中如何修改APP圖標(biāo)和APP名稱,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11Android 自定義按鈕點(diǎn)擊事件和長(zhǎng)按事件對(duì)比
這篇文章主要介紹了 Android 自定義按鈕點(diǎn)擊事件和長(zhǎng)按事件對(duì)比的相關(guān)資料,需要的朋友可以參考下2017-04-04Android開發(fā)之項(xiàng)目模塊化實(shí)踐教程
這篇文章主要給大家介紹了關(guān)于Android開發(fā)之項(xiàng)目模塊化的相關(guān)資料,文中通過(guò)示例代碼給各位Android開發(fā)者們介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)下吧。2017-09-09Android開發(fā)之StackView用法和遇到的坑分析
這篇文章主要介紹了Android開發(fā)之StackView用法和遇到的坑,結(jié)合實(shí)例形式分析了Android StackView圖片操作用法及常見問(wèn)題解決方法,需要的朋友可以參考下2019-03-03Android切換至SurfaceView時(shí)閃屏(黑屏閃一下)以及黑屏移動(dòng)問(wèn)題的解決方法
本文主要介紹了Android切換至SurfaceView時(shí)閃屏(黑屏閃一下)以及黑屏移動(dòng)問(wèn)題的解決方法。具有一定的參考作用,下面跟著小編一起來(lái)看下吧2017-01-01詳解Android創(chuàng)建Handler的必備知識(shí)點(diǎn)
本篇文章主要介紹Handler中需要了解的幾個(gè)必備知識(shí)點(diǎn),比如Handler創(chuàng)建、異步Handler是個(gè)啥及如何創(chuàng)建,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下2022-10-10android的RecyclerView實(shí)現(xiàn)拖拽排序和側(cè)滑刪除示例
在平時(shí)開發(fā)應(yīng)用的時(shí)候,經(jīng)常會(huì)遇到列表排序、滑動(dòng)刪除的需求。這篇文章主要介紹了android的RecyclerView實(shí)現(xiàn)拖拽排序和側(cè)滑刪除示例,有興趣的可以了解一下。2017-02-02