web-dev-qa-db-ja.com

アクティビティからフラグメントが作成されたときにgetViewがnullを返す

私は現在、携帯電話でも仕事をしようとしている実用的なタブレットアプリケーションを持っています。テーブルの画面には、リストフラグメントと詳細フラグメントの2つのフラグメントがあります。電話では、リストフラグメントが表示され、リストアイテムが押されると新しいアクティビティが作成されます。このアクティビティは、単にonCreate()メソッドでフラグメントを作成し、次のように画面にコミットします。

_// Place an DeallDetailsFragment as our content pane
DealDetailsFragment f = new DealDetailsFragment();
getFragmentManager().beginTransaction().add(Android.R.id.content, f).commit();
getFragmentManager().executePendingTransactions();
_

これは期待どおりに機能していますが、このアクティビティ内から、どの詳細をロードして表示するかをフラグメントに伝える必要があります。 DealDetailsFragmentクラスには、次のようにコンテンツを更新するupdateDeal()メソッドがあります。

_if (deal==null) { // could be null if user presses the loading deals list item before it loads
    return;
}
this.deal=deal;
if (dealTitle==null) { // get the view objects only once
    holder = new ViewHolder();  
    holder.dealHeat=(TextView) getView().findViewById(R.id.dealDetails_heat_textView);
    holder.dealPrice=(TextView) getView().findViewById(R.id.dealDetails_price_textView);
    holder.dealRetailer=(TextView) getView().findViewById(R.id.dealDetails_retailer_textView);
    holder.dealTitle=(TextView) getView().findViewById(R.id.dealDetails_title_textView);
    holder.dealDesc=(TextView) getView().findViewById(R.id.dealDetails_desc_textView);
    holder.goToButton= (LinearLayout) getView().findViewById(R.id.dealDetails_goToDeal);
    holder.dealImage=(ImageView) getView().findViewById(R.id.dealDetails_imageView);
    holder.postedBy=(TextView) getView().findViewById(R.id.dealDetails_poster_textView);
    holder.datePosted=(TextView) getView().findViewById(R.id.dealDetails_date_textView);
_

getView()は、フラグメントが1つしか表示されていない電話でアプリケーションを実行すると、nullを返します。

何か案は?残念ながら、オンラインで入手できるフラグメントの例は多くありません。

58
bencallis

メソッド呼び出しをonCreateViewの間に実行されるように移動し、getView()の代わりに参照用に拡張するビューを使用します。詳細については、フラグメントのライフサイクルを参照してください。 https://developer.Android.com/guide/components/fragments.html#Creating

getView()が返される前にnullを返す理由を説明するonCreateView(LayoutInflater, ViewGroup, Bundle)のドキュメント:

getView()フラグメントのレイアウト(onCreateView(LayoutInflater、ViewGroup、Bundle)によって返されるもの)のルートビューを取得します(提供されている場合)。

https://developer.Android.com/reference/Android/app/Fragment.html#getView()

123
Jason Robinson

メソッドをonCreateView()に移動しても助けにはなりませんでした...グローバル変数mViewを作成します

_ protected View mView;
_

およびonCreateView()

_ @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "oncreateView");
        super.onCreateView(inflater, container, savedInstanceState);

        View view = inflater.inflate(R.layout.activity_secure_cloud_drive_folder, container, false);
        this.mView = view;
        return view;
}
_

そして、すべてのgetView()mViewに置き換えます

21
spaceMonkey

これを修正するには、コードをonViewCreated()- method内に配置します。このメソッドはオーバーライドする必要があります。 super()を呼び出すことを忘れないでください。

8
Joaquin Iurchuk

OnAttach(...)関数でnullである理由を理解するには、Android Lifecycleを確認する必要があります。

フラグメントの作成時に呼び出される最初の関数はonAttach()ですが、実際にはビューは作成されていません。そのため、この呼び出し内でアクセスしようとするとnullが返されます。

次の関数はonCreate()...ですが、ビューはまだ作成されていません!!!!

呼び出される3番目の関数はonCreateView()であり、このフラグメントにアタッチされたビューがどれであるかを示す必要があるのはここです。ビューオブジェクトが存在し、アクセスできるこの呼び出しから。

ライフサイクル全体を読んで学ぶ こちら

あいさつ

4
Anibal Itriago

基本的に、ビューが膨張する前にgetview()を呼び出すため、nullになります。 Viewオブジェクトを作成し、inflaterを使用して入力し、UI要素を見つけます。以下のコードを参照してください

  View view = inflater.inflate(R.layout.fragment_albumslist, container, false);
        TextView t= (TextView)view.findViewById(R.id.txtTest);
        t.setText(strtext);
        return view;
1
Code_Worm