用fragment创建动态组件

 fragment 是一种模块 可以在android中创建动态的多版面的界面布局。 Fragment 类对象是activity中的一个模块 就像一个小型的activity,可以定义自己的布局亦可以管理自己的生命周期。

当fragment指定你的布局的时候,fragment 可以根据屏幕尺寸  联合其他的frament  在activity中设置不同的排列组合 ,例如:在大屏幕的时候可以显示多个fragment,而在小屏幕的时候只显示一个fragment.

fragment可以创建动态的界面模块,优化用户体验支持不同尺寸的设备。


创建一个静态的fragment


我们要创建一个fragment ,需要集成Fragment类,复写生命周期中的回调方法,这个有点类似于activity类。

不同点是要定义一个Fragment类必须要调用回调方法onCreateView()来定义布局。  如果你想让fragment运行起来,你只需要重写这个回调方法就可以了。

例1:

   

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;

public class FirstFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.first_view, container, false);
    }
}
 

       当然fragment也可以继承  , 其他的回调方法,来管理fragment的生命周期。 当fragment所在的activity在不同的生命周期状态之间转化的时候,内部的fragment也发生改变,当activity调用onstop()方法时fragment 也调用onstop()方法。


res/layout/first_view.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/first"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:textSize="18sp" />


添加一个fragment到activity中去

res/layout-large/news_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <fragment android:name="com.example.android.fragments.SecondFragment"
              android:id="@+id/headlines_fragment"
              android:layout_weight="1"
              android:layout_width="0dp"
              android:layout_height="match_parent" />

    <fragment android:name="com.example.android.fragments.FirstFragment"
              android:id="@+id/article_fragment"
              android:layout_weight="2"
              android:layout_width="0dp"
              android:layout_height="match_parent" />

</LinearLayout>
注意:上述的xml的文件路径为res/layout-large/     意思是只有在大屏幕的设备上才会这个布局。


应用布局到activity中去

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_activity);
    }
}
当你使用的是 v7appcompat library库的时候,你应该继承的类是 AppCompatActivity

以上是在Activity中静态的添加fragment,不能随时添加或者移除fragment.


在运行时向 Activity 添加 Fragment

利用 FragmentManager 类提供的方法,你可以在运行时添加、移除和替换 Activity 中的 Fragment,以便为用户提供一种动态体验。

你可以在 Activity 运行时向其添加 Fragment,而不用像上一课中介绍的那样,使用 <fragment> 元素在布局文件中为 Activity 定义 Fragment。如果你打算在 Activity 运行周期内更改 Fragment,就必须这样做。

要执行添加或移除 Fragment 等事务,你必须使用 FragmentManager 创建一个 FragmentTransaction,后者可提供用于执行添加、移除、替换以及其他 Fragment 事务的 API。

如果 Activity 中的 Fragment 可以移除和替换,你应在调用 Activity 的 onCreate() 方法期间为 Activity 添加初始 Fragment(s)。

在处理 Fragment(特别是在运行时添加的 Fragment )时,请谨记以下重要规则:必须在布局中为 Fragment 提供 View 容器,以便保存 Fragment 的布局。

下面是上一课所示布局的替代布局,这种布局一次只会显示一个 Fragment。要用一个 Fragment 替换另一个 Fragment, Activity 的布局中需要包含一个作为 Fragment 容器的空 FrameLayout

请注意,该文件名与上一课中布局文件的名称相同,但布局目录没有 large 这一限定符。因此,此布局会在设备屏幕小于“large”的情况下使用,原因是尺寸较小的屏幕不适合同时显示两个 Fragment。

res/layout/news_acitivity.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 API 调用 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_activity);

            // 确认 Activity 使用的布局版本包含
            // fragment_container FrameLayout
            if (findViewById(R.id.fragment_container) != null) {

                // 不过,如果我们要从先前的状态还原,
                // 则无需执行任何操作而应返回
                // 否则就会得到重叠的 Fragment 。
                if (savedInstanceState != null) {
                    return;
                }

                // 创建一个要放入 Activity 布局中的新 Fragment 
                SecondFragment secondFragment = new SecondFragment();

                // 如果此 Activity 是通过 Intent 发出的特殊指令来启动的,
                // 请将该 Intent 的 extras 以参数形式传递给该 Fragment 
                secondFragment.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 的步骤与添加 Fragment 的步骤相似,但需要调用 replace() 方法,而非 add()

请注意,当你执行替换或移除 Fragment 等 Fragment 事务时,最好能让用户向后导航和“撤消”所做更改。要通过 Fragment 事务允许用户向后导航,你必须调用 addToBackStack(),然后再执行 FragmentTransaction


注意:当你移除或替换 Fragment 并向返回堆栈添加事务时,已移除的 Fragment 会停止(而不是销毁)。如果用户向后导航,还原该 Fragment,它会重新启动。如果你没有向返回堆栈添加事务,那么该 Fragment 在移除或替换时就会被销毁。

替换 Fragment 的示例:

  // 创建 Fragment 并为其添加一个参数,用来指定应显示的文章
    FirstFragment firstFragment = new FirstFragment();
    Bundle args = new Bundle();
    args.putInt(ArticleFragment.ARG_POSITION, position);
    firstFragment.setArguments(args);

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    // 将 fragment_container View 中的内容替换为此 Fragment ,
    // 然后将该事务添加到返回堆栈,以便用户可以向后导航
    transaction.replace(R.id.fragment_container, firstFragment);
    transaction.addToBackStack(null);

    // 执行事务
    transaction.commit();
addToBackStack() 方法可接受可选的字符串参数,来为事务指定独一无二的名称。除非你打算使用 FragmentManager.BackStackEntry API 执行高级 Fragment 操作,否则无需使用此名称。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值