7

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

我试过打电话,notifyDataSetChanged()startActivityForResult()我的onResume()方法,但没有奏效。我应该使用什么方法来完成ListView当前代码中的更新?

我知道SimpleCursorAdapter可以使用 a 并且我试图实现该代码但没有成功。我是新手,需要实际代码来了解需要做什么。

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);   
    }
}
4

7 回答 7

5

这正是 aLoader的伟大之处。我建议您创建一个SimpleCursorAdapter将 DB 绑定到 UI(ListView在这种情况下),一个ContentProvider与 DB 交互,以及一个CursorLoader监视 DB 的更改,并在必要时更新 UI。Loader它将处理所有数据库更改并ListView通过简单地更新您的适配器来更新您的。这似乎需要大量的工作,但一旦配置完成,功能就非常强大,并且将贯穿整个 Android 生命周期。

这些教程应该会有所帮助:

于 2013-02-12T03:36:31.260 回答
5

编辑

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. 直接给Adapter设置assign list(onCreate)

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

  2. 呼入。populateList()_onCreate()

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

如果您的列表是全新的调用adapter.clear()并且loginArrayList.clear()populateList()将数据添加到loginArrayList. 将数据添加到loginArrayList调用后adapter.notifyDataSetChanged()

这应该工作...

于 2013-02-17T17:01:42.813 回答
0

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

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

于 2013-02-12T02:06:51.700 回答
0

试试这个代码

在公共区域添加变量: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()

}

让我们知道你是否解决了它。

于 2013-02-16T18:24:16.367 回答
0

我的推荐。

  1. 不要循环加载您的列表。如果它是一个包含所有字符串的简单列表。尝试使用SimpleCursorAdapterand 将使您的应用程序更快更短的代码。
  2. 更新数据库后,您要做的就是查询数据库以Cursor获取Adapter. swapCursor(newCursor). 这将在保持滚动位置的同时更新您的列表。
于 2013-02-12T01:41:53.967 回答
0

这是我的示例代码,用于编辑每一行以及列表视图的数据库,希望对您有所帮助

首先创建我创建一个适配器名称“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;
}
}

这是我的 data_list_item

                            <?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 希望这能回答您的问题

于 2013-02-14T03:04:15.897 回答
0

我认为在 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);
    }

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

于 2013-02-14T18:41:37.500 回答