Fragment解析

2017-11-20  本文已影响0人  荞麦穗

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);
    }
}
20160122221155310.gif

之前传递的参数都不见了,因为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());
    }
}
上一篇下一篇

猜你喜欢

热点阅读