前言
在做项目过程中突然需要手动切换Fragment,在这里+传值卡了三个多小时在基础上,真的是脑子秀逗了,至此特意回顾了下Fragment基础用法。
-
小tip
1.除了用户下拉刷新以外,还可以在onHiddenChanged()方法中每次切换时刷新加载数据。
2.能不用Fragment则尽量不用,其真的是最差劲儿的控件。
3.尽量使用AS自带创建方式的newInstance传入值,其使用setArguments在当前Fragment对象出现问题重新恢复时可大概率的找回所传数据
-
注意点:
1.现在一般使用v4包下的Fragment,今年起可以使用androidx包下的
2.没有继承AppCompatActivity的宿主Activity需继承FragmentActivity
3.操作切换的FragmentManager对象不可改变实例,但操作时的beginTransaction()事务不可是同一个实例否则报commit already called
错误
4.Fragment中获取管理类用getChildFragmentManager(),Activity中的用v4包下的getSupportFragmentManager()
5.所有的Fragment对象必须在事务中先add,否则无其切换无反应,因为其还未被添加进视图
6.尽量在初始化时添加字符串flag
7.show()、hide()、commit()方法调用必须在同一个事务对象中完成。
8.Fragment里的getActivity有null隐患,尽量使用onAttach方法传递的Activity。
-
简易传值
1.Activity在实例Fragment时使用setArguments传值可以保证Fragment在内存或异常回收后可以从onSaveInstance里面重新取回传参
2.Activity获取Fragment中的参数,Activity实现一个回调接口set给Fragment让其在所在位置调用接口抽象方法,回调接口是0延时操作。
3.Fragment获取Activity中参数,使用context转为具体的Activity对象直接从Activity里面拿取。
4.Fragment对Fragment传参,通过Activity中转获取别的Fragment实例
-
Fragment简单使用示例代码
1简易手动添加切换
public void swtichFragment(int flagPos) {
Fragment fragment = fragmentManager.findFragmentByTag(flagPos + "");
if (fragment == null) {
try {
fragmentManager.beginTransaction()
.add(R.id.content_frame_layout, fragList.get(flagPos), flagPos + "")
.commitAllowingStateLoss();
} catch (Exception e) {
//程序重启
}
}
for (int i = 0; i < fragList.size(); i++) {
if (i == flagPos) {
fragmentManager.beginTransaction().show(fragList.get(i)).commitAllowingStateLoss();
} else {
fragmentManager.beginTransaction().hide(fragList.get(i)).commitAllowingStateLoss();
}
}
}
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
private void initFragment() {
HomeFragment homeFragment = HomeFragment.newInstance("", "");
ShopFragment shopFragment = ShopFragment.newInstance("", "");
MineFragment mineFragment = MineFragment.newInstance("", "");
fragList.add(homeFragment);
fragList.add(shopFragment);
fragList.add(mineFragment);
fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.content_frame_layout, fragList.get(0), "0")
.add(R.id.content_frame_layout, fragList.get(1), "1")
.add(R.id.content_frame_layout, fragList.get(2), "2")
.show(fragList.get(0))
.hide(fragList.get(1))
.hide(fragList.get(2))
.commitAllowingStateLoss();
}
}
2.TabLayout+字符串tag
mainactivityTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//获取当前被选中的tab标签的tag属性
int tag = Integer.parseInt(tab.getTag().toString());
Fragment fragment = mFragmentManager.findFragmentByTag("" + tag);
if (fragment == null) {
mFragmentManager.beginTransaction().add(R.id.mainactivityFragment, mList.get(tag), tag + "").commit();
}
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
for (int i = 0; i < mList.size(); i++) {
if (i == tag) {
fragmentTransaction.show(mList.get(i));
} else {
fragmentTransaction.hide(mList.get(i));
}
}
fragmentTransaction.commit();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
4.Fragment+ViewPager
切换,隐藏与展示都交由适配器操作,极其简单。
//添加伪代码
TaskListFragment taskListFragment = TaskListFragment.newInstance("","");
TaskCollectFragment taskCollectFragment = TaskCollectFragment.newInstance("","");
fragList.add(taskListFragment);
fragList.add(taskCollectFragment);
vPagerAdapter = new TaskVpagerAdapter(getSupportFragmentManager(), fragList);
vPager.setAdapter(vPagerAdapter);
vPager.setCurrentItem(0);
//适配器代码
public class TaskVpagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> list = new ArrayList<>();
public TaskVpagerAdapter(FragmentManager fm,ArrayList<Fragment> list) {
super(fm);
this.list=list;
}
@Override
public Fragment getItem(int position) {
return list.get((position%list.size()));
}
@Override
public int getCount() {
return list.size();
}
}