Android Training - 使用碎片创建一个动态UI(3) - 构建一个灵活的UI

来源:互联网 发布:云计算与大数据技术 编辑:程序博客网 时间:2024/04/29 19:53
当设计你的程序去支持大部分屏幕尺寸时,你可以在不同的布局文件中复用你的碎片,在不同的屏幕空间中优化你的用户体验。

例如,手机中可能一次只适合显示一个碎片,相反的,在大屏幕设备中,你可能想在一个界面中挨着显示很多个碎片。

图解:一个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()去添加一个碎片。

你可以使用FragmentTransaction去处理多个碎片,当你确认好要改变碎片时,你必须调用commit()。

例如,下面演示了怎么添加一个碎片:
import android.os.Bundle;import android.support.v4.app.FragmentActivity;public class MainActivity extends FragmentActivity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.news_articles);        // 检查activity使用的布局中是否有碎片容器        if (findViewById(R.id.fragment_container) != null) {            // 如果我们只是恢复先前的状态,            // 那么我们什么都不用做,只是返回或者我们可以覆盖先前的碎片            if (savedInstanceState != null) {                return;            }            // 创建一个碎片实例            HeadlinesFragment firstFragment = new HeadlinesFragment();                        // 使用特别的指令从一个Intent开始一个activity,            // 把Intent中附加的数据做为碎片的参数。            firstFragment.setArguments(getIntent().getExtras());                        // 添加碎片到碎片容器中。            getSupportFragmentManager().beginTransaction()                    .add(R.id.fragment_container, firstFragment).commit();        }    }}
因为随便是在运行中被添加到FrameLayout容器中的,所以activity可以用一个不同的碎片替换它,或者是删除它。

用另外一个碎片替换当前碎片

替换一个碎片的步骤和添加一样简单,只需要把add改为replace就可以了。

记住,当你进行碎片操作时,比如替换或者删除,你需要让用户可以返回和撤销改变。为了实现这些,你需要在提交碎片操作前调用addToBackStack()。

提示:当你删除或者替换一个碎片,并且添加了这些操作在后退堆栈,碎片移除会被停止(没有被销毁),如果用户想返回恢复碎片,它就会被重新开启。如果没有加入后退堆栈,这个碎片就会在替换或者删除的时候被销毁。

替换的例子:
// 创建一个碎片,传递一个参数给它,指定显示的内容。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执行高级的碎片操作。