您的位置:首页 > 产品设计 > UI/UE

Training--使用Fragment创建动态UI(2)--构建一个灵活的UI

2014-07-10 15:10 585 查看
使用Fragment创建动态UI(2)--构建一个灵活的UI

 

当你想把你的app设计成一个可以支持各种屏幕尺寸的时候,你可以根据屏幕上可用的空间,在不同的布局文件里复用fragment,优化用户体验。

 

例如,在一个手持设备上,在单面板用户界面上可能更适合一次显示一个fragment。相反地,在平板上,由于屏幕宽度大,你也许可以挨个放置多个fragment来给用户显示更多地信息。

 


Figure 1. 两个fragment,在不同的屏幕尺寸下,同一个activity的显示设置是不一样的.在大屏幕下,适合同时显示两个fragment,
但是在手持设备上,一次最多适合显示一个fragment,所以当用户在界面上跳转的时候fragment必须相互代替显示
 

FragmentManager类提供在activity运行时,动态添加,删除和替换fragment。

 

运行时添加Fragment到Activity

 

相较于在布局文件中为一个activity定义fragment—如上节课所示使用<fragment>元素—你可以在activity运行时添加一个fragment。如果你计划在activity的生存期间改变fragment的话,这是非常有必要的。

 

为了执行一个事务,如添加和移除fragment,你必须使用FragmentManager去创建一个FragmentTransaction,它提供添加,移除,替换和执行其他fragment事务操作的API接口。

 

如果你的activity允许fragment被移除和替换,你应该在activity的onCreate()方法里添加初始的fragment。

 

一个比较重要的原则是当处理fragment的时候—尤其是那些运行时添加的—这些fragment必须在activity的布局文件中有一个容纳自己的容器view,fragment的布局就会寄宿在这个view里。

 

下面这个例子中的布局就是上节课展示的布局的另一个方案---一次只显示一个fragment。为了能够使用一个fragment替换另一个,这个activity的布局包含了一个空的FrameLayout作为fragment的容器。

 

注意到文件名和上节课的一模一样,但是布局所在的文件夹并没有large修饰符,所以这个布局文件当只有屏幕尺寸“小”的时候才会使用—因为小尺寸屏幕不能同时容纳两个fragment显示。

 

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中,使用支持库中的API接口getSupportFragmentManager()得到一个FragmentManager。然后调用beginTransaction()创建一个FragmentTransaction,再调用add()去添加一个fragment。

 

你可以使用同一个FragmentTransaction执行更多的fragment事务。当你决定要实施这些事务的时候,你必须调用commit()。

 

例如,下面是如何添加一个fragment到上面的布局中:

 

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的布局文件中是否包含有
// fragment_container FrameLayout
if (findViewById(R.id.fragment_container) != null) {

//然而,如果我们是从之前的状态中恢复的话(请参考前面的课程“重建一个activity”),
// 那么我们不需要做任何事情,否则
// 会重复叠加相同的fragment.
if (savedInstanceState != null) {
return;
}

// Create a new Fragment to be placed in the activity layout
HeadlinesFragment firstFragment = new HeadlinesFragment();

// 如果这个activity是通过某个特别的Intent启动的话,
// 把Intent的数据作为fragment的参数传进去
firstFragment.setArguments(getIntent().getExtras());

// 把fragment添加进 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
}
}
}

 

因为这个fragment是被动态添加到FrameLayout容器中的—而不是在activity的布局中使用<fragment>元素定义的—这个activity可以移除这个fragment或者使用别的fragment替换它。

 

使用一个fragment替换另一个

 

替换一个fragment的过程与添加的非常相似,但是需要使用方法replace()不是add()。

 

记住,当你执行fragment事务的时候,例如替换或者移除一个fragment,通常应该允许用户后退或者“撤销”这种变化。为了允许用户回退fragment事务,你必须在提交FragmentTransaction之前调用addToBackStack()。

 

注意:当你移除或者替换一个fragment的时候,并且把这个事务加入了事务回退栈,那么这个被移除的fragment将进入停止状态(而不是被销毁状态)。如果用户返回到这个fragment,它将重启。如果你没有把这个事务添加到回退栈,那么一个fragment被移除或者替换的时候,这个fragment就会被销毁。

 

下面是一个替换fragment的例子:

 

// 创建一个fragment,并传递一个参数指定显示哪篇文章
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

//使用新创建的fragment替换之前的fragment_container容纳的fragment,
//把事务加入回退栈,这样用户可以回退这个事务
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// 提交事务
transaction.commit();

 

addToBackStack()方法有一个可选参数,给某个事务指定唯一的名字。这个名字不是必须地,除非你想使用FragmentManager.BackStackEntry 的API接口做更高级的fragment相关的操作。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android sdk Training
相关文章推荐