2017-01-27 12 views
1

findViewByIdを使用しようとしていますが、警告が表示されます。私はserveralがこの警告を解決するために使用されたさまざまな方法を見てきましたが、自分のコードに関して正しいかどうかわかりません。この文脈でこの警告を削除するのが正しい方法を知っていますか?フラグメント内のfindViewByIdを宣言した後のjava.lang.NullpointerException

メソッドの呼び出しが 'findViewById' 'のjava.lang.NullPointerException'

を生成することがPage1Fragment.java

public class Page1Fragment extends android.support.v4.app.Fragment { 

    boolean squareState; 

    public Page1Fragment() { 

    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 

     return inflater.inflate(R.layout.fragment_page1, container, false); 
    } 

    @Override 
    public void onResume(){ 
     super.onResume(); 
     loadPreferences(); 
     displaySettings(); 
    } 

    public void loadPreferences(){ 
     SharedPreferences pref = this.getActivity().getSharedPreferences("settings", AppCompatActivity.MODE_PRIVATE); 
     squareState = pref.getBoolean("square_state", true); 
    } 

    public void displaySettings() { 
     if (squareState) { 
      getView().findViewById(R.id.blue_square).setVisibility(View.VISIBLE); 
     } else { 
      getView().findViewById(R.id.blue_square).setVisibility(View.GONE); 
     } 
    } 
} 
+0

を回避するためには、あるいはそのonCreateViewがまだ呼び出さ持っていない場合があります。フラグメントのビューがまだ作成されていない場合、getView()を呼び出すとnullが返されます。したがって、nullをチェックする必要があります。 –

+0

getViewメソッドをどこで呼び出すのかわかっている場合(onCreateViewの後とonDestroyViewの前)、これらの警告を無視できます。 – AnixPasBesoin

+0

@AnixPasBesoinしかし、その前提を作ることは、過去に私にとって厄介な驚きをもたらしました。フラグメントがアクティビティにいつアタッチされ、ビューが作成されたかを知ることは必ずしも容易ではありません。たとえば、AsyncTaskを起動してバックグラウンドスレッドのデータを取得してからUIを更新すると、ユーザはフラグメントからナビゲートしてしまい、getView()はnullを返します。 –

答えて

0

私はあなたが糸くずの警告の話をしていると仮定します。

フラグメントが存在するライフサイクルのどの部分に応じて、まだonCreateViewメソッドが呼び出されていてもいなくてもかまいません。

フラグメントのビューがまだ作成されていない場合(onCreateViewがまだ呼び出されていない場合)、getView()を呼び出すとnullが返されます。

したがって、あなたはとてもようにnullをチェックする必要があります:

View contentView = getView(); 
if (contentView != null) { 
    contentView.findViewById(R.id.blue_square).setVisibility(View.VISIBLE); 
} 

それは断片が活動に取り付けられており、そのビューが作成されたときを知ることは必ずしも容易ではありません。たとえば、AsyncTaskを起動してバックグラウンドスレッドのデータを取得してからUIを更新すると、ユーザはフラグメントからナビゲートしてしまい、getView()はnullを返します。

フラグメントライフサイクルの詳細については、developer.android.comのFragmentのドキュメントをご覧ください。

+0

答えは正しいですが、使用するたびにgetViewをnullからチェックすると、コードが醜いものになる傾向があります。とにかく結果がnullにならない場合、nullの場合は処理していないと考える人もいます。 – AnixPasBesoin

+0

フラグメントがどのように使われるかに注目していないので、NullPointerExceptionをスローするよりも醜い方がいいです。あなたがそのコードを扱っている唯一の開発者であれば、そのコードはonCreateViewとonDestroyViewの間でのみ呼び出されるという前提を安全に行うことができますが、おそらく他の人が引き継ぐかもしれないと仮定してコードを記述しますそれをサポートします。 –

+0

フラグメントのライフサイクルはランダムな振る舞いではありません。十分理解すれば(それは複雑ではありません)、そのためにnullptrexceptionが発生することはありません。 – AnixPasBesoin

0

onCreateViewの後でonDestroyViewの後にgetView()メソッドを呼び出している場合は、これらの警告を無視できます。 このメソッドは、この2つのコールバックの外側にnullを返します。

繰り返し確認することを避けるためのきれいな方法は、rootViewdislplaySettingsメソッドへの参照として渡すことです。

@Override 
public void onResume() { 
    displaySettings(getView()); // You're safe here! 
} 

フラグメントのライフサイクルdocsを参照してください:次のようにあなたがonResume内で使用するときは、なし得るでしょう

public void displaySettings(View rootView) { 
    if (squareState) { 
     rootView.findViewById(R.id.blue_square).setVisibility(View.VISIBLE); 
    } else { 
     rootView.findViewById(R.id.blue_square).setVisibility(View.GONE); 
    } 
} 

は文句を言います。

ボーナス

はフラグメントがであるライフサイクルのどの部分に応じて、いくつかのコードの重複

public void displaySettings(View rootView) { 
    rootView.findViewById(R.id.blue_square).setVisibility(squareState ? View.VISIBLE : View.GONE); 
} 
+0

このコードを使用しようとしましたが、残念ながら何らかの理由で動作しません。アプリはクラッシュしない。 – MacaronLover

+0

私は引数としてrootViewを渡したばかりですが、動作しない理由はありません。どのように使ったことがありますか? – AnixPasBesoin

+0

あなたの提案に基づいて 'displaySettings'メソッド内で' rootView'を使用しましたが、私の好みの範囲内でスイッチを変更しても項目は消えません。 – MacaronLover

関連する問題