2016-10-07 5 views
0

カスタムアダプターを使用してListViewを埋めようとしています。
NotifyDatasetChangedを使用してレイアウトを更新したいが、動作しません。
HTTPリクエストからいくつかのJSONデータを取得し、結果の文字列を操作してListViewに入力しますNotifyDatasetChangedがカスタムアダプターで動作していません

私のコードで何が問題になっていますか?

import android.content.Context; 
import android.graphics.Color; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.TextView; 

import java.util.ArrayList; 

public class CalendarioAdapter extends BaseAdapter { 
    private ArrayList listData; 
    private LayoutInflater layoutInflater; 
    final static String TAG = "sb.dl"; 

    public CalendarioAdapter(Context context, ArrayList listData) { 
     Log.d(TAG, "CalendarioAdapter"); 
     this.listData = listData; 
     layoutInflater = LayoutInflater.from(context); 
    } 

    @Override 
    public int getCount() { 
     return listData.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return listData.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     Log.d(TAG, "CalendarioAdapter.getView"); 
     ViewHolder holder; 

     if (convertView == null) { 
      convertView = layoutInflater.inflate(R.layout.calendario_row_layout, null); 
      holder = new ViewHolder(); 
      holder.edId = (TextView) convertView.findViewById(R.id.edId); 
      holder.edData = (TextView) convertView.findViewById(R.id.edData); 

      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     Calendario newsItem = (Calendario) listData.get(position); 
     holder.edId.setText(newsItem.getId()); 
     holder.edData.setText(newsItem.getData()); 

     return convertView; 
    } 

    static class ViewHolder { 
     TextView edId; 
     TextView edData; 
    } 

public void updateData(ArrayList<Calendario> updatedData) { 
    listData = updatedData; 
    this.notifyDataSetChanged(); 
} 
} 
+0

さてあなたは、常に同じパラメータを使用しているハンドラを使用してそれを行うことを忘れてはいけないので、どのような場合データは同じですか? – vilpe89

+0

CalendarioAdapterコードを追加してください –

+0

?私はコメントにすることはできません – Simone

答えて

0

問題:

listDataCaleクラスの内部変数である UPDATE(アドバイスについて)CODE

public class CalendarioFragment extends Fragment { 
    ListView listView; 
    ArrayList<Calendario> calenList; 
    CalendarioAdapter adapter; 
    String json; 
    ArrayList<String> arrayId = new ArrayList<String>(); 
    ArrayList<String> arrayData = new ArrayList<String>(); 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.calendario_layout, null); 

     listView = (ListView) view.findViewById(R.id.listCale); 
     listView.setEmptyView(view.findViewById(R.id.emptyElement)); 

     calenList = new ArrayList<Calendario>(); 
     adapter = new CalendarioAdapter(getActivity(), calenList); 
     listView.setAdapter(adapter); 

     execQuery("query", "0"); 

