Activity & Fragment & tips
来源:互联网 发布:知乎怎么发不了文章 编辑:程序博客网 时间:2024/06/06 16:34
相比于Activity来说,创建一个Fragment所需系统资源相比Activity来说更少,然而控制却更为灵活。Fragment一般分为两类,一类是有UI的Fragment,可以作为页面,作为View来展示,另一类是用没有UI的Fragment,一般用作保存数据。
封装BaseFragment基类
例如为了实例化View,抽象一个getLayoutId方法,子类无需关心具体的创建操作,父类来做View的创建处理。同时可以提供一个afterCreate抽象函数,在初始化完成之后调用,子类可以做一些初始化的操作,你也可以添加一些常用的方法在基类,例如ShowToast().
public abstract class BaseFragment extends Fragment { protected View mRootView;@Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if(null == mRootView){ mRootView = inflater.inflate(getLayoutId(), container, false); } return mRootView; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); afterCreate(savedInstanceState); }protected abstract int getLayoutId(); protected abstract void afterCreate(Bundle savedInstanceState);}
public View onCreateView 这个方法中返回之前判断一下你的mRootView是null再inflate,这样会比较好,在ViewPager中随着页面滑动这个方法会调用多次,inflate过了之后就直接用就好了。
使用静态工厂方法newInstance(…)来获取Fragment实例
可以在Google的代码中发现这种写法,好处是接收确切的参数,返回一个Fragment实例,避免了在创建Fragment的时候无法在类外部知道所需参数的问题,在合作开发的时候特别有用。
还有就是Fragment推荐使用setArguments来传递参数,避免在横竖屏切换的时候Fragment自动调用自己的无参构造函数,导致数据丢失。
public static WeatherFragment newInstance(String cityName) { Bundle args = new Bundle(); args.putString(cityName,"cityName"); WeatherFragment fragment = new WeatherFragment(); fragment.setArguments(args); return fragment;}
Fragment状态保存/现场恢复
不要在Fragment里面保存ViewState!
为了让你的代码更加清晰和稳定,最好区分清楚fragment状态保存和view状态保存,
如果某个属性属于View,则不要在Fragment中做它的状态保存,除非属性属于Fragment。
每一个自定义View都有义务实现状态的保存,可以像EditText一样,设置一个开关来选择是否保存
比如说:android:freezeText=”true/false”。
public class CustomView extends View { @Override public Parcelable onSaveInstanceState() { Bundle bundle = new Bundle(); // 在这里保存当前状态 return bundle; } @Override public void onRestoreInstanceState(Parcelable state) { super.onRestoreInstanceState(state); // 恢复保存的状态 }}
处理fragment状态保存,例如保存从服务器获取的数据。
private String serverData; @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("data", serverData); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); serverData = savedInstanceState.getString("data"); }
避免错误操作导致Fragment的视图重叠
视图重叠是因为fragment已经发生了内存泄漏。
activity的创建、销毁完全托管到systemserver(ams),而fragment一般是手动new一个对象再add到systemserver,所以这里就有问题了。
fragment生命周期开始于add,结束于remove。不管app中间怎么变化,崩溃、进程被回收,只要没有remove,android框架都会自动创建、恢复fragment的状态。
这个问题很简单,在add或者replace的时候,调用含有TAG参数的那个方法,之后再add相同TAG的Fragment的话,之前的会被替换掉,也就不会同时出现多个相同的Fragment了。
public class WeatherFragment extends Fragment { //TAG public static final String TAG = WeatherFragment.class.getSimpleName();
不过为了最大限度的重用,可以在Activity的onCreate(Bundle savedInstanceState)中判断savedInstanceState是否不为空;
不为空的话,先用getSupportFragmentManager(). findFragmentByTag()找一下,找到实例就不用再次创建。
WeatherFragment fragment = null;if(savedInstanceState!=null){fragment = getSupportFragmentManager().findFragmentByTag(WeatherFragment.TAG);}if(fragment == null){ fragment = WeatherFragment.newInstance(...);}
Fragment里监听虚拟按键和实体按键的返回事件
mRootView.setFocusable(true);mRootView.setFocusableInTouchMode(true);mRootView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { //不一定是要触发返回栈,可以做一些其他的事情,我只是举个栗子。 getActivity().onBackPressed(); return true; } return false; }});
注意事项:
* FragmentTransaction异步执行相关问题。FragmentTransaction#commit函数是异步执行的(其把本次transaction的所有操作添加到消息队列里),不注意这一点可能会出现一些奇怪的问题。比如闪屏问题:view的显示隐藏是同步执行的,而fragment的hide、show是异步执行的,所以可能会碰到view隐藏了,而fragment的界面还没显示,导致闪屏。不过android也提供了FragmentManager#executePendingTransactions方法,强制同步执行。
- Activity & Fragment & tips
- Fragment Tips
- Fragment - Tips 个人理解
- Fragment activity
- Activity Fragment
- activity->fragment
- Android Tips-- Activity.runOnUiThread
- Android Activity+ViewPager(Fragment)+Fragment
- Fragment获取Activity,Activity获取Fragment
- Activity跳转Activity,Fragment切换下一个Fragment
- fragment与fragment,activity与fragment传值
- Fragment对比Activity
- Activity-Fragment-1
- Activity-Fragment-2
- Fragment与Activity通讯
- Fragment和Activity
- activity和fragment生命周期
- Fragment与Activity
- div+js实现自制滚动条效果
- ActiveMQ性能优化
- Fiddler显示IP的设置方法
- java中的浅克隆
- 最大流网络之Push-Relabel算法
- Activity & Fragment & tips
- cocos2dx在安卓6.0(android-23)以上版本打包
- 单例模式应用场景和设计失误所引发的问题
- 线段树 模板
- web特殊符号
- python的排序模块bisect
- Cookie免验证自动登录
- shell中的分支
- 【STL】STL空间配置器