Android官方开发文档Training系列课程中文版:多样屏幕之实现自适应UI
原文地址:http://android.xsoftlab.net/training/multiscreen/adaptui.html
基于程序當前所顯示的布局來說,UI流程可能會有所不同。比如說,如果程序當前處于多面板模式,點擊左面板中的項目會直接在右面版中顯示具體的內容;如果當前是單面板模式,那么具體的內容則會在新的頁面中顯示。
檢查當前的布局
因為每種布局的實現可能會有所不同,所以首先要做的事情就是檢查用戶當前使用的是哪種布局。比如說,你可能需要知道用戶當前處于”單面板”模式還是”多面板”模式。你可以通過查詢給定的View是否存在及是否可見的方式來得知當前的模式。
public class NewsReaderActivity extends FragmentActivity {boolean mIsDualPane;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main_layout);View articleView = findViewById(R.id.article);mIsDualPane = articleView != null && articleView.getVisibility() == View.VISIBLE;} }注意這部分代碼在查詢”article”面板是否可用,這要比查詢指定布局的方式要靈活的多。
如何適配不同的組件的另一個示例是通過檢查這些組件是否可用的方式來完成的。比如說,在新聞閱讀APP中,有一個用于打開菜單的按鈕,但是這個按鈕只在3.0以上的版本才有。所以,如果要為這個按鈕添加監聽器,你可以這么做:
Button catButton = (Button) findViewById(R.id.categorybutton); OnClickListener listener = /* create your listener here */; if (catButton != null) {catButton.setOnClickListener(listener); }根據當前的布局做出響應
一些行為可能基于當前的布局產生不同的結果。比如說,在新聞閱讀APP中,點擊任意一條新聞標題,在多面板模式中,具體文章則會出現在右面板中,但是在單面板模式中,則會啟動一個新的Activity來顯示這些文章。
@Override public void onHeadlineSelected(int index) {mArtIndex = index;if (mIsDualPane) {/* display article on the right pane */mArticleFragment.displayArticle(mCurrentCat.getArticle(index));} else {/* start a separate activity */Intent intent = new Intent(this, ArticleActivity.class);intent.putExtra("catIndex", mCatIndex);intent.putExtra("artIndex", index);startActivity(intent);} }同樣的,如果APP當前處于多面板模式,那么應該設置帶有tab的ActionBar用于導航,然而,在單面板模式下,就應當設置帶有spinner的導航控件。所以代碼中還應當檢查當前是哪種情況:
final String CATEGORIES[] = { "Top Stories", "Politics", "Economy", "Technology" }; public void onCreate(Bundle savedInstanceState) {....if (mIsDualPane) {/* use tabs for navigation */actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_TABS);int i;for (i = 0; i < CATEGORIES.length; i++) {actionBar.addTab(actionBar.newTab().setText(CATEGORIES[i]).setTabListener(handler));}actionBar.setSelectedNavigationItem(selTab);}else {/* use list navigation (spinner) */actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_LIST);SpinnerAdapter adap = new ArrayAdapter(this, R.layout.headline_item, CATEGORIES);actionBar.setListNavigationCallbacks(adap, handler);} }重用Fragment
在設計多面板的應用時會反復出現的一個場景,有一部分UI在一種屏幕配置中以面板的形式出現,而在其它的配置中,又是以獨立的Activity出現。
在類似這種情況下,你可以通過重用Fragment的方式來避免代碼冗余。比如,ArticleFragment就用于多面板的情況:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="horizontal"><fragment android:id="@+id/headlines"android:layout_height="fill_parent"android:name="com.example.android.newsreader.HeadlinesFragment"android:layout_width="400dp"android:layout_marginRight="10dp"/><fragment android:id="@+id/article"android:layout_height="fill_parent"android:name="com.example.android.newsreader.ArticleFragment"android:layout_width="fill_parent" /> </LinearLayout>在小屏幕中,又被Activity重用:
ArticleFragment frag = new ArticleFragment(); getSupportFragmentManager().beginTransaction().add(android.R.id.content, frag).commit();上面的代碼與在XML布局中聲明Fragment含有相同的效果,但是這種情況下XML布局就沒必要工作了,因為article Fragment作為了這個Activity的組件。
一個非常重要的點要記住,在設計Fragment時不要與指定的Activity產生強耦合。你可以通過定義接口的方式來使Fragment與宿主Activity產生交互,宿主Activity需要實現這個接口:
public class HeadlinesFragment extends ListFragment {...OnHeadlineSelectedListener mHeadlineSelectedListener = null;/* Must be implemented by host activity */public interface OnHeadlineSelectedListener {public void onHeadlineSelected(int index);}...public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener listener) {mHeadlineSelectedListener = listener;} }因此,當用戶選擇了一條新聞時,Fragment通過接口的方式來通知宿主Activity:
public class HeadlinesFragment extends ListFragment {...@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {if (null != mHeadlineSelectedListener) {mHeadlineSelectedListener.onHeadlineSelected(position);}}... }處理屏幕配置變更
如果使用了單獨的Activity實現了UI的獨立部分,那么要記得響應某些配置的變化,比如屏幕旋轉,以便保持UI的一致性。
比如說,一款運行Android 3.0系統的7英寸平板,新聞閱讀APP在垂直模式下使用的是獨立的Activity展示文章的內容,但是在水平模式下使用的是多面板模式。
如果用戶當前處于垂直模式下,那么需要檢查方向更改為了水平模式,并需要通過結束結尾Activity并返回MainActivity的方式來讓內容展示于雙面板模式:
public class ArticleActivity extends FragmentActivity {int mCatIndex, mArtIndex;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mCatIndex = getIntent().getExtras().getInt("catIndex", 0);mArtIndex = getIntent().getExtras().getInt("artIndex", 0);// If should be in two-pane mode, finish to return to main activityif (getResources().getBoolean(R.bool.has_two_panes)) {finish();return;}... }總結
以上是生活随笔為你收集整理的Android官方开发文档Training系列课程中文版:多样屏幕之实现自适应UI的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 优化器
- 下一篇: Android官方开发文档Trainin