【Android Developers Training】 21. 创建一个

系统 1904 0

注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

原文链接: http://developer.android.com/training/basics/fragments/fragment-ui.html


当你在设计你的应用时,为了支持不同的屏幕尺寸,你可以在不同的布局配置中重用你的fragment,以此在可用的屏幕空间上获得最优化的用户体验。

例如,在一个手持设备上,以单一窗格每次只显示一个fragment也许是一个不错的选择。相对应的,你也许希望在屏幕更大的平板设备上并排显示多个fragment,为用户显示更多的信息。

图1. 两个fragment,在不同屏幕尺寸上隶属于同一个activity的显示效果。在大屏幕上,两个fragment可以同时并排显示。但在手持设备上,同一时间只能容纳一个fragment,所以当用户进行操作时,必须令fragment相互替换。

FragmentManager 类提供了允许你在运行时为一个activity添加,删除和替换fragments的方法,以此来创建一个动态的用户体验。

 

一). 在运行时为一个activity添加一个fragment

与上一节课中在XML布局文件内通过 <fragment>标签 为一个activity定义一个fragment有所不同,你可以在运行时为一个activity添加一个fragment。如果你计划着在activity的生命周期过程中改变fragment,那么这么做是必要的。

为了实现诸如添加或删除一个fragment的事务,你必须使用 FragmentManager 来创建一个 FragmentTransaction ,它提供了添加,删除,替换fragment的APIs,同时还有其他fragment相关的事务。

如果你的activity允许fragments可以被删除或者替换,你应该在activity的 onCreate() 方法中,将初始化好的fragment添加至activity。

一个处理fragment时(尤其是你在运行时添加一个fragment)的关键的规则是:该fragment必须在布局中有一个 View 容器,fragment的布局将会放置于其中。

下面的布局是上一节课中所展示的布局的另一个形式,它在同一时刻只显示一个fragment。为了将一个fragment替换成另外一个,这个activity的布局包含了一个空的 FrameLayout ,它的作用相当于一个fragment容器。

注意到这里的文件名和上一节课中的那个例子是一样的,但是布局文件的目录路径中不包含“ 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中,如果使用的是 Support Library APIs,可以 调用 getSupportFragmentManager() 来获得一个 FragmentManager 。之后调用 beginTransaction() 来创建一个 FragmentTransaction ,然后调用 add() 来添加一个fragment。

你可以通过使用相同的 FragmentTransaction ,来为这个activity执行多个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 a new Fragment to be placed in the activity layout
      
      

            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已经在运行时被添加至 FrameLayout 这一容器,而不是在activity的布局中通过 <fragment>标签进行定义的,所以activity可以用一个不同的fragment去替换它。

 

二). 用一个不同的fragment进行替换

替换一个fragment的过程和添加一个基本类似,区别在于需要的是 replace() 方法而不是 add() 方法。

记住当你执行一个fragment事务(比如替换或删除)时,最好允许用户可以进行撤销操作。为了实现用户的撤销,你必须在提交 FragmentTransaction 之前,执行 addToBackStack() 方法。

Note:

当你删除或者替换了一个fragment,然后将这个事务添加至后退栈(back stack),被删除的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() 方法接受一个可选的string参数,它用来为这个事务指定一个唯一的名字。这个名字不是必须的,除非你打算使用 FragmentManager.BackStackEntry 中的APIs来执行一些高阶fragment操作。

【Android Developers Training】 21. 创建一个可变动的UI


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论