29

我在服务器中有一个数据库,从平板电脑中我从数据库中的一个表中获取一些值。我将此信息正确加载到列表中,但我想知道为什么在发生更改时,即使我使用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();
                }
            });

        }

    }
}
4

8 回答 8

118

notifyDataSetChanged()对您不起作用的主要原因之一是,

您的适配器失去了对您的列表的引用

当您第一次初始化时,Adapter它会引用您的引用arrayList并将其传递给它的超类。但是,如果您重新初始化现有arrayList的,它将失去参考,因此,与Adapter.

在创建新列表并将其添加到Adapter. 始终遵循以下准则:

  1. arrayList在全局声明时初始化。
  2. 直接将 List 添加到适配器,而不检查 null 和空值。直接将适配器设置到列表中(不检查任何条件)。适配器向您保证,无论您对数据进行更改,arrayList它都会处理它,但永远不会丢失参考。
  3. 始终修改 arrayList 本身中的数据(如果您的数据是全新的,那么您可以调用adapter.clear()并且arrayList.clear()在实际将数据添加到列表之前)但不要设置适配器,即如果新数据填充arrayListadapter.notifyDataSetChanged()

忠于文档。

于 2013-12-09T19:32:49.127 回答
5

你需要编辑的东西是把你的

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 列表的计时器。

于 2013-04-23T09:49:20.400 回答
5

如果您对registerDataSetObserver(). Android Studio 为我添加了一个,但没有实现对 super 的调用。如下添加它足以让我的 listView 再次工作:

@Override
    public void registerDataSetObserver(DataSetObserver observer) {
        super.registerDataSetObserver(observer);    
    }
于 2015-01-30T18:14:16.153 回答
3

适配器定义布局的组成部分!-> 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

于 2013-04-23T09:45:19.617 回答
2

应该从 UI 线程调用更新函数。我的答案实际上与@user1621629 的答案相似,不同之处在于我使用的是 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();
        }
    });
}
......
于 2017-02-20T16:32:05.033 回答
1

正如Hissain 上面所描述的

您需要维护对列表的引用

这是我如何让它工作的:

  1. 让发送给适配器的列表设置为活动中的实例成员

  2. 在对数据执行更改的逻辑中,确保它更新了活动传递给适配器的相同列表实例

  3. 然后调用 .notifyDataSetChanged(); 工作过

请记住,listView 位置从 1 开始,因此您必须为您的 java.util.List 执行 (listViewPosition - 1)

于 2014-03-05T19:03:12.017 回答
1

我对 Hissain 先生的回答没有太多的评论。这是正确的,但我想再提一件事,对列表的引用不应该改变。如果底层数据源发生变化,请不要更改对新列表的引用。只需对同一个列表对象执行操作。为此,请使用 clear() 清除列表,然后使用 add() 或 addALL() 将数据添加到同一列表中,然后调用 notifyDataSetChanged()。例如。在列表的第一次初始化

list = dataSource.getList();

然后可以从列表中添加和删除内容并调用 notifyDataSetChanged() 它工作正常,但如果在代码中,尝试更改对另一个对象的引用。像

list = dataSource.getList();

其中 getList() 每次都返回新列表,因此引用更改为其他列表对象并调用 notifyDataSetChnaged 不会对列表产生影响。但是如果 getList() 返回相同的列表对象,则它可以正常工作。

于 2015-03-11T06:19:07.690 回答
0

如果您设置的一切都很好但仍然无法正常工作,那么您的列表...是否是列表中的 Mutablekind...!

private val demoList: MutableList<AnyClass> = mutableListOf()

一旦你像上面可变的方式定义了你的列表,那么你就可以获得该方法

.add
.addAll
.remove

ETC...

否则,如果您创建了普通列表,那么它将无法正常工作notifyDataSetChanged

于 2019-09-20T07:51:17.863 回答