     return view; 
    } 

    private void execQuery(final String query, final String taskId) { 
     final MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse() { 
      @Override 
      public void onTaskCompleted(String output) { 

       if (output == null) { 
        Toast.makeText(getActivity(), "Nessuna connessione internet attiva!", Toast.LENGTH_SHORT).show(); 
       } else { 
        json = output; 

        try { 
         ParseJson(); 
         calenList.clear(); 

         String[] ids = arrayId.toArray(new String[arrayId.size()]); 
         String[] date = arrayData.toArray(new String[arrayData.size()]); 

         for (int i = 0; i < ids.length; i++) { 
          Calendario calendario = new Calendario(); 
          calendario.setId(ids[i]); 
          calendario.setData(date[i]); 

          calenList.add(calendario); 
          adapter.updateData(calenList); 
         } 

        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }, getActivity()); 

     asyncTask.execute(query, taskId); 
    } 

    private void ParseJson() throws JSONException { 
     JSONObject jsonObject = new JSONObject(json); 
     JSONArray jsonArray = jsonObject.getJSONArray("risposta"); 

     for (int i = 0; i < jsonArray.length(); i++) { 
      JSONObject JO = jsonArray.getJSONObject(i); 
      arrayId.add(JO.getString("ID")); 
      arrayData.add(JO.getString("DATA")); 
     } 
    } 
} 

これはCustomAdapterCodeあります。新しい値を設定すると、Caleクラスの変数が変更されています。データの複製が設定されている残りのコードは変更されていません。換言すれば、CalendarioAdapterの内部のデータは、CaleクラスにあるlistDataを変更しても更新されません。

ソリューション:

あなたはそれが変更された後に更新listDataが再びアダプタに渡す必要があります。これを行うには、CalendarioAdapterアダプタ内のメソッドを作成し、アダプタ内のデータを更新してからnotifyDataSetChanged()を呼び出します。

あなたCalendarioAdapterアダプタにこのメソッドを追加します。後

updateData(listData); 
+0

@Simone私の答えはあなたにとって有益でしたか? – Marat

0

:これで

adapter.notifyDataSetChanged(); 

:あなたのCaleクラスでこれを置き換え、そのメソッドを使用するために今すぐ

public void updateData(ArrayList<Calendario> updatedData) { 
    listDataInYourAdapter = newData; 
    this.notifyDataSetChanged(); 
} 

これらの3行は

listData = new ArrayList<Calendario>(); 
adapter = new CalendarioAdapter(getActivity(), listData); 
listView.setAdapter(adapter); 

listDataを再割り当てしないでください。これを実行すると、アダプター内のリストの参照が切り離され、更新の通知を受けなくなります。

代わりに、clear()、次にaddAll()がリストに必要です。例えば

ParseJson(); // You should really pass 'output' as a parameter here 
listData = getListData(); // Don't re-assign 

はなぜlistData.addAll(getListData());を呼び出し、また

ParseJson(); 
listData.clear(); 
listData.addAll(getListData()); 

を通知し、その後、これに代えていますか?すでにクリア、追加、および通知の正しいことを行うこのメソッドがあります。

private ArrayList<Calendario> getListData() { 

    listData.clear(); // Cleared 
    String[] ids = arrayId.toArray(new String[arrayId.size()]); 
    String[] date = arrayData.toArray(new String[arrayData.size()]); 

    for (int i = 0; i < ids.length; i++) { 
     Calendario calendario = new Calendario(); 
     calendario.setId(ids[i]); 
     calendario.setData(date[i]); 

     listData.add(calendario); // Adding 
    } 

    adapter.notifyDataSetChanged(); // Notify 

    return listData; 
} 

ので、現実的に、あなただけのAsyncTaskでこれらの2行を必要とする(そして再び、あなたはjson = outputを保存する必要はありません、ParseJsonのパラメータとしてoutputを追加する必要があります)。

ParseJson(); 
getListData(); 
+0

申し訳ありません..常に同じ結果:( – Simone

+0

あなたは私の答えに完全に従っているかどうかはわかりません。まだ更新されていますが、あなたはまだ 'listData = updatedData;' –

+0

です。 – Simone

0

解決済み! それは愚かなことでした!

parseJsonサブでは、配列をクリアしてから入力する必要があります。

private void ParseJson() throws JSONException { 
    JSONObject jsonObject = new JSONObject(json); 
    JSONArray jsonArray = jsonObject.getJSONArray("risposta"); 

    arrayId.clear(); 
    arrayData.clear(); 

     for (int i = 0; i < jsonArray.length(); i++) { 
      JSONObject JO = jsonArray.getJSONObject(i); 
      arrayId.add(JO.getString("ID")); 
      arrayData.add(JO.getString("DATA")); 
     } 
    } 
0

リストをもう一度割り当て直してください - >これは推奨されない動作です。アダプタ内部 : はここに正しいことを行うにはどのような方法であるpublic void update(List<ItemMessage> updatedList){ list.clear(); list.addAll(updatedList); notifyDataSetChanged();}

関連する問題