我正在尝试使用自定义适配器填充ListView 我想使用NotifyDatasetChanged刷新布局,但它不起作用 我从HTTP请求中检索一些JSON数据,然后操纵结果字符串,然后填充ListView
我的代码有什么问题? 更新代码(有关建议)
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:
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 :(得分:0)
<强>问题:强>
listData
是Cale
类中的变量。当您为其设置新值时,Cale
类中的变量将被修改。设置数据副本的其余代码不会更改。换句话说,当您修改CalendarioAdapter
类中的listData
时,Cale
内的数据不会更新。
<强>解决方案:强>
更改后,您需要再次将更新的listData
传递给适配器。为此,您需要在CalendarioAdapter
适配器内创建一个方法,该方法将负责更新适配器内部的数据,然后调用notifyDataSetChanged()
。
将此方法添加到CalendarioAdapter
适配器:
public void updateData(ArrayList<Calendario> updatedData) {
listDataInYourAdapter = newData;
this.notifyDataSetChanged();
}
现在使用该方法,在Cale
类中替换为:
adapter.notifyDataSetChanged();
用这个:
updateData(listData);
答案 1 :(得分:0)
这三行之后
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
改为执行此操作,然后通知
ParseJson();
listData.clear();
listData.addAll(getListData());
或者,为什么要拨打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中使用这两行(并且再次添加output
作为ParseJson
的参数,你不需要保存json = output
)。
ParseJson();
getListData();
答案 2 :(得分:0)
我解决了! 那是一件蠢事!
在parseJson sub中,我需要在填充之前清除数组!
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"));
}
}
答案 3 :(得分:0)
再次重新分配列表 - &gt;这不是推荐的行为。
以下是正确的方法:
适配器内部:public void update(List<ItemMessage> updatedList){
list.clear();
list.addAll(updatedList);
notifyDataSetChanged();}