android fragment创建,Android — 创建和修改 Fragment 的方法及相关注意事项

如何创建 fragment activity

public class FooFragment extends Fragment {

@Override

public View onCreateView(LayoutInflater inflater,

ViewGroup container, Bundle savedInstanceState) {

// 为fragment提供 XML 布局文件

return inflater.inflate(R.layout.fragment_foo, container, false);

}

}

如何在代码中使用 Fragment

在代码中实现 Fragment 一般有两种方法,分别为静态实现和动态实现。

1. 在 XML 中确定 Fragment 内容

在 XML 通过 android:name 参数来确定 fragment 要显示的内容,这种方法建立的 fragment 不可以在程序运行过程中移除,示例代码如下:

android:name="com.fragment.FooFragment"

tools:layout="@layout/fragment_foo"

android:id="@+id/fragment"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

其中的 com.fragment.FooFragment 为名为 FooFragment 的 Fragment Activity。

2. 在程序运行时确定 Fragment 内容

首先,在 xml 布局文件中应该放置 FragmentLayout 作为 fragment 的容器,代码如下:

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/fragment_container">

在声明了 android:id 之后,在 Java 代码中就可以操作这个 Fragment 容器了。可以使用add(), replace(), remove()等方法,示例代码如下:

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();

fragmentTransaction.remove(R.id.fragment_container, new FooFragment());

fragmentTransaction.commit();

3. add() 方法和 replace() 方法说明

add()方法是在原有的基础上添加一个 fragment,实现叠加的效果。

replace()方法是将原先所有的 fragment移除,然后添加一个 fragment。

如何保留 Fragment 状态

不要每次都 new 一个 Fragment,而是用 hide() 和 show() 方法来实现切换。

在 onCreate() 中先 add() 两个 fragment。

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();

fragmentTransaction.add(R.id.fragment_container, homeFragment);

fragmentTransaction.add(R.id.fragment_container, meFragment);

fragmentTransaction.commit();

之后需要切换时,用如下方法实现。

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();

fragmentTransaction.hide(meFragment);

fragmentTransaction.show(homeFragment);

fragmentTransaction.commit();

关于 fragment 的注意事项

1. 如何理解 addToBackStack() 方法

fragmentTransaction.replace(R.id.fragment_container, new BarFragment());

fragmentTransaction.addToBackStack(null);

fragmentTransaction.commit();

在代码中,我们可以看到,addToBackStack() 方法作用的对象是一个 transaction。也就是说,在执行这个 transaction 时,系统会建立一个回退栈,其中记录的是进行 transaction 前后 fragment 的内容。当手机上的 back 键按下时,最后建立的回退栈先进行响应,使得当前 fragment 先 remove 进行 transaction 后 fragment 的内容,再 add 上进行 transaction 前 fragment 的内容。

来一个实例,假设当前 fragment 内容为 C,先进行了一次有 addToBackStack 的replace(container, A),再进行一次无 addToBackStack 的replace(container, B)时,如果触发了 back 事件,那么之前建立的回退栈响应,使 fragment 先 remove 掉 A,事实上本来就已经没了有,然后 add 上原先状态的C。此时,B是不会被 remove 掉的。所以,最后 fragment 中的内容为 B 和 C 两者的叠加。

如果希望清空 fragment 的回退栈,可以采用在 replace 前加上 popBackStack() 方法,第二个参数为POP_BACK_STACK_INCLUSIVE。示例代码如下:

getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();

fragmentTransaction.replace(R.id.fragment_container, new FooFragment());

fragmentTransaction.commit();

2. 关于 fragmentTransaction 的延迟问题

fragmentTransaction.commit()并不是立即执行的,也并非进入UI线程队列中等待顺序执行,而是由系统自动调配,在 UI 线程空闲时执行。这样就会产生一个问题,如果我需要获取到 fragment 中对象的实例,这个时候findViewById()方法会返回 null ,那么如何解决这个问题呢?

第一种方法是通过getSupportFragmentManager().executePendingTransactions()来让 transaction 立即加入UI线程执行,而不是被调配在空闲时间执行。但是如果是在其他线程中获取view,这个方法依然行不通,因为有可能UI线程本身正在进行一个相对耗时的操作,而第二种方法则更为安全。

第二种方法是在 fragment activity 的onCreateView()方法中获取对应的view,示例代码如下:

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.fragment_bar, container, false);

textView = (TextView)rootView.findViewById(R.id.textbar);

return rootView;

}

fragment lifecycle 流程图

1460000006760847

references:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值