0

現在のステータスバー通知のリストを表示するrecyclerViewを作成しようとしていました。私はすべての通知を格納するためにSQLiteのDBを使用していますList notifyDataSetChanged()がカスタムRecyclerViewアダプタで動作しない

NotificationItemInformation
public class NotificationItemInformation 
{ 
    int iconId,noitId; 
    String packageName; 
    Drawable notiIcon; 
} 

を取るカスタムアダプタ(NotiRecyclerAdapter)を作成しました。 NotificationListenerServiceは、通知がポストされたり削除されたりするたびに、DBから書き込みおよび削除を行います。

私はNotificationItemInformationListにDBの内容を読み取るために(myDBHelperの内部にある)

public List<NotificationItemInformation> ReadNotilist (Context context); 

と呼ばれる方法を使用するには、(私の主な活動で、地球公共および静的である)dataと呼ばれます。 私はadapter(私のメインアクティビティではグローバル、パブリック、スタティック)を使用してdataを取得し、onCreateメソッド内のRecyclerViewに私のMainActivityを設定します。

これまでのところすべてうまくいきました。現在StatusBar通知が入力されたRecyclerViewが表示されます。

問題は、アクティビティを再開するまでリストが更新されない(新しい通知があった場合)ということです。私は私のNotificationListenerServiceの(DBに追加した後)onNotificationPosted内... ...呼び出し

MainActivity.data.clear(); 
MainActivity.data = dbh.ReadNotilist(this); // dbh is DBhelper object 
MainActivity.adapter.notifyDataSetChanged(); 

を試してみました。しかし、私は活動を再開するまでまだRecyclerViewは更新されていません。

あなたが見たい場合はここに私のMainActivityです。ここで

public class MainActivity extends AppCompatActivity 
{ 

    SQLiteDatabase db; 
    DBHelper dbh; 

    RecyclerView notificationIconRecyclerView; 
    public static NotiRecyclerAdapter adapter; 
    public static List<NotificationItemInformation> data = Collections.EMPTY_LIST; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     dbh = new DBHelper(this); 
     db = dbh.getDb(); 
     notificationIconRecyclerView = (RecyclerView) findViewById(R.id.notificationIconRecyclerView); 
     data = dbh.ReadNotilist(this); 
     adapter = new NotiRecyclerAdapter(this,data); 
     notificationIconRecyclerView.setAdapter(adapter); 
     notificationIconRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,true)); 
    } 
} 

は、データオブジェクトへの参照をリセットしないでくださいRecyclerView

public class NotiRecyclerAdapter extends RecyclerView.Adapter<NotiRecyclerAdapter.MyViewHolder> 
{ 

    private LayoutInflater inflater; 
    List<NotificationItemInformation> data = Collections.emptyList(); 

    NotiRecyclerAdapter(Context context, List<NotificationItemInformation> data) 
    { 
     inflater = LayoutInflater.from(context); 
     this.data = data; 
    } 


    @Override 
    public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer) 
    { 
     super.registerAdapterDataObserver(observer); 
    } 

    @Override 
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    { 
     View view = inflater.inflate(R.layout.custom_recyclerview_item,parent,false); 
     MyViewHolder holder = new MyViewHolder(view); 
     return holder; 
    } 

    @Override 
    public void onBindViewHolder(MyViewHolder holder, int position) 
    { 
     NotificationItemInformation current = data.get(position); 
     holder.recyclerItemIcon.setImageDrawable(current.notiIcon); 
    } 

    @Override 
    public int getItemCount() 
    { 
     return data.size(); 
    } 

    public class MyViewHolder extends RecyclerView.ViewHolder 
    { 
     ImageView recyclerItemIcon; 
     public MyViewHolder(View itemView) 
     { 
      super(itemView); 
      recyclerItemIcon = itemView.findViewById(R.id.notiRecyclerItemIcon); 
     } 
    } 

} 
+0

あなたのアダプターのコンストラクターを見るのが好きです。データリストのコピーを作成していると思われます。実際には、アダプタコード全体を見ると便利です。 –

+0

@ BenP。助けてくれてありがとう、私は今質問の全体のアダプタコードを追加しました。 –

答えて

0

のための私のカスタムアダプタです。代わりに、このような何かしてみてください:

MainActivity.data.clear(); 
MainActivity.data.addAll(dbh.ReadNotilist(this)); 
MainActivity.adapter.notifyDataSetChanged(); 
+0

ありがとうございました! 。これは問題を解決しました! –

0

アダプタのコンストラクタでは、あなたはこれがあなたのアダプタのdataフィールドに、コンストラクタに渡されたList<NotificationItemInformation>割り当て

this.data = data; 

書きます。あなたのアダプタは、このように構成されています

adapter = new NotiRecyclerAdapter(this,data); 

これはあなたのMainActivity.dataフィールドとあなたのadapter.dataフィールドは、両方の同じリストを参照していることを意味します。

後で、書き:

MainActivity.data.clear(); 
MainActivity.data = dbh.ReadNotilist(this); 
MainActivity.adapter.notifyDataSetChanged(); 

最初の行はMainActivity.dataadapter.dataをクリアします(彼らは、アダプタを構築した方法が原因同じリストだ、覚えておいてください)。 2行目はMainActivity.dataに新しいリストを割り当てますが、決してadapter.dataには影響しません。 3行目は、アダプターにデータセットが変更されたことを通知します(これはクリアされていますが、アダプターは新しい情報をdbh.ReadNotilist()から「見る」ことはありません)。 MainActivity.dataadapter.dataはまだ同じListを指していることを代わりに割り当て(=)のaddAll()手段を用い、そのアダプタが新しい情報を「見る」になるため

AChez9の答えは動作します。

この理由から、コピーののリストを外部ソースから受け取ったときに作成するのが正しいことがよくあります。言い換えれば、あなたのアダプタのコンストラクタはこれをしたいかもしれません:

this.data = new ArrayList<>(data); 

これは、それが(この場合、MainActivity.dataに)渡されたリストへの変更から「安全」であることを意味します。しかし、これはあなたの活動があなたのアダプターを正しく更新する方法を公開する必要があることを意味します。私はこのような方法をお勧めします:

public void updateData(List< NotificationItemInformation> data) { 
    this.data = new ArrayList<>(data); 
    notifyDataSetChanged(); 
} 
関連する問題