質問: messageData.getMessageList(); } notifyDataSetChanged(); } ``` としています。 データの更新があったら`setData`を呼び出してMyArrayAdapterを更新しているのですが、更新される場合とされない場合があります。 * MethodAから呼ぶと更新される: `getView`が呼ばれてListViewに反映される * MethodBから呼ぶと更新されない: 更新されたデータだけ`getView`が呼ばれず、ListViewに反映されない(元々入っていた要素に関しては'getView'が呼ばれている) * MethodA、MethodBはMainThreadから実行している(各メソッド内でThread確認済み) ほとんど同じ処理であり、Listデータの数も更新されたものが渡されています。MyArrayAdapterが保持するListデータもMethodAの場合もMethodBの場合もsizeが更新されて数が増えているのですが、MethodBで実行すると新規で追加したデータに関してのみListViewに更新がかからない状態です。 MethodBで呼び出した場合は新規データの箇所のみMyArrayAdapterのgetViewが呼ばれず、 既存のデータに関してはgetViewが呼ばれます。 つまりMethodBの場合は表示が変更されません。 MethodBの実装 Hogeクラス内で ``` public void MethodB(JSONArray array){ //JSONからListを取り出す ListmessageList=jsonUtil.getMessageDataList(array); if(messageList.size()!=0){ userData.addMessageDataAll(messageList); userData=saveDataUtil.setUserData(userData); messageData=userData.getMessageData("ID"); if(messageData!=null){ //この時点では新規データが入っており更新されている messageData.getMessageList().size()="+messageData.getMessageList().size()); adapter.setData(messageData); //ここでlist.getCount()したがサイズが増えていない。 listView.setSelection(listView.getCount()-1); }else{ Log.e(TAG,"messageData==null"); } } ``` MethodAの実装 ``` public void MethodA(JSONArray array){ List detailList=jsonUtil.getMessageDetailList(array); Log.d(TAG,"送信したMessageDetail messageDetailList.size="+detailList.size()); if(detailList.size()!=0){ MessageDetail detail=detailList.get(0); messageData.addMessageList(detail); userData.setMessageData(messageData); userData=saveDataUtil.setUserData(userData);//userData保存 messageData=userData.getMessageData("ID"); if(messageData!=null){ adapter.setData(messageData); }else{ Log.e(TAG,"userData.messageData==null"); } listView.setSelection(listView.getCount()-1); } ``` MethodAとMethodBは共にVolleyのJSONArray取得メソッドから呼び出されています。 この場合どのような状況が考えられるのでしょうか?
回答: 推測になってしまうのですが、単に参照の問題だと思います。 `ArrayAdapter`はコンストラクタで受け取ったリスト(配列のオーバーロードコンストラクタでは、`Arrays.asList()`を利用してリストに変換する)を、`ListView`などに表示するアダプタです。 サブクラスを作る場合、「**`ArrayAdapter`が管理する`List`は`private`であり、サブクラスから参照を変更できない**」という点に注意する必要があります。 `ArrayAdapter`は、Class Referenceにあるように一度保持したリストに対して、`add()`、`clear()`、`remove()`などのメソッドで操作するアダプタクラスになります。リストそのものの参照を外部から置き換えたい場合には、`BaseAdapter`を継承した方が楽です。 表題の事象が起こり得るとすれば、以下のような原因かと思います。 * `MethodA()`の呼び出し側で更新しているリストは、`ArrayAdapter`のコンストラクタに渡したリストの参照なので、`ArrayAdapter`が内部で管理しているリスト=`ListView`が更新される。 * `MethodB()`の呼び出し側ではリストを新規に生成して、`MyArrayAdapter`のメンバ変数を更新しているだけなので`ListView`は更新されない