• Android


    当设计程序来支持各种不一样的屏幕尺寸时,可以在不同的布局中重用fragment来根据可用的屏幕大小来优化用户体验。

    例如,在手机上可能使用一个fragment来使用单窗口用户体验比较合适。但是,你可能想在平板上边靠边的设置两个fragment因为有更宽的屏幕向用户展示更多信息。

     

     图1.两个fragment,同一个activity在不同的屏幕大小上的不同展现形式。在大屏幕上,两个fragment边靠边,但是在手机设备上,一次只显示一个fragment因此fragment在用户切换的时候替换另一个。

    为了创建动态的体验, FragmentManager类提供了方法可以在运行时添加,删除,替换activity中的fragment。

    在运行时向activity添加fragment

    不仅仅可以在activity布局文件中定义fragment(前面介绍了使用<fragment>元素),也可以在activity运行时加入fragment。如果计划在activity运行时改变fragment,这个很有必要。

    要处理添加删除fragment,可以使用FragmentManager来创建一个FragmentTransation,它提供了API来添加,替换和fragment的其他事务。

    如果activity允许fragment删除或者替换,应该在activity的onCreate()方法中添加fragment的初始化信息。

    处理fragment有一个重要的规则,特别是在运行时添加的fragment:fragment在布局中必须有一个View容器。

    下面的布局是上一篇中布局的一个变形,这里一次只显示一个fragment。为了用一个fragment替换另一个,这个activity的布局包含一个空的FrameLayout作为fragment的容器。

    这个文件名和前面一篇中布局的文件名是一样的,但是布局文件夹没有large标识,所以这个布局使用在小屏幕上因为小屏幕不需要同时显示两个fragment。

    res/layout/news_articles.xml:

    1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2     android:id="@+id/fragment_container"
    3     android:layout_width="match_parent"
    4     android:layout_height="match_parent" />

    在activity中,使用Support Library中的API getSupportFragmentManager()来获得FragmentManager.然后调用beginTransaction()来创建一个FragmentTransaction再调用add()添加一个fragment。

    可以使用一个FragmentTransaction来处理多个activity的fragment rransaction。当准备好执行这些改变后,调用commit()。

    例如,这里展示了如何把fragment加到前一个布局上:

     1 import android.os.Bundle;
     2 import android.support.v4.app.FragmentActivity;
     3                                                       
     4 public class MainActivity extends FragmentActivity {
     5     @Override
     6     public void onCreate(Bundle savedInstanceState) {
     7         super.onCreate(savedInstanceState);
     8         setContentView(R.layout.news_articles);
     9                                                      
    10                                             
    11         //检查activity的布局是使用fragment_container FrameLayout的版本
    12         if (findViewById(R.id.fragment_container) != null) {
    13                                                       
    14             // 但是,如果是从前一个状态恢复的话
    15             // 我们不需要做任何事情,直接返回就行了,否则就会重叠fragments。
    16             if (savedInstanceState != null) {
    17                 return;
    18             }
    19                                                       
    20             //创建一个Fragment实例
    21             HeadlinesFragment firstFragment = new HeadlinesFragment();
    22                                                                   
    23             //有可能activity是从Intent中的特殊指令创建的,
    24             //把Intent的extras当参数传递给fragment
    25             firstFragment.setArguments(getIntent().getExtras());
    26                                                                   
    27             // 把fragment加入到'fragment_container' FrameLayout
    28             getSupportFragmentManager().beginTransaction()
    29                     .add(R.id.fragment_container, firstFragment).commit();
    30         }
    31     }
    32 }


    因为fragment是在运行时加入到FrameLayout的(不是在activity的布局文件中用<fragment>定义的),activity就可以移出这个fragment然后用一个不同的替换它。

    用一个fragment替换另一个

    换掉一个fragment的方法和添加一个相似,但是需要使用replace()方法,而不是add()

    记住当执行fragment切换时,例如添加或者删除,经常要允许用户切换回去来恢复这些改变。为了允许用户在fragment切换时切换回去,应该在提交FragmentTransaction之前调用addToBackStack()。

    注意:当移除或者替换一个fragment然后加到切换的返回堆栈中时,被移除的fragment是Stopped状态(并不是Destroyed)。如果用户切换回去来恢复fragment,它就重启。如果没有把它加到返回堆栈中,fragment被移除或者替换时就销毁了。

    用一个fragment替换另一个的例子:

     1 //创建一个fragment,然后把应该展示的文章的参数传给它
     2 ArticleFragment newFragment = new ArticleFragment();
     3 Bundle args = new Bundle();
     4 args.putInt(ArticleFragment.ARG_POSITION, position);
     5 newFragment.setArguments(args);
     6                                     
     7 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
     8                                     
     9 //用这个fragment替换掉fragment_container view 中的东西,
    10 //然后把transaction加到返回堆栈中,这样用户就可以切换回去了
    11 transaction.replace(R.id.fragment_container, newFragment);
    12 transaction.addToBackStack(null);
    13                                     
    14 //提交transaction
    15 transaction.commit();

    addToBackStack()方法带一个可选的字符串参数,用来指定一个唯一的transaction名字。这个名字并不是必需的除非需要用FragmentManager.BackStackEntryAPI的一些特使操作。

    上一篇:Android - 用Fragments实现动态UI - 创建Fragment

    下一篇:Android - 用Fragments实现动态UI - 和其他Fragments通信

  • 相关阅读:
    28
    27
    26
    25
    24
    23
    17
    16
    15
    14
  • 原文地址:https://www.cnblogs.com/fengquanwang/p/3142646.html
Copyright © 2020-2023  润新知