安卓:notifyDataSetChanged的调用,但没有更新的ListView [英] Android: notifyDataSetChanged is called but ListView not updated

查看:98
本文介绍了安卓:notifyDataSetChanged的调用,但没有更新的ListView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到这个ListView控件是从网络上的JSON数据填充。但是,当我更新了JSON条目,例如添加新条目的ListView不更新。它不显示)列表eventhough我已经叫notifyDataSetChanged(在新的条目。

有人能帮助我吗?谢谢你。

下面是我的code:

 公共类ProjectsList延伸活动{
    / **当第一次创建活动调用。 * /
    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.projects_list);
        意图serviceIntent =新意图(这一点,LooserSync.class);
        startService(serviceIntent);
        ListView控件的ListView =(ListView控件)findViewById(R.id.lstText);
        MySimpleCursorAdapter projectAdapter =新MySimpleCursorAdapter(这一点,R.layout.listitems,
                managedQuery(Uri.withAppendedPath(LooserProvider.CONTENT_URI,
                        Database.Project.NAME),新的String [] {BaseColumns._ID,
                        Database.Project.C_PROJECTTITLE,Database.Project.C_SMALLIMAGE},NULL,NULL,
                        空),新的String [] {Database.Project.C_PROJECTTITLE,Database.Project.C_SMALLIMAGE},新的INT [] {
                        R.id.txt_title,R.id.image});
        listView.setAdapter(projectAdapter);
        projectAdapter.notifyDataSetChanged();
        listView.setOnItemClickListener(新OnItemClickListener(){
            公共无效onItemClick(适配器视图<>母公司,观景,INT位置,长的id){                意图I =新意图(ProjectsList.this,DetailsActivity.class);
                i.setData(Uri.withAppendedPath(Uri.withAppendedPath(
                        LooserProvider.CONTENT_URI,Database.Project.NAME),龙
                        的ToString(ID)));
                i.putExtra(spendino.de.ProjectDetail.position位置);
                startActivity(ⅰ);
            }
        });    }    类MySimpleCursorAdapter扩展SimpleCursorAdapter {        公共MySimpleCursorAdapter(上下文的背景下,INT布局,光标C,
                的String []从,INT []到){
            超(背景下,布局,C,从,到);
            装载机=新ImageLoaderCache(背景);
            this.context =背景;
        }
        活动活动= ProjectsList.this;
        上下文的背景下= NULL;
        ImageLoaderCache装载机= NULL;        公共无效setViewImage(ImageView的V,字符串值){
            v.setTag(值);
            loader.displayImage(价值活动,V);
        }
    }
}

