Android viewpagerとfragmentの関連最適化

3809 ワード

前に2つのプロジェクトを書いたことがありますが、いずれも微信のような底の4つのナビゲーションで、このような効果を実現する方法は実は多く、当時私のやり方はviewpagerとfragmentを結合していました.
では、私は開発した工事でどのような問題に直面し、どのような最適化をしましたか.
1.オリジナルのviewpagerは左右に1つずつのpageをキャッシュするという特徴があるため、fragmentを切り替えるたびに切り替わると、fragmentのonCreateViewメソッドが再実行され、このメソッドではinflateなどの関連操作を行い、リソースを比較消費し、inflate後のfindView ByIDメソッドも比較的時間がかかる.個人的にはここが最適化できると思います
2.viewpagerのキャッシュ効果は大きくないのではないでしょうか.
このような状況に対して、私がやった最適化の仕事はどれらがありますか?
1.onCreateViewが実行されるたびに、毎回inflate関連のレイアウトが実行される以上、なぜ関連するレイアウトviewを出さないのか、私が初めてinflateを終了した後、その後、使用するたびに直接戻ってくれればいいのか、baseFragment(これは私のFragmentのベースクラス)でviewタイプのグローバル変数rootViewを定義し、onCreateViewを実行するたびにrootViewが空であるかどうかを判断し、空であればinflateレイアウトに行き、空でなければこのrootViewオブジェクトをそのまま返すだけです.これによりonCreateViewメソッドを実行するたびにinflateに行くことを効果的に回避でき、このような判定のようにappの多くの場所で行われます.
2.データのロードについては、私が使うときにデータをロードするのが一般的です.これが通常の怠け者ロードです.「怠け者」という字を言うと、単例モードの2つの方法を思い出します.怠け者式と餓漢式です.最初は、怠け者式とは何か、餓漢式とは何か、怠け者とは何か、つまり対象が怠け者で、この対象を使う必要があるときだけ、このオブジェクトが作成されると、それに対応する餓漢は、オブジェクトが飢えていることであり、最初から需要を満たすために作成され、後で使用するたびに、直接このオブジェクトを持ってきて使用すればよい.先ほどのリロード方式に戻り、fragmentにはsetuserVisibleHintという方法があります.この方法には2つの特徴があり、fragmentが現在表示されているか非表示になるたびにコールバックされます.また、この方法の呼び出しタイミングがonCreateView方法よりも早いということです.この2つの認識に基づいて、私はこの方法を書き直し、方法内でコールバックのパラメータisVisibleToUserを判断し、isVisibleToUserがtrueであれば、表示を説明します.それではすぐに関連するデータをロードして、さもなくば何もしないで、ユーザーがインタフェースを切り替えるのを待ってからデータをロードして、このように少し資源を節約することができて、Android携帯電話の配置は高いですが、すべてのappに分けるメモリはすべて有限で、やはり節約することができて節約して、最適化することができて最適化します.特に良いプログラマーになりたいなら、eclipseでコードを書くことがあることに気づき、コードのビューウィンドウの右側の欄に黄色い警報を提示し、余計なガイドバッグのせいかもしれないが、このような警報を消す方法もたくさん考えられ、クラス全体がきれいに見えると安心し、多くの同業者に似たような強迫症があると思います.
3.第2のポイントの怠惰なロードの認識とsetuserVisibleHintの方法に対する認識に基づいて、それでは前にした第1のポイントの最適化は更に一歩前進することができて、データはすべてユーザーが見た後にやっとロードしたので、どうして初期化viewをユーザーが見た後に置いてからしますか?怠惰になって、怠惰な徹底的にして、前に1人の古いプログラマーを聞いて、“サボらない”プログラマーは良いプログラマーではありませんと言って、もう一度最適化するときは、onCreateViewメソッドに空のレイアウトファイルを直接返すだけでいいです.ユーザーが表示されるたびに、本当のレイアウトinflateを出てからこのコンテナに追加すればいいです.最後に、私のsetuserVisibleHintメソッドは次のようになります.
	@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		if (isVisibleToUser) {
			if (null == contentView) {
				dialog = ProgressDialog.show(getActivity(), null, null);
				contentView = mInflater.inflate(getContentID(), null);
				initViews(contentView);
				if (null != rootView) {
					((ViewGroup) rootView).addView(contentView);
				}
			}
			loadDatas();
		}
	}
fragment全体をベースクラスにカプセル化すると、次のようになります.
public abstract class BaseFragment extends Fragment {
	public static int DelayTime = 500;
	private View rootView, contentView;
	private LayoutInflater mInflater = LayoutInflater.from(App.getInstance());
	protected Handler mHandler = new Handler(Looper.getMainLooper());
	protected ProgressDialog dialog;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		if (null == rootView) {
			rootView = inflater.inflate(R.layout.layout_base_fragment,
					container, false);
			if (null != contentView) {
				((ViewGroup) rootView).addView(contentView);
			}
		}
		return rootView;
	}

	@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		if (isVisibleToUser) {
			if (null == contentView) {
				dialog = ProgressDialog.show(getActivity(), null, null);
				contentView = mInflater.inflate(getContentID(), null);
				initViews(contentView);
				if (null != rootView) {
					((ViewGroup) rootView).addView(contentView);
				}
			}
			loadDatas();
		}
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		((ViewGroup) rootView).removeView(rootView);
	}

	public abstract int getContentID();

	public abstract void initViews(View contentView);

	public abstract void loadDatas();
}