アプリケーションに基本的なスナックバーを追加したいのですが、理由がわからないというエラーが表示されます。
このコードをFragmentのonCreateView()メソッドに追加しました。
Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
そして、このエラーを受け取りました:
06-01 10:26:09.955 1232-1232/? E/ActivityThread﹕ Failed to find provider info for me.muraterdogan.watchme.MetricaContentProvider
06-01 10:26:10.075 1232-1447/? E/ActivityThread﹕ Failed to find provider info for me.muraterdogan.watchme.YPLContentProvider
06-01 10:33:55.044 6646-6646/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: me.muraterdogan.watchme, PID: 6646
Java.lang.NullPointerException: Attempt to invoke virtual method 'Android.content.Context Android.view.ViewGroup.getContext()' on a null object reference
at Android.support.design.widget.Snackbar.<init>(Snackbar.Java:116)
at Android.support.design.widget.Snackbar.make(Snackbar.Java:140)
at me.muraterdogan.watchme.fragments.TrendingFragment.GetData(TrendingFragment.Java:90)
at me.muraterdogan.watchme.fragments.TrendingFragment.onCreateView(TrendingFragment.Java:83)
...
Fragmentが既存のアクティビティに追加された場合(xmlを使用して追加できることを思い出してください)、SnackBarのメソッドをFragmentのonActivityCreated()メソッドに呼び出す必要があります。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Snackbar.make(view, "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
1. onActivityCreatedメソッドに移動します。
2.以下のようなmakeメソッドでgetView()を使用してみます。
Snackbar.make(getView(), "Snackbar", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
私が取り組んでいるコードベースでは、ネットワークコールのエラーハンドラーなどの非同期メソッドコールバックにSnackbar
sが表示されていました。 Snackbar
が作成されていたとき、移動するFragment
はアタッチされておらず、getView()
から返されたView
にはCoordinatorLayout
またはFrameLayout
Snackbar
は、ビューの階層に含めたいと考えています。
特に、階層を走査するのはSnackbar
のプライベート findSuitableParent()
メソッドです。
_private static ViewGroup findSuitableParent(View view) {
ViewGroup fallback = null;
do {
if (view instanceof CoordinatorLayout) {
// We've found a CoordinatorLayout, use it
return (ViewGroup) view;
} else if (view instanceof FrameLayout) {
if (view.getId() == Android.R.id.content) {
// If we've hit the decor content view, then we didn't find a CoL in the
// hierarchy, so use it.
return (ViewGroup) view;
} else {
// It's not the content view but we'll use it as our fallback
fallback = (ViewGroup) view;
}
}
if (view != null) {
// Else, we will loop and crawl up the view hierarchy and try to find a parent
final ViewParent parent = view.getParent();
view = parent instanceof View ? (View) parent : null;
}
} while (view != null);
// If we reach here then we didn't find a CoL or a suitable content view so we'll fallback
return fallback;
}
_
このメソッドの結果はSnackbar
コンストラクターに渡され、そのコンストラクターでgetContext()
を呼び出します。このメソッドがnull
を返す場合は、質問にあるようにNPEを取得します。
添付されたフラグメントにCoordinatorLayout
またはFrameLayout
が含まれているという幸せなケースがまだ成り立つと仮定して、問題を修正する方法はいくつかあります。
最初にisDetached()
をチェックして、フラグメントがデタッチされていないことを確認してください。
私が自分でやったこと:コードベースのSnackbar
用の Builderパターン スタイリングラッパーがすでにあったため、ビルダーでfindSuitableParent()
をフォークして追加しましたSnackbar.make()
を呼び出す前に、それが_!= null
_を返すことを確認するチェック。このように、Snackbarビルダーの呼び出し元は、追加のチェックを追加する必要がありませんでした。
プロセスによって、スナックバーはビューを検索します。
そのため、アプリ自体は、実行時にフラグメントのビューを実際に参照していたことを実際には認識していません。
スナックバーのshowメソッドをフラグメントの「onResume」に配置してみてください。お役に立てれば。
なぜこれをonCreate内で行うのですか?
さらに、いくつかのルールに従っていることを確認してください。
ドキュメントに「Snackbarは親ビューを見つけて、ビューに与えられた値からSnackbarのビューを保持しようとします」とあります。
そのため、現在アタッチされている任意のビューを渡すことができます。