这里已更新的的LooserSync.java

 公共类LooserSync扩展IntentService {    公共LooserSync(){
        超级(LooserSyncService);
    }    @覆盖
    保护无效onHandleIntent(意向意图){
        Database.OpenHelper dbhelper =新Database.OpenHelper(getBaseContext());
        SQLiteDatabase分贝= dbhelper.getWritableDatabase();
        DefaultHttpClient的HttpClient =新DefaultHttpClient();
        db.beginTransaction();
        HTTPGET请求=新HTTPGET(
                http://liebenwald.spendino.net/admanager/dev/android/projects.json);
        尝试{
            HTT presponse响应= httpClient.execute(请求);
            如果(response.getStatusLine()的getStatus code()== HttpStatus.SC_OK){
                InputStream的河道= response.getEntity()的getContent()。
                BufferedReader中R =新的BufferedReader(新的InputStreamReader(
                        插播广告),8000);
                StringBuilder的总=新的StringBuilder();
                串线;
                而((行= r.readLine())!= NULL){
                    total.append(线);
                }
                instream.close();
                串bufstring = total.toString();
                JSONArray ARR =新JSONArray(bufstring);
                Database.Tables标签= Database.Tables.AllTables.get(Database.Project.NAME);
                tab.DeleteAll(DB);
                的for(int i = 0; I< arr.length();我++){
                    tab.InsertJSON(分贝,(的JSONObject)arr.get(一));
                }
                db.setTransactionSuccessful();
            }
        }赶上(例外五){
            e.printStackTrace();
        }
        db.endTransaction();
        db.close();    }}


解决方案

由于您使用的游标来填充你必须得到一个新的列表或重新查询旧您更改后(添加,编辑或删除)在一些模型。

当你有一个新的光标,你可以通过调用<一个把它传递给适配器href=\"http://developer.android.com/reference/android/widget/CursorAdapter.html#changeCursor%28android.database.Cursor%29\"相对=nofollow> changeCursor()。

更新

继code将分别调用时onResume()得到一个新的光标。所以,你的列表应该是最新的。当然,这些都使得同时显示在列表上的模型更改不会更新到列表中。如果你想在列表的实时更新,你必须实现某种观察者模式。因此,当模型改变了你的活动将得到通知。

 公共类ProjectsList延伸活动{
    / **当第一次创建活动调用。 * /
    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.projects_list);
        意图serviceIntent =新意图(这一点,LooserSync.class);
        startService(serviceIntent);
        ListView控件的ListView =(ListView控件)findViewById(R.id.lstText);        最终的String [] =由新的String [] {Database.Project.C_PROJECTTITLE,Database.Project.C_SMALLIMAGE};
        最终诠释[]为= INT新[] {R.id.txt_title,R.id.image};        MySimpleCursorAdapter projectAdapter =新MySimpleCursorAdapter(这一点,R.layout.listitems,空,从,到);        listView.setAdapter(projectAdapter);        listView.setOnItemClickListener(新OnItemClickListener(){
            公共无效onItemClick(适配器视图&LT;&GT;母公司,观景,INT位置,长的id){                意图I =新意图(ProjectsList.this,DetailsActivity.class);
                i.setData(Uri.withAppendedPath(Uri.withAppendedPath(
                        LooserProvider.CONTENT_URI,Database.Project.NAME),龙
                        的ToString(ID)));
                i.putExtra(spendino.de.ProjectDetail.position位置);
                startActivity(ⅰ);
            }
        });    }    公共无效onResume(){
        光标光标= managedQuery(Uri.withAppendedPath(LooserProvider.CONTENT_URI,
                        Database.Project.NAME),新的String [] {BaseColumns._ID,
                        Database.Project.C_PROJECTTITLE,Database.Project.C_SMALLIMAGE},NULL,NULL,NULL);        ListView控件的ListView =(ListView控件)findViewById(R.id.lstText);
        ((CursorAdapter的)listView.getAdapter())changeCursor(光标);
    }

I got this ListView which is populated from a JSON data on the web. But when I updated the JSON entry, for example adding a new entry the ListView isn't updated. It doesn't show the new entry on the list eventhough I've already called the notifyDataSetChanged().

Can anybody help me? Thanks.

Here's my code:

public class ProjectsList extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.projects_list);
        Intent serviceIntent = new Intent(this, LooserSync.class);
        startService(serviceIntent);
        ListView listView = (ListView) findViewById(R.id.lstText);
        MySimpleCursorAdapter projectAdapter = new MySimpleCursorAdapter(this, R.layout.listitems,
                managedQuery(Uri.withAppendedPath(LooserProvider.CONTENT_URI,
                        Database.Project.NAME), new String[] { BaseColumns._ID,
                        Database.Project.C_PROJECTTITLE, Database.Project.C_SMALLIMAGE }, null, null,
                        null), new String[] { Database.Project.C_PROJECTTITLE, Database.Project.C_SMALLIMAGE }, new int[] {
                        R.id.txt_title, R.id.image });
        listView.setAdapter(projectAdapter);
        projectAdapter.notifyDataSetChanged();


        listView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {              

                Intent i = new Intent(ProjectsList.this, DetailsActivity.class);
                i.setData(Uri.withAppendedPath(Uri.withAppendedPath(
                        LooserProvider.CONTENT_URI, Database.Project.NAME), Long
                        .toString(id)));
                i.putExtra("spendino.de.ProjectDetail.position",position);
                startActivity(i);
            }
        });

    }

    class MySimpleCursorAdapter extends SimpleCursorAdapter {

        public MySimpleCursorAdapter(Context context, int layout, Cursor c,
                String[] from, int[] to) {
            super(context, layout, c, from, to);
            loader = new ImageLoaderCache(context);
            this.context = context;
        }
        Activity activity= ProjectsList.this;
        Context context=null;
        ImageLoaderCache loader = null;

        public void setViewImage(ImageView v, String value) {
            v.setTag(value);
            loader.displayImage(value, activity, v);
        }
    }


}

