常用代码整理:使用 Fragment 的注意事项

版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/zeqiao/article/details/83588047

说明:大部分内容都是参考别的文章,这里做整理是为了以后的编程有实用的模板,可以即需即用。

1、用 newInstance 来初始化 Fragment:

Activity 在默认情况下,切换横竖屏,Activity 会销毁重建,依附于上面的 Fragment 也会销毁重建,Fragment 是通过反射进行重建的,而且,只调用了无参构造的方法,这也是有部分人通过 new Fragment() 的方式构建 Fragment时,遇到屏幕切换时,Fragment 会报空指针异常的原因!注意看代码中 f.setArguments(args); 也就是说,Fragment 在初始化之后会把参数保存在 arguments 中,当 Fragment 再次重建的时候,它会检查 arguments 中是否有参数存在,如果有,则拿出来再用,所以我们再 onCreate() 方法里面才可以拿到之前设置的参数,但是:Fragment 在重建的时候不会调用有参构造,所以,通过 new Fragment() 的方法来初始化,Fragment 重建时,我们通过有参构造函数设置的参数就没有了。

// 谷歌提供的模版
public class BlankFragment extends Fragment {
        // TODO: Rename parameter arguments, choosenames that match
        // the fragment initialization parameters,e.g. ARG_ITEM_NUMBER
        private static final String ARG_PARAM1 = "param1";
        private static final String ARG_PARAM2 = "param2";
        // TODO: Rename and change types of parameters
        private String mParam1;
        private String mParam2;

        public BlankFragment() {
                // Required empty public constructor
        }

        public static BlankFragment newInstance(String param1, String param2) {
                BlankFragment fragment = new BlankFragment();
                Bundle args = new Bundle();
                args.putString(ARG_PARAM1, param1);
                args.putString(ARG_PARAM2, param2);
                fragment.setArguments(args);
                return fragment;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                if (getArguments() != null) {
                        mParam1 = getArguments().getString(ARG_PARAM1);
                        mParam2 = getArguments().getString(ARG_PARAM2);
                }
         }

        @Override
        public View onCreateView(LayoutInflater inflater,ViewGroup container,  BundlesavedInstanceState) {
                // Inflate the layout for this fragment
                return inflater.inflate(R.layout.fragment_blank, container, false);
        }
}

2、PagerAdapter,FragmentPagerAdapter,FragmentPagerStateAdapter 的区别:

  • 三种 Adapter 的缓存策略各有不同:
    • PagerAdapter:缓存三个,通过重写 instantiateItem 和 destroyItem 达到创建和销毁 view 的目的。
    • FragmentPagerAdapter:内部通过 FragmentManager 来持久化每一个 Fragment,在 destroyItem 方法调用时只是 detach 对应的 Fragment,并没有真正移除。
    • FragmentPagerStateAdapter:内部通过 FragmentManager 来管理每一个 Fragment,在 destroyItem 方法调用时移除对应的 Fragment。
  • 分情况使用这三个 Adapter :
    • PagerAdapter:当所要展示的视图比较简单时适用。
    • FragmentPagerAdapter:当所要展示的视图是 Fragment,并且数量比较少时适用。
    • FragmentStatePagerAdapter:当所要展示的视图是 Fragment,并且数量比较多时适用。

3、Fragment 懒加载:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * 懒加载 Fragment
 */

public abstract class LazyLoadBaseFragment extends Fragment {

    private boolean mIsViewCreated;
    private boolean mIsFragmentVisible;
    private boolean mIsFirstVisible = true;
    private View mRootView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (mRootView == null) {
            mRootView = inflateView(inflater, container);
        }
        initView(mRootView);
        mIsViewCreated = true;
        if (mIsFragmentVisible && mIsFirstVisible) {
            requestData();
            mIsFirstVisible = false;
        }
        return mRootView;
    }

    protected abstract View inflateView(LayoutInflater inflater, ViewGroup container);

    protected abstract void initView(View view);

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        mIsFragmentVisible = isVisibleToUser;
        if (isVisibleToUser && mIsViewCreated && !mIsFirstVisible) {
            requestDataAutoRefresh();
        }
        if (!isVisibleToUser && mIsViewCreated) {
            stopRefresh();
        }
        if (isVisibleToUser && mIsViewCreated && mIsFirstVisible) {
            requestData();
            mIsFirstVisible = false;
        }
    }

    protected abstract void requestData();

    protected abstract void requestDataAutoRefresh();

    protected abstract void stopRefresh();

}

参考文章:
1、https://blog.csdn.net/xiaoxiaocaizi123/article/details/79074501
2、https://blog.csdn.net/android_cyw/article/details/54632112
3、https://blog.csdn.net/learningcoding/article/details/79244443

猜你喜欢

转载自blog.csdn.net/zeqiao/article/details/83588047