Android Training - 使用碎片创建一个动态UI(3) - 构建一个灵活的UI
当设计你的程序去支持大部分屏幕尺寸时,你可以在不同的布局文件中复用你的碎片,在不同的屏幕空间中优化你的用户体验。
例如,手机中可能一次只适合显示一个碎片,相反的,在大屏幕设备中,你可能想在一个界面中挨着显示很多个碎片。
图解:一个activity在不同屏幕尺寸的显示效果。在大屏幕中,两个碎片紧挨着显示,在手机中,一次只显示一个碎片。
FragmentManager类提供一些函数,让你可以在程序运行时添加,删除和替换碎片,从而产生动态显示效果。
运行中添加一个碎片上一个教程中,我们在XML文件中添加碎片,不同的是,你现在可以在activity运行期间添加一个碎片,在activity生命周期中改变碎片是非常有必要的。
要实现碎片的添加和删除,你需要使用FragmentManager去创建一个FragmentTransaction,它提供API去添加,删除,替换和执行其他碎片转换。
如果你想允许碎片被移除和替换,你需要在activity的onCreate()函数中初始化碎片。
一个重要的规定是:要操作碎片,尤其是运行中添加碎片,碎片必须有一个view容器,这个容器包含了碎片的布局。
下面这个布局和上一个课程的有所不同,它一次只显示一个碎片。为了能用其他碎片替换这一个碎片,activity布局需要包含一个空的FrameLayout碎片容器。
需要提醒的是,下面的文件名和上一课的一样,但是目录没有large限定符,所以,这个布局是当设备屏幕尺寸小于large的时候才会被应用,因为屏幕太小,不够同时显示多个碎片。
res/layout/news_articles.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" />在你的activity中,调用getSupportFragmentManager()去取得一个FragmentManager。然后调用beginTransaction()去创建一个FragmentTransaction,再调用add()去添加一个碎片。
import..Bundle;import....FragmentActivity;publicclassMainActivityextendsFragmentActivity{@Overridepublicvoid(Bundle){super.();(..);// 检查activity使用的布局中是否有碎片容器if((..)!=null){// 如果我们只是恢复先前的状态,// 那么我们什么都不用做,只是返回或者我们可以覆盖先前的碎片if(!=null){return;}// 创建一个碎片实例HeadlinesFragment=newHeadlinesFragment();// 使用特别的指令从一个Intent开始一个activity,// 把Intent中附加的数据做为碎片的参数。.(().());// 添加碎片到碎片容器中。().().(..,).();}}}因为随便是在运行中被添加到FrameLayout容器中的,所以activity可以用一个不同的碎片替换它,或者是删除它。
// 创建一个碎片,传递一个参数给它,指定显示的内容。ArticleFragment newFragment = new ArticleFragment();Bundle args = new Bundle();args.putInt(ArticleFragment.ARG_POSITION, position);newFragment.setArguments(args);FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();// 替换碎片容器中的碎片,// 添加操作到后退堆栈中,以便用户可以返回。transaction.replace(R.id.fragment_container, newFragment);transaction.addToBackStack(null);// 提交操作transaction.commit();addToBackStack()函数需要传递一个字符串参数,为操作指定一个独一无二的名称,这个名称不是必须的,除非你计划开始使用FragmentManager.BackStackEntryAPI执行高级的碎片操作。