UPDATED here's the LooserSync.java

public class LooserSync extends IntentService {

    public LooserSync() {
        super("LooserSyncService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Database.OpenHelper dbhelper = new Database.OpenHelper(getBaseContext());
        SQLiteDatabase db = dbhelper.getWritableDatabase();
        DefaultHttpClient httpClient = new DefaultHttpClient();
        db.beginTransaction();
        HttpGet request = new HttpGet(
                "http://liebenwald.spendino.net/admanager/dev/android/projects.json");
        try {
            HttpResponse response = httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                InputStream instream = response.getEntity().getContent();
                BufferedReader r = new BufferedReader(new InputStreamReader(
                        instream), 8000);
                StringBuilder total = new StringBuilder();
                String line;
                while ((line = r.readLine()) != null) {
                    total.append(line);
                }
                instream.close();
                String bufstring = total.toString();
                JSONArray arr = new JSONArray(bufstring);
                Database.Tables tab = Database.Tables.AllTables.get(Database.Project.NAME);
                tab.DeleteAll(db);
                for (int i = 0; i < arr.length(); i++) {
                    tab.InsertJSON(db, (JSONObject) arr.get(i));
                }
                db.setTransactionSuccessful();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        db.endTransaction();
        db.close();

    }

}

解决方案

As you're using a cursor to populate the list you have to get a new one or requery the old one after you changed (add, edit or remove) something on your model.

When you got a new cursor you can pass it to the adapter by calling changeCursor().

UPDATE

Following code will get a new cursor each time onResume() called. So your list should be up to date. Of course changes on the model which are made while the list is shown are not updated to the list. If you want a live update of the list you have to implement some kind of observer pattern. So your activity would get notified when the model changed.

public class ProjectsList extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.projects_list);
        Intent serviceIntent = new Intent(this, LooserSync.class);
        startService(serviceIntent);
        ListView listView = (ListView) findViewById(R.id.lstText);

        final String[] from = new String[] { Database.Project.C_PROJECTTITLE, Database.Project.C_SMALLIMAGE };
        final int[] to = new int[] {R.id.txt_title, R.id.image};

        MySimpleCursorAdapter projectAdapter = new MySimpleCursorAdapter(this, R.layout.listitems, null, from, to);

        listView.setAdapter(projectAdapter);

        listView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {              

                Intent i = new Intent(ProjectsList.this, DetailsActivity.class);
                i.setData(Uri.withAppendedPath(Uri.withAppendedPath(
                        LooserProvider.CONTENT_URI, Database.Project.NAME), Long
                        .toString(id)));
                i.putExtra("spendino.de.ProjectDetail.position",position);
                startActivity(i);
            }
        });

    }

    public void onResume(){
        Cursor cursor = managedQuery(Uri.withAppendedPath(LooserProvider.CONTENT_URI,
                        Database.Project.NAME), new String[] { BaseColumns._ID,
                        Database.Project.C_PROJECTTITLE, Database.Project.C_SMALLIMAGE }, null, null, null);

        ListView listView = (ListView) findViewById(R.id.lstText);                         
        ((CursorAdapter)listView.getAdapter()).changeCursor(cursor);
    }

这篇关于安卓:notifyDataSetChanged的调用,但没有更新的ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