Fragment与Activity。什么时候用什么时候不用?
回答: 看需求!
个人觉得推荐场景:
(使用Fragment完全替换Activity,而Activity用来管理Fragment或者把fragment当作一个轻量级activity使用)
当你一个Activity需要模块化的时候,你可以单独写一个Fragment并且嵌套在任何一个界面,不用担心重复代码。
一般主页的每个tab都是用Fragment,类似的一个页面下有多个布局需要切换的时候感觉用Fragment很方便
布局在不同的设备上比如手机和平板上的适配
比如 App 中有一个新用户注册功能,包括设置用户名、密码、手机号等等流程,设计师在 UI 设计上将每个流程单独设计成一个界面,引导用户一步步操作。作为开发人员,如果将每一个完善信息的流程单独设置成一个 Activity 的话操作起来就比较繁琐,并且也不易于应用里的逻辑处理,而如果使用 Fragment 并结合回退栈的话,就非常合适了
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.hide(firstStepFragment);
if (secondStepFragment==null){
ft.add(R.id.fl_content, secondStepFragment);
}else {
ft.show(secondStepFragment);
}
ft.addToBackStack(null);
ft.commit();
注意:这里使用了 hide() 方法,而不是 replace() 方法,因为我们当然希望用户返回上一步操作时,之前设置的内容不会消失。
Activity管理Fragment的思路:(曾经用过)
当然别忘了FragmentManager。管理着 正在activity里显示的fragment们(用list)以及detach之后跟view hiearchy断开联系的被放进backstack的fragment:
建一个hashmap,用于存放已实例过的fragment,要复用的时候直接拿出来,而且还可以解决Fragment 重叠问题;
-
写一个Basefragment,子Fragment继承与它,自定义接口,在activity里实现接口方法,因此activity可以根据待实例化fragment的属性进行管理控制。(这也是观察着模式)
具体实现方式如下:
public class BaseFragment extends Fragment implements View.OnClickListener{
public interface IOneFragmentClickListener{
void onOneFragmentClick();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View contentView = inflater.inflate(R.layout.fragment_one, null);
contentView.findViewById(R.id.edt_one).setOnClickListener(this);
return contentView;
}
@Override
public void onClick(View v) {
if (getActivity() instanceof IOneFragmentClickListener){
((IOneFragmentClickListener) getActivity()).onOneFragmentClick();
}
}
}
只要在宿主 Activity 实现 Fragment 定义的对外接口 IOneFragmentClickListener,便可以实现 Fragment 调用 Activity 的功能。
fragment的使用:
作为 Activity 界面的一部分,Fragment 的存在必须依附于 Activity,并且与 Activity 一样,拥有自己的生命周期,同时处理用户的交互动作。同一个 Activity 可以有一个或多个 Fragment 作为界面内容,并且可以动态添加、删除 Fragment,灵活控制 UI 内容,也可以用来解决部分屏幕适配问题。
另外,support v4 包中也提供了 Fragment,兼容 Android 3.0 之前的系统(当然,现在 3.0 之前的系统在市场上已经很少见了,可以不予考虑),使用兼容包需要注意两点:
Activity 必须继承自 FragmentActivity;
使用 getSupportFragmentManager() 方法获取 FragmentManager 对象;
fragment 生命周期:
一边看一边提出一些问题:
- attach跟add怎么理解?inflate呢?
- attach有什么作用?有什么好处,因此适合什么场景?
个人对提出问题的回复:
Applications should generally not implement a constructor. Prefer
{@link #onAttach(Context)} instead. It is the first place application code can run where
the fragment is ready to be used - the point where the fragment is actually associated with its context. Some applications may also want to implement {@link #onInflate} to retrieve
attributes from a layout resource, although note this happens when the fragment is attached.</pre>
- attach:将fragment与Activirty联系起来,通过context。所以通过fragment startActiviotyForResult 其实也是Activity start的,回调onActivityResult() 也是应该由activity处理。 </pre>
- add:将fragment加到ViewHiearchy中,通过把fragment加到manager管理的active的fragment的List里。
- onInflate():保存布局里的属性
Called when a fragment is being created as part of a view layout
inflation, typically from setting the content view of an activity. This may be called immediately after the fragment is created from a <fragment>
tag in a layout file. Note this is <em>before</em> the fragment's
{@link #onAttach(Activity)} has been called; all you should do here is
parse the attributes and save them away. <p>This is called every time the fragment is inflated, even if it is
being inflated into a new instance with saved state. It typically makes sense to re-parse the parameters each time, to allow them to change with different configurations.</p> </pre>
attach与detach及回退栈的配合,如果当你detach fragment时,那么被移除的fragment就被停止了(没有消亡,但视图已经销毁了),如果用户导航回来重新加载这个fragment,它将会重新启动,视图也会重新创建,如果你没有把事务加入到堆栈中,当fragment被remove时,这个fragment也就消亡了。
通信方式
通常,Fragment 与 Activity 通信存在三种情形:
-
Activity 操作内嵌的 Fragment
由于 Activity 持有所有内嵌的 Fragment 对象实例(创建实例时保存的 Fragment 对象,或者通过 FragmentManager 类提 供的 findFragmentById() 和 findFragmentByTag() 方法也能获取到 Fragment 对象),所以可以直接操作 Fragment;
Fragment 操作宿主 Activity;
Fragment 通过getActivity()
方法可以获取到宿主 Activity 对象(强制转换类型即可),进而可以操作宿主 Activity;那么很自然的,获取到宿主 Activity 对象的 Fragment 便可以操作其他 Fragment 对象。Fragment 操作同属 Activity中的其他 Fragment。
高内聚,低耦合。Fragment 做好自己的事情即可,所有涉及到 Fragment 之间的控制显示等操作,都应交由宿主 Activity来统一管理。