我在服务器中有一个数据库,从Tablet中我从数据库中的一个表中获取一些值。我将这些信息正确地加载到列表中但我想知道为什么当有更改时,即使我使用notifyDataSetChanged();
也没有任何反应。我必须说,为了加载加载数据,请使用AsyncTaskClass
所以,我的问题是我不知道是否使用notifyDataSetChanged();方法正确,因为如果有更改我想刷新图像。以下是该类代码的一部分:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.all_candidatos);
candidatosList = new ArrayList<HashMap<String, String>>();
new CargarCandidatos().execute();
}
// public void timer(){
// new CountDownTimer(tiempo, 100) {
//
// public void onTick(long millisUntilFinished) {
//
// }
//
// public void onFinish() {
// // new CargarCandidatos().execute();
//
// }
// }.start();}
/**
* Background Async Task to Load all product by making HTTP Request
* */
class CargarCandidatos extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Monitorizacion.this);
pDialog.setMessage("Loading ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
JSONObject json = jParser.makeHttpRequest(url_candidatos, "GET", params);
Log.d("Candidatos: ", json.toString());
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
candidatos = json.getJSONArray(TAG_CANDIDATOS);
for (int i = 0; i < candidatos.length(); i++) {
JSONObject c = candidatos.getJSONObject(i);
// Storing each json item in variable
String nserie = c.getString(TAG_NSERIE);
String dni = c.getString(TAG_DNI);
String nombre = c.getString(TAG_NOMBRE);
String test = c.getString(TAG_TEST);
String pregunta = c.getString(TAG_PREGUNTA);
String bateria = c.getString(TAG_BATERIA);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_NSERIE, nserie);
map.put(TAG_DNI, dni);
map.put(TAG_NOMBRE, nombre);
map.put(TAG_TEST, test);
map.put(TAG_PREGUNTA, pregunta);
map.put(TAG_BATERIA, bateria);
// adding HashList to ArrayList
candidatosList.add(map);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
pDialog.dismiss();
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
adapter = new SimpleAdapter(
Monitorizacion.this, candidatosList,
R.layout.list_item, new String[] { TAG_NSERIE,
TAG_DNI, TAG_NOMBRE, TAG_TEST, TAG_PREGUNTA, TAG_BATERIA},
new int[] { R.id.id, R.id.dni, R.id.nombre, R.id.test, R.id.pregunta, R.id.bateria});
setListAdapter(adapter);
adapter.notifyDataSetChanged();
// timer();
}
});
}
}
}
答案 0 :(得分:88)
notifyDataSetChanged()
不适合您的主要原因之一是
您的适配器失去对列表的引用。
首次初始化Adapter
时,需要引用arrayList
并将其传递给超类。但是,如果您重新初始化现有的arrayList
,它会丢失引用,从而丢失与Adapter
的通信渠道。
创建新列表并向Adapter
添加新列表时。始终遵循以下准则:
arrayList
。arrayList
的数据进行更改,它会处理它,但永远不会松散
参考adapter.clear()
和arrayList.clear()
实际上将数据添加到列表中)但是没有设置适配器,即If
新数据填充在arrayList
而不仅仅是
adapter.notifyDataSetChanged()
坚持文档。
答案 1 :(得分:4)
你需要编辑的东西是你的
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
adapter = new SimpleAdapter(
Monitorizacion.this, candidatosList,
R.layout.list_item, new String[] { TAG_NSERIE,
TAG_DNI, TAG_NOMBRE, TAG_TEST, TAG_PREGUNTA, TAG_BATERIA},
new int[] { R.id.id, R.id.dni, R.id.nombre, R.id.test, R.id.pregunta, R.id.bateria});
setListAdapter(adapter);
adapter.notifyDataSetChanged();
// timer();
}
});
进入OnCreate()。并从Asynctask返回列表candidatosList。比设置计时器更新candidatosList列表。
答案 2 :(得分:3)
适配器定义布局的comportement! - &GT; setListAdapter():为ListView / GridView / Gallery定义适配器... 但是你需要指定数据!
我建议您在'onCreate'或构造函数中初始化'setListAdapter'。 将数据设置到适配器(例如:adapter.setItem(yourData))
之后现在!你应该调用notifyDataSetChanged! 因为您已更改数据但视图未刷新且notifydatasetchanged()重新加载视图的内容(ListView / GridView / Gallery ...)
为了良好的做法并正确理解,我建议您使用“ baseAdapter ”来使用“自定义适配器”
阅读并完成本教程(我已经了解到这一点):http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
阅读文档:http://developer.android.com/reference/android/widget/BaseAdapter.html
答案 3 :(得分:3)
如果registerDataSetObserver()
有空替代值,可能值得一试。 Android Studio为我添加了一个而没有实现对super的调用。如下添加它足以让我的listView再次工作:
@Override
public void registerDataSetObserver(DataSetObserver observer) {
super.registerDataSetObserver(observer);
}
答案 4 :(得分:1)
您需要维护对列表的引用
以下是我如何使用它:
让发送到适配器的列表设置为活动中的实例成员
在对数据执行更改的逻辑中,确保它更新活动传递给适配器的相同列表实例
然后调用.notifyDataSetChanged();工作
请记住,listView位置从1开始,因此您必须为您的java.util.List执行(listViewPosition - 1)
答案 5 :(得分:1)
应该从UI线程调用更新函数。 我的答案实际上与@ user1621629的answer相似,但我使用的是rxJava,所以这里有解决这个问题的工作代码:
this.subscriber = myAdapter.getSubscriber(); // keep for unsubscribe in destroy
dataSource.subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread()).subscribe(this.subscriber);
所以我设置所有执行以便将列表的数据提供给计算线程,但是在UI线程中显示结果。
以下是我为此创建订阅者的方式:
public class MyListAdapter extends RecyclerView.Adapter<LocationListAdapter.ViewHolder> {
private List<ListItem> mDataset = new ArrayList<>();
public Subscriber<ListItem[]> getSubscriber() {
return Subscribers.create(new Action1<ListItem[]>() {
@Override
public void call(ListItem[] listItems) {
mDataset.clear();
mDataset.addAll(Arrays.asList(listItems));
notifyDataSetChanged();
}
});
}
......
答案 6 :(得分:0)
我对Hissain先生的回答没有多大的评价。这是正确的,但我想提一下,对列表的引用不应该改变。如果基础数据源正在更改,请不要更改对新列表的引用。只需要在同一个列表对象上执行操作。要做到这一点,使用clear()清除列表,然后使用add()或addALL()将数据添加到同一列表,然后调用notifyDataSetChanged()。例如。 首次初始化列表
list = dataSource.getList();
然后可以添加和删除列表中的内容并调用notifyDataSetChanged()它工作正常,但如果在代码中,则尝试更改对另一个对象的引用。像
list = dataSource.getList();
其中getList()每次都返回新列表,因此引用更改为其他列表对象,并且调用notifyDataSetChnaged对list也没有影响。但是如果getList()返回相同的列表对象,则它可以正常工作。
答案 7 :(得分:0)
如果您设置的所有内容仍然无法使用,那么您的列表... 是列表中的Mutablekind ...!
private val demoList: MutableList<AnyClass> = mutableListOf()
一旦您按照上述可变方式定义了列表,就可以获得方法
.add
.addAll
.remove
等...
否则,如果您已创建普通列表,则该列表将不会像notifyDataSetChanged