![](/img/trans.png)
[英]Android: making layouts in the activity's fragment, if not using several fragments
[英]Fragment design: Adapting to multiple screen layouts by showing/hiding fragments within a single Activity?
我試圖了解如何使用片段來創建能夠很好地適應多種屏幕和布局的應用程序。 我研究了幾個例子:
所有這些都提倡多Activity
方法:
Activity
和多個Fragment
Fragment
拆分到多個Activity
中。 我想到了另一種方法 - 一個單一的Activity
:
Fragment
的Activity
。Fragment
(使用FragmentTransaction.show()
/ FragmentTransaction.hide()
)。以 Android 開發人員指南使用的相同“新聞文章列表/文章內容”示例進行說明:
News
活動同時包含ArticleListFragment
和ArticleReaderFragment
。ArticleReaderFragment
最初是隱藏的。 從列表中選擇文章時,隱藏ArticleListFragment
並顯示ArticleReaderFragment
。 有人使用過類似的方法嗎? 這種方法可能有任何實際的缺點嗎? 與多活動方式相比,它看起來更好/更差嗎? 例如,不能在 XML 中顯示/隱藏片段 - 為此必須使用FragmentTransaction
。
想象一個可以在屏幕上同時顯示最多三個“窗格”的應用程序。 此外,這些是要考慮的因素:
為簡單起見,讓我們將電視屏幕排除在討論之外。
現在,將其轉化為設計:
到目前為止,我們還沒有考慮任何與 Android 開發人員指南中提供的新聞閱讀器示例有顯着不同的地方。 唯一的主要區別是有三個片段而不是兩個。
現在,7 英寸的表殼只能容納 2 個碎片。 這將如何工作? 請注意,這里有兩種可能的組合:
我只是無法解決這個問題。 我是否在 ActivityA 中執行所有這些操作? 我只是創建一個全新的 ActivityD 嗎? 我需要創建多少個布局(我數了數大約 8 個)? 是不是排列太多了?
我確實意識到我上面提出的單一活動方法可能也不適合這種情況——因為顯示/隱藏片段本身是非常重要的。
關於如何在不被布局和組合淹沒的情況下處理這個問題的任何建議?
@Taylor Clark 的回答非常有用。 但是,這並不是我在原始問題中提出的使用單一活動方法的實際經驗分享。 我着手修改 Android 開發人員指南中的新聞閱讀器示例以使用單活動方法,並提出了一個可行的解決方案。
還有待觀察的是,在哪些用例中這種方法比多活動方法更可取(或者是否存在任何此類情況)。 此外,我還沒有詳細查看我的問題的編輯 1 中描述的 3 窗格場景。
我希望盡快發布我的整個項目,但這里是我如何進行的快速概述:
Activity
:NewsActivityTitlesListFragment
和DetailsFragment
NewsActivity
中。 根據當前的雙窗格,我顯示/隱藏適當的片段。我遇到的一些問題:
是否將布局指定為雙窗格:
在原始新聞閱讀器示例中,雙窗格布局有一個FrameLayout
用於保存新聞詳細信息。 我們通過測試此框架布局的存在來確定我們當前是否處於雙窗格布局中。
但是,在我的解決方案中,這兩個片段始終存在於所有布局中。 我dualPane
View
android:visibility="gone"
的視圖並在單窗格布局中省略這個視圖來解決這個問題。 然后,這是一個問題
mDualPane = findViewById(R.id.dualPane);=null;
編輯:
有比虛擬視圖更好的方法來指定雙窗格。 我更喜歡的方法是創建一個 boolean 資源。 比如我有一個config.xml
如下:
<resources>
<bool name="dual_pane">false</bool>
</resources>
然后,我可以將其他config.xml
文件放在values-xlarge-land
、 values-port
或values-sw600dp
等文件夾中,並根據需要將 boolean 值調整為true
或false
。
然后,在代碼中是getResources().getBoolean(R.bool.dual_pane);
的問題。
關閉詳細信息片段
這是區分Activity
關閉和Fragment
關閉的問題。 最后,我不得不重寫onBackPressed()
如下:
super.onBackPressed()
;TitlesListFragment
中,調用super.onBackPressed()
;DetailsFragment
中,則將其視為關閉片段。 這意味着隱藏它並顯示TitlesListFragment
。這並不理想,但這是我能想到的最好的。
編輯:
根據@SherifelKhatib 在評論中的建議,有一種更簡潔的方法來處理后退按鈕按下:只需將顯示/隱藏細節片段的事務添加到 Fragment backstack。 這樣,當您按下后退按鈕時,片段事務將被撤銷。 如果您希望在其他按鈕點擊時這樣做,您也可以手動彈出后退堆棧。
通常,應用程序被拆分為活動,因為每個活動都代表用戶可以執行的特定“事情”。 例如,在 email 應用程序中,定義的一組操作可以是:
每個動作都可以是它自己的活動,顯示單個(或一組)片段。 但是,如果您有屏幕空間,那么將消息列表的查看和消息詳細信息合並到一個可以顯示/隱藏“詳細視圖”片段的活動中是有意義的。 本質上,片段允許您一次向用戶顯示多個“活動”。
做決定時要考慮的事項:
我通常對平板電腦版本的應用程序采用“多片段方法”,對手機采用“每個活動一個片段”,這聽起來與您列出的第一種方法一致。 並不是說第二個沒有時間和地點,但我可以看到實施很快變得一團糟!
抱歉冗長的回復? 也許您可以詳細說明您的具體用例? 希望這可以幫助!
以下是我想象的如何設置您的應用程序項目:
源文件:
yourapp.package.phone: NewsActivity1, NewsActivity2, NewsActivity3
yourapp.package.tablet:NewsMultipaneActivity
資源
布局/
activity_news.xml- phone version, only includes Fragment1
activity_news_detail.xml- phone version, only includes Fragment2
activity_news_<something>.xml- phone version, only includes Fragment3
布局-大/
activity_news.xml- 7" tablet version, includes Fragment2 and an empty fragment container. Split vertically
布局大地/
activity_news.xml- same as layout-large, but with the split being horizontally
布局-xlarge-土地/
activity_news.xml- 10"+ tablet version, contains all three fragments split horizontally
那么這里發生了什么?
只要文件名相同,Android 就會根據屏幕大小和方向為您交換布局。 因為 Fragment2 將始終顯示,您可以將其“硬編碼”到您的平板電腦布局中。 然后可以根據需要使用FragmentTransactions在容器中的Fragment1和Fragment3之間切換
請務必查看http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources了解如何利用資源限定符來減輕不同屏幕和方向的一些麻煩
感謝您提出這個問題和您的見解。 在遇到問題之前,我一直使用多活動方法。 我的應用程序就像文檔示例新聞閱讀器。 考慮這種情況:
發生了什么? 活動 B 正在顯示全尺寸的文章,而我當然想 go 回到兩個窗格。 我不確定如何很好地解決這個問題。 當然,活動 B 可能會檢查多窗格模式並自行完成,活動 A 可能會檢查最后顯示的文章是什么……看起來很難看。 想法?
PS 我懷疑 GMail 應用程序使用單一活動方法。 當我從列表中發送電子郵件 select 時,我沒有看到任何活動轉換。 它在我描述的場景中也表現得很好。
在本文http://developer.android.com/guide/practices/tablets-and-handsets.html#Fragments Google 中說:
“你選擇的方法取決於你的設計和個人喜好。”
和
“然而,其他時候,為您的手機設計動態交換片段會使您的代碼更加復雜,因為您必須管理活動代碼中的所有片段組合(而不是使用替代布局資源來定義片段組合)並管理后台堆棧自己碎片化(而不是讓正常的活動堆棧處理返回導航)。”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.