fragment:解决app适应不同大小屏幕,可在activity中组装,添加,替换,移除。响应时间比activity时间短。
引用方式
在XML中,使用标签<Fragment><Fragment/>
<fragment
android:id="@+id/id_content"
android:name="com.fragments.MyFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
代码中添加
FragmentManager 通过 getFragmentManager()/getSupportFragmentManager()获得
findFragmentById(@IdRes int id)
findFragmentByTag(String tag);
//入栈
PopBackStack();
popBackStack(int id, int flags)
popBackStackImmediate(int id, int flags);
FragmentTransaction操作Fragment
.add()
.remove()
.replace()
.hide()
.show()
.detach()
.attach()
.addtoBackStack()
Activity和Fragment传值
构造函数传值
public class MainActivity extends FragmentActivity {
private FragmentManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = getSupportFragmentManager();
/*
* 这里为什么要进行空判断,因为在屏幕旋转的时候,系统会执行onSaveInstanceState
* 方法去保存当前activity的状态,然后activity会重建,执行onCreate方法,如果我们不判断
* savedInstanceState是否为空,那么每次就会执行下面的commit操作,向Fragmnet传递参数,
* 这样参数的却会保留下来,但是我们不应该每次都去传递参数。当进行了空判断时,当Activity重建
* 的时候,会调用Fragment的默认构造函数,所以我们传递过去的参数不能保留了。
*/
if(savedInstanceState == null){
manager.beginTransaction().replace(R.id.fl_main, new FragmentOne("params")).commit();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
System.out.println("=========savedInstanceState ");
super.onSaveInstanceState(outState);
}
}

之前传递的参数都不见了,因为recreate你的Fragment的时候,调用的是默认构造函数。
必须写出默认的构造函数,因为Fragment重建的时候,会调用默认的构造函数,也就是空参数的构造函数,如果我们只是给出了带参数的构造函数,系统是不会为我们创建空参数的构造函数的,如果你不写,在Fragment重建的时候就会发生的错误。
setArguments()传值
FragmentOne fragmentOne = new FragmentOne();
Bundle bundle = new Bundle();
bundle.putString("name", text);
//fragment保存参数,传入一个Bundle对象
fragmentOne.setArguments(bundle);//getArguments()
先把bundle对象赋值给mArguments,然后通过无參反射构造了一个新的Fragment对象,然后把我们保存的Bundle对象传递给了新的Fragment对象的mArguments成员变量。创建Fragment时候在传入。
Fragment懒加载
public abstract class LazyFragment extends Fragment {
protected boolean isVisible;
/**
* setUserVisibleHint()在所有的Fragment生命周期之前调用,在这里设置是否加载数据
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(getUserVisibleHint()) { //fragment可见
isVisible = true;
onVisible();
} else { //不可见
isVisible = false;
onInvisible();
}
}
protected void onVisible(){
lazyLoad();
}
protected abstract void lazyLoad();
protected void onInvisible(){}
}
fragment重叠
原因:系统在页面重启前,帮我们保存了Fragment的状态,但是在重启后恢复时,视图的可见状态没帮我们保存,而Fragment默认的是show状态,所以产生了Fragment重叠现象。
解决方案:
public class BaseFragment extends Fragment {
private static final String STATE_SAVE_IS_HIDDEN = "STATE_SAVE_IS_HIDDEN";
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
...
if (savedInstanceState != null) {
boolean isSupportHidden = savedInstanceState.getBoolean(STATE_SAVE_IS_HIDDEN);
FragmentTransaction ft = getFragmentManager().beginTransaction();
if (isSupportHidden) {
ft.hide(this);
} else {
ft.show(this);
}
ft.commit();
}
@Override
public void onSaveInstanceState(Bundle outState) {
...
outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden());
}
}
网友评论