2017-07-19 6 views
0

私は、recyclerviewのアイテムをクリックした後に、異なるデータでrecyclerviewを設定したい(そして別のレイアウトを採用したい)。 recyclerviewを生成するために使用されるデータは、firebaseリアルタイムデータベースからのものです。アイテムがクリックされると、recyclerviewは選択されたノードの子を表示することになっています。新しいアクティビティを開始し、新しいレイアウト全体を拡張する代わりに。私は1つのレイアウトの一部を変更しようとします。私は、レンダリング、メモリ、バッテリーの性能に関してパフォーマンス上の利点があるかもしれないと考えています(含まれるファイルが少なくて済み、apkも小さくなります)。コードをプロファイルし、複数のアクティビティがある場合と比較する必要があることを認識していますが、まずコードをデータベースの上下に移動させたいと考えています。私のMainFragmentには、recyclerviewのAdapterクラスで呼び出されるリスナーが含まれています(下図参照)。リアルタイムデータベースで作業するときに異なるRecyclerViewアイテムのレイアウトを使用する

@Override 
public void setItemLayoutResuorce(String key) { 
    Log.i("Hilarity", "SILR"); 
    mMessagesDatabaseReference = mMessagesDatabaseReference.child(key); 
    Log.i("Hilarity", mMessagesDatabaseReference.getKey()); 
    mChildEventListener = new ChildEventListener() { 
     @Override 
     public void onChildAdded(DataSnapshot dataSnapshot, String s) { 
      if (mMessagesDatabaseReference.getKey().equals(getString(R.string.languages))) { 
       String langauge = dataSnapshot.getKey(); 
       languages.add(langauge); 
       jokeAdapter.notifyItemInserted(languages.size() - 1); 
       jokeAdapter.notifyDataSetChanged(); 
       Log.i("Hilarity", "languages add"); 
      } else { 
       Log.i("Hilarity", "joke added"); 
       Joke joke = dataSnapshot.getValue(Joke.class); 
       jokes.add(joke); 
       jokeAdapter.notifyItemInserted(jokes.size() - 1); 
       jokeAdapter.notifyDataSetChanged(); 
      } 
     } 

     public void onChildChanged(DataSnapshot dataSnapshot, String s) {} 
     public void onChildRemoved(DataSnapshot dataSnapshot) {} 
     public void onChildMoved(DataSnapshot dataSnapshot, String s) {} 
     public void onCancelled(DatabaseError databaseError) {} 
    }; 
    mMessagesDatabaseReference.addChildEventListener(mChildEventListener); 
    jokeAdapter = new JokeAdapter(getActivity(), jokes, languages, this, true); 
    recyclerview.setAdapter(jokeAdapter); 

それは(Adapter.ViewHolder.onClickで呼ばれています)(下図)

@Override 
    public void onClick(View view){ 
     if (view instanceof TextView) { 
      showJokes = true; 
      TextView textView = (TextView) view; 
      rvc.setItemLayoutResuorce(textView.getText().toString()); 
     } 
    } 

私はリサイクルビュー項目をクリックしてrecyclerviewは、データを再作成する必要がありますが、ときに致命的なエラーが来ますデータがありません(まだ)、私はIndex.InBindViewHolderの範囲外の例外を取得します。それはchildEventListenerのようなもので、私が作成したリスナー(元々MainFragment.onCreate()で作成された)で再インスタンス化されてもリセットされません。

ボタンをクリックした後にデータベースに新しいデータを送信させるにはどうすればいいですか?(他のものはすべて動作しているように見えますが、新しいレイアウトリソースはrecyclerviewにデータを入れるために必要です)このコード部分をC++で記述し、DatabaseReferenceおよびChildEventListenerオブジェクトへの参照を手動で削除してから作成するといいでしょうか?

答えて

0

バックグラウンドスレッドでデータソース(あなたの場合はFirebase)からRecyclerViewのコンテンツを直接更新しているようです。

RecyclerViewで表示する必要があるすべてのデータをバックグラウンドスレッドで収集し、ローカルコピー(ローカルArrayListまたはMap、データ構造に依存します)に保存するのは、UIスレッドで、 notifyDataSetChanged()または異なる更新方法でアダプタから更新します。最初の更新は最後の1まで指定された位置から、アダプタのすべての項目を更新する必要がありますよう、notifyItemInserted()を呼び出した後notifyDataSetChanged()権利をコールする必要はありません

jokeAdapter.notifyItemInserted(jokes.size() - 1); 
jokeAdapter.notifyDataSetChanged(); 

はまた、あなたのコードで私は冗長な呼び出しを発見しました。 notifyDataSetChangedの追加通話は更新を繰り返すだけですが、すべてのアイテムについて繰り返されます。

関連する問題