Android ListView refresh



我有一个Listview,它从sqlite DB中提取并显示数据。DB的第一列中的数据显示在ListView中,当单击时,Activity开始显示与第一列相关联的列的其余部分。编辑数据时,ListView需要更新以反映这一点,但除非重新启动应用程序,否则它不会显示更新。

我试过在onResume()方法中调用notifyDataSetChanged()startActivityForResult(),但没有成功。我应该使用什么方法来更新当前代码中的ListView

我知道可能会使用SimpleCursorAdapter,我曾尝试实现该代码,但没有成功。我是一个新手,需要实际的代码来理解需要做什么。

public class LoginList extends Activity implements OnClickListener, OnItemClickListener {
    private ListView loginList;
    private Button webLogin;
    private ListAdapter loginListAdapter;
    private ArrayList<LoginDetails> loginArrayList;
    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login_listview);
        loginList = (ListView)
        findViewById(R.id.loginlist);
        loginList.setOnItemClickListener(this);
        webLogin = (Button)
        findViewById(R.id.button3);
        webLogin.setOnClickListener(this);
        loginArrayList = new ArrayList<LoginDetails>();
        loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList());
        loginList.setAdapter(loginListAdapter);
    }
    @Override
    public void onClick (View v) {
        Intent webLoginIntent = new Intent (this, LoginPlusActivity.class);
        startActivity(webLoginIntent);
    }
    public List<String> populateList () {
        List<String> webNameList = new ArrayList<String>();
        dataStore openHelperClass = new dataStore (this);
        SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase();
        Cursor cursor = sqliteDatabase.query(dataStore.TABLE_NAME_INFOTABLE, null, null, null, null, null, dataStore.COLUMN_NAME_SITE, null);
        startManagingCursor(cursor);
        while (cursor.moveToNext()) {
            String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE));
            String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS));
            String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME));
            String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD));
            String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES));
            LoginDetails lpDetails = new LoginDetails();
            lpDetails.setsName(sName);
            lpDetails.setwUrl(wUrl);
            lpDetails.setuName(uName);
            lpDetails.setpWord(pWord);
            lpDetails.setlNotes(lNotes);
            loginArrayList.add(lpDetails);
            webNameList.add(sName);
        }
        sqliteDatabase.close();
        return webNameList;
    }

    @Override
    protected void onResume() {
        super.onResume();
        loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList());
        loginList.setAdapter(loginListAdapter);  
    }

@Override
    public void onItemClick(AdapterView<?> arg0 , View arg1, int arg2, long arg3) {
        Toast.makeText(getApplicationContext(), "Selected ID :" + arg2, Toast.LENGTH_SHORT).show();
        Intent updateDeleteLoginInfo = new Intent (this, UpdateDeleteLoginList.class);
        LoginDetails clickedObject = loginArrayList.get(arg2);
        Bundle loginBundle = new Bundle();
        loginBundle.putString("clickedWebSite",clickedObject.getsName());
        loginBundle.putString("clickedWebAddress",clickedObject.getwUrl());
        loginBundle.putString("clickedUserName",clickedObject.getuName());
        loginBundle.putString("clickedPassWord",clickedObject.getpWord());
        loginBundle.putString("clickedNotes",clickedObject.getlNotes());
        updateDeleteLoginInfo.putExtras(loginBundle);
        startActivityForResult(updateDeleteLoginInfo, 0);   
    }
}

这正是Loader的优点。我建议您创建一个SimpleCursorAdapter来将DB绑定到UI(在本例中为ListView),创建一个与DB接口的ContentProvider,以及创建一个用于监视DB的更改并在必要时更新UI的CursorLoaderLoader将处理所有DB更改,并通过简单地更新适配器来更新ListView。它看起来有很多前期工作,但一旦配置好,它的功能就非常强大,并将贯穿整个Android生命周期。

这些教程应该很有帮助:

  • https://developer.android.com/training/load-data-background/index.html
  • http://www.vogella.com/articles/AndroidSQLite/article.html#background_loader
  • https://github.com/browep/AndroidCursorLoaderTutorial

编辑

private ArrayList<LoginDetails> loginArrayList = new ArrayList<LoginDetails>();;
@Override 
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.login_listview);
    loginList = (ListView)
    findViewById(R.id.loginlist);
    loginList.setOnItemClickListener(this);
    webLogin = (Button)
    findViewById(R.id.button3);
    webLogin.setOnClickListener(this);

    loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,loginArrayList );
    loginList.setAdapter(loginListAdapter);
    populateList();
}
@Override
public void onClick (View v) {
    Intent webLoginIntent = new Intent (this, LoginPlusActivity.class);
    startActivity(webLoginIntent);
}
public void populateList () {
    loginListAdapter.clear();
    loginArrayList.clear();
    dataStore openHelperClass = new dataStore (this);
    SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase();
    Cursor cursor = sqliteDatabase.query(dataStore.TABLE_NAME_INFOTABLE, null, null, null, null, null, dataStore.COLUMN_NAME_SITE, null);
    startManagingCursor(cursor);
    while (cursor.moveToNext()) {
        String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE));
        String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS));
        String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME));
        String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD));
        String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES));
        LoginDetails lpDetails = new LoginDetails();
        lpDetails.setsName(sName);
        lpDetails.setwUrl(wUrl);
        lpDetails.setuName(uName);
        lpDetails.setpWord(pWord);
        lpDetails.setlNotes(lNotes);
        loginArrayList.add(lpDetails);
        webNameList.add(sName);
    }
    loginListAdapter.notifyDatasetChanged();
    sqliteDatabase.close();
}

你正在失去对你的列表视图的引用,这就是为什么你的列表没有更新。。。

在代码中进行此修改。1.在ArrayList被声明(全局)时初始化它。

ArrayList loginArrayList = new ArrayList<LoginDetails>();
  1. 直接将分配列表设置为适配器(onCreate)

    loginListAdapter=新的ArrayAdapter(this,android.R.layout.simple_list_item_1,loginArrayList);

  2. 在CCD_ 18中调用CCD_。

  3. 在您的populateList()中,不要将数据添加到新列表中,而是添加到与适配器关联的现有列表中,即loginArrayList

如果您的列表是全新的,请在向loginArrayList添加数据之前调用populateList()中的adapter.clear()loginArrayList.clear()。将数据添加到loginArrayList后,调用adapter.notifyDataSetChanged()

这应该有效

我的建议。

  1. 不要循环加载列表。如果它是一个包含所有字符串。尝试使用SimpleCursorAdapter,将使您的应用程序更快、更短的代码
  2. 一旦您更新了数据库,那么您要做的就是查询DB以获得Cursor,并使用Adapter。CCD_ 30。这将在保持滚动位置的同时更新您的列表

如果您手动创建适配器的备份数据(在这种情况下,您使用的是ArrayAdapter,这在很多情况下是完全可以接受的),那么当数据库发生更改时,您需要重新查询数据库,重新创建数据集,更改适配器的备份数据库,并告诉列表数据集已经更改。

实现这一点的一种方法可能是广播一个意图,让您的活动知道要执行上述步骤(通过使用BroadcastReceiver捕捉该意图)。

这是我编辑每一行以及列表视图数据库的示例代码,我希望它能帮助你

首先创建一个适配器名称"ListAdapterItem.java"

     import java.util.ArrayList;
     import java.util.HashMap;
     import android.content.Context;
     import android.view.LayoutInflater;
     import android.view.View;
     import android.view.ViewGroup;
     import android.widget.BaseAdapter;
     import android.widget.RelativeLayout;
     import android.widget.TextView;
     public class ListAdapterItem extends BaseAdapter {
private ArrayList<HashMap<String, Object>> list;
private Context context;
private RelativeLayout ll;
// used to keep selected position in ListView
private int selectedPos = -1; // init value for not-selected
private TextView label,label_id;
String name,id;
public ListAdapterItem (Context context,ArrayList<HashMap<String, Object>> list) {
    this.list = list;
    this.context = context;
}
public void setSelectedPosition(int pos) {
    selectedPos = pos;
    // inform the view of this change
    notifyDataSetChanged();
}
public int getSelectedPosition() {
    return selectedPos;
}
public View getView(int position, View convertView, ViewGroup parent) {
    ll = (RelativeLayout) LayoutInflater.from(this.context).inflate(R.layout.data_list_item, null);
    // get text view
    label = (TextView) ll.findViewById(R.id.txtview_country_name);
    label_id=(TextView) ll.findViewById(R.id.txtview_id);
    id=list.get(position).get("Id").toString();
    name = list.get(position).get("Name").toString();
    label.setText(name);
    label_id.setText(id);
    return ll;
}
public int getCount() {
    return this.list.size();
}
public Object getItem(int position) {
    return position;
}
public long getItemId(int position) {
    return position;
}
}

这是我的数据列表项

                            <?xml version="1.0" encoding="utf-8"?>
            <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="fill_parent"
                android:orientation="vertical"
                android:padding="5dp">
                 <TextView
                    android:id="@+id/txtview_id"
                    android:layout_width="wrap_content"
                    android:layout_height="fill_parent"
                    android:layout_margin="8dp"
                    android:layout_marginRight="2dp"
                    android:textColor="@android:color/black"
                    android:textSize="22dp"
                    android:visibility="invisible"/>
                <TextView
                    android:id="@+id/txtview_country_name"
                    android:layout_width="wrap_content"
                    android:layout_height="fill_parent"
                    android:layout_margin="8dp"
                    android:layout_marginRight="2dp"
                    android:textColor="@android:color/black"
                    android:textSize="22dp" />

            </RelativeLayout>

和主类"main.java"

                    public class Main extends Activity implements OnClickListener {
                    String name;
                    SQLiteDatabase db;
                    Cursor cursor;
                    private ProgressDialog progressDialog;
                    public ListAdapterItem list_adapter;
                    private ArrayList<HashMap<String, Object>> lst_data;
                    private HashMap<String, Object> hm;
                    private ListView listview;
                    private String list_id;
                    private int counter_id,selectedPosition;
                    private View selectedView;
                    public void onCreate(Bundle savedInstanceState) {
                        super.onCreate(savedInstanceState);
                        setContentView(R.layout.main_layout);
                        lst_data = new ArrayList<HashMap<String, Object>>();
                        listview = (ListView) findViewById(R.id.list);
                        new FetchDB().execute();
                        }
                    private class FetchDB extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> {
                        protected void onPreExecute() {
                            progressDialog = ProgressDialog.show(Main.this,"Fetching Data", "Loading,Please wait...", true);
                        }
                        protected ArrayList<HashMap<String, Object>> doInBackground(String... lstStrings)throws IllegalArgumentException {
                            try {
                                db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
                                cursor = db.rawQuery("SELECT * FROM person WHERE Id <> ''",null);
                                if (cursor != null && cursor.getCount() > 0) {
                                    if (cursor.moveToFirst()) {
                                        do {
                                            hm = new HashMap<String, Object>();
                                            hm.put("Id",cursor.getInt(cursor.getColumnIndex("Id")));
                                            hm.put("Name", cursor.getString(cursor.getColumnIndex("Name")));
                                            lst_data.add(hm);
                                        } while (cursor.moveToNext());
                                    }// end of cursor.moveToFirst()
                                    cursor.close();
                                }
                            } catch (Exception e) {
                                e.getMessage();
                            }
                            db.close();// database close
                            return lst_data;
                        }// end of doInbackgournd
                        @Override
                        protected void onPostExecute(ArrayList<HashMap<String, Object>> result) {
                            progressDialog.dismiss();
                            list_adapter = new ListAdapterItem(Main.this,result);
                            listview.setAdapter(list_adapter);
                            listview.setOnItemClickListener(new OnItemClickListener() {
                                public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
                                    list_adapter.setSelectedPosition(arg2);
                                    selectedPosition = arg2;
                                    selectedView = arg1;
                                    list_id=((TextView) selectedView.findViewById(R.id.txtview_id)).getText().toString();
                                }
                            });
                        }
                    }// end of FetchDBTask
                        private class SaveTask extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> {
                        @Override
                        protected void onPreExecute() {
                            progressDialog = ProgressDialog.show(Main.this,"Saving Data", "Loading,Please wait...", true);
                        }
                        protected ArrayList<HashMap<String, Object>> doInBackground(String... arg0)throws IllegalArgumentException {
                            counter_id++;
                            name = editext_name.getText().toString();
                            hm = new HashMap<String, Object>();
                            hm.put("Id",counter_id);
                            hm.put("Name",name);
                            lst_data.add(hm);
                            saveDB();
                            return lst_data;
                        }// end of doInbackgournd
                        protected void onPostExecute(ArrayList<HashMap<String, Object>> result) {
                            progressDialog.dismiss();
                            list_adapter = new ListAdapterItem(Main.this,result);
                            listview.setAdapter(list_adapter);
                            listview.setOnItemClickListener(new OnItemClickListener() {
                                public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
                                    list_adapter.setSelectedPosition(arg2);
                                    selectedPosition = arg2;
                                    selectedView = arg1;
                                    list_id=((TextView) selectedView.findViewById(R.id.txtview_id)).getText().toString();
                                }
                            });
                        }
                    }// end of saveTask
                    public void saveDB(){
                        String sql;
                        db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
                        // create table if not e exist
                        db.execSQL("CREATE TABLE IF NOT EXISTS person(Name VARCHAR ,Id INT(3));");
                        sql = "SELECT * FROM person WHERE Id="+list_id; //selected or click row in list item
                        Cursor cursor = db.rawQuery(sql, null);
                        if (cursor.moveToFirst()) {
                            String sqlUpdate = "UPDATE person SET Name=? WHERE Id="+db_id;
                            db.execSQL(sqlUpdate, new Object[] {db_name});
                            cursor.close();
                            db.close();// database close
                        } else {// empty insert
                            String sqlInsert = "INSERT INTO person VALUES (?,"+null+")";
                            db.execSQL(sqlInsert, new Object[] {db_name,db_address,db_phone,db_email,db_license,db_comments,db_company,db_policy,db_phone_insurance,vehc_year,vehc_make,vehc_model,vehc_license,vehc_vinnum,vehc_color,db_position });
                            cursor.close();
                            db.close();// database close
                        }
                    }
                    //Edit by row
                    private class EditData extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> {
                        protected void onPreExecute() {
                            progressDialog = ProgressDialog.show(Main.this,"Saving Data", "Loading Please wait...", true);
                        }
                        protected ArrayList<HashMap<String, Object>> doInBackground(String... id)throws IllegalArgumentException {
                            name = editext_name.getText().toString();

                            hm = new HashMap<String, Object>();
                            hm.put("Id",counter_id);
                            hm.put("Name",name);
                            lst_data.set(selectedPosition, hm); //specific row update
                            list_id=Integer.parseInt(edit_counter);
                            saveDB();
                            return lst_data;
                        }// end of doInbackgournd
                        protected void onPostExecute(ArrayList<HashMap<String, Object>> result) {
                            progressDialog.dismiss();
                            list_adapter = new ListAdapterItem(Main.this,result);
                            listview.setAdapter(list_adapter);
                        }
                    }
                }

和main_layout.xml

            <?xml version="1.0" encoding="utf-8"?>
            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"                    
                android:orientation="vertical" >
                <ListView
                    android:id="@+id/list"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:background="@android:color/transparent"
                    android:cacheColorHint="#00000000"
                    android:dividerHeight="2dp"
                    android:paddingTop="8dp"
                    android:transcriptMode="normal" />
            </LinearLayout>

在列表视图中的每个列表行指定您的id,希望这能回答您的问题

我认为在while块之前的populate()方法中,应该调用loginListAdapter.notifyDataSetChanged()和loginListAdapter.clear();这将清除适配器并通知它新的数据列表。

区块将如下所示:

 loginListAdapter.notifyDataSetChanged();
 loginListAdapter.clear();
 while (cursor.moveToNext()) {
        String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE));
        String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS));
        String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME));
        String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD));
        String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES));
        LoginDetails lpDetails = new LoginDetails();
        lpDetails.setsName(sName);
        lpDetails.setwUrl(wUrl);
        lpDetails.setuName(uName);
        lpDetails.setpWord(pWord);
        lpDetails.setlNotes(lNotes);
        loginArrayList.add(lpDetails);
        webNameList.add(sName);
    }

我只是编辑了,因为你调用通知和清除的顺序不正确。清除必须发生在通知之后,这正是我从经验中得到的,除非适配器不会重新绘制列表。

试试这个代码

在公共区域添加变量:List<String> arrayList = new ArrayList<String>();

并在onCreate()中添加以下内容:

    arrayList = populateList();

//然后在适配器中添加变量,如

loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayList );

在onResume()中,此代码:

@Override
protected void onResume() {
    super.onResume();
    loginArrayList.clear();
    arrayList.clear();
    arrayList = populateList();
    loginListAdapter.notifyDataSetChanged()
}

如果您解决了问题,请告诉我们。

相关内容

  • 没有找到相关文章

最新更新