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

Android培训---创建灵活的UI

2013-01-24 20:24 337 查看
本文译自:http://developer.android.com/training/basics/fragments/fragment-ui.html

当要把应用程序设计成支持大多数屏幕尺寸的时候,你可以在不同的布局配置中复用你的Fragment,并基于可用的屏幕空间来优化用户体验。

例如,在手持设备上,它可能每次只适合显示一个Fragment作为用户界面。相反,在平板电脑上,你可能想要一组Fragment彼此相连,把更多的信息显示给用户。



图1.在不同屏幕尺寸上的同一个Activity中使用不同的配置来显示两个Fragment。在大屏幕上,两个Fragment彼此相连同时显示,但是在手持设备上,每次只会显示一个Fragment,因此在用户浏览时,两个Fragment必须交替的来显示。

为了创建动态的体验,FragmentManager类提供了在运行时添加、删除、替换Fragment的方法。

在运行是把一个Fragment添加给Activity

相比在布局文件中给Activity定义Fragment而言,你可以在Activity运行期间把Fragment添加给Activity。如果你打算在Activity生存期间来改变Fragment,这样做是必须。

要执行诸如添加或删除Fragment这样的事务处理,你必须使用FragmentManager来创建一个FragmentTransaction,它提供了添加、删除、替换以及其他Fragment事务处理的API。

如果你的Activity允许删除和替换Fragment,你应该在Activity的onCreate()方法执行期间把初始的Fragment添加给Activity。

处理Fragment时的一个重要规则---尤其是在运行时添加的那些Fragment---它们必须要有一个View布局容器,这个布局容器将会包含该Fragment的布局。

下面的布局是上节课所示布局的一个替代方案,它每次只显示一个Fragment。为了让一个Fragment替换另一个Fragment,Activity的布局包含了一个作为Fragment容器的空的FrameLayout

注意,文件名与上节课中布局文件名相同,但布局目录中没有large限定符,因此当设备屏幕比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内部,调用getSupportFragmentManager()方法来获得支持类库API所使用的FragmentManager对象。然后调用beginTransaction()方法来创建FragmentTransaction,并调用add()方法来添加一个Fragment。

对于一个Activity,你可以使用相同的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);
 
       
// Check that the activity is using the layout version with
       
// the fragment_container FrameLayout
       
if (findViewById(R.id.fragment_container) != null) {
 
           
// However, if we're being restored from a previous state,
           
// then we don't need to do anything and should return or else
           
// we could end up with overlapping fragments.
           
if (savedInstanceState != null) {
               
return;
           
}
 
           
// Create an instance of ExampleFragment
           
HeadlinesFragment firstFragment = new HeadlinesFragment();
           

           
// In case this activity was started with special instructions from an Intent,
           
// pass the Intent's extras to the fragment as arguments
           
firstFragment.setArguments(getIntent().getExtras());
           

           
// Add the fragment to the 'fragment_container' FrameLayout
           
getSupportFragmentManager().beginTransaction()
                   
.add(R.id.fragment_container, firstFragment).commit();
       
}
   
}
}

 

因为该Fragment是在运行时被添加到FragmentLayout容器中,而不是在Activity的布局中用<fragment>元素来定义的,所以该Activity可以删除该Fragment,并用另一个Fragment来替换它。

用另一个Fragment来替换

替换Fragment的过程与添加过程类似,但是它需要使用replace()方法而不是add()方法。

要记住,在执行Fragment事务时,如替换或删除,要适当的允许用户返回和取消改变。要允许用户返回Fragment事务,在你提交FragmentTransaction之前,你必须调用addToBackStack()方法。

注意:当你删除或替换一个Fragment,并把该事务添加到回退堆栈时,被删除的Fragment会被终止(而不是销毁)。如果用户返回来恢复该Fragment,那么该Fragment就会重启。如果你没有把事务添加到回退堆栈,那么该Fragment就会在删除或替换时被销毁。

用另一个Fragment来替换一个Fragment的示例:

// Create fragment and give it an argument specifying the article it should show
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
 
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
 
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
 
// Commit the transaction
transaction.commit();

 

addToBackStack()方法需要一个可选的字符串参数,用于指定该事务的唯一名称。除非你打算使用FragmentManager.BackStackEntry的API来执行高级的Fragment操作,否则不需要指定这个唯一名称。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: