Android 常用代碼整理:使用 Fragment 的注意事項

說明:大部分內容都是參考別的文章,這裏做整理是爲了以後的編程有實用的模板,可以即需即用。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章