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メソッドは次のようになります.
では、私は開発した工事でどのような問題に直面し、どのような最適化をしましたか.
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();
}