简体   繁体   English

Android 工作室列表视图更改项目

[英]Android studio listview change item

can anyone help me with changing the name of the item in listview?谁能帮我更改列表视图中的项目名称? I don't have an idea how to do it.我不知道该怎么做。 I am using SQLite database and this is my update name:我正在使用 SQLite 数据库,这是我的更新名称:

public void doneName(String finishedName,int id, String oldName)
    {

        SQLiteDatabase db = this.getWritableDatabase();
        String query = "UPDATE " + TABLE_NAME + " SET " + COL2 + " = '" + finishedName + "' WHERE " + COL1 +
                " = '" + id + "'" + " AND " + COL2 + " = '" + oldName + "'";
        db.execSQL(query );
    }

after that in my activity I have set onItemClickListener where it should change name but it does not, it only shows toast:之后在我的活动中,我设置了 onItemClickListener 应该更改名称但它没有,它只显示吐司:

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String name = parent.getItemAtPosition(position).toString();
                Cursor cursor =th.getItemID(name);
                int itemID = -1;
                while(cursor.moveToNext())
                {
                    itemID = cursor.getInt(0);
                }
                if(itemID>-1) {
                    String item = "Done";
                    th.doneName(item, selectedID, selectedName);
                    Toast.makeText(HomePageActivity.this, "You have accomplished this task!", Toast.LENGTH_SHORT).show();
                }}
        });

I'm afraid you don't update the instance of the relevant adapter item.恐怕你没有更新相关适配器项的实例。 If you have a list of Strings that attached with this ListView Adapter you should initialize the String item at the relevant position with the name you want to show.如果您有与此 ListView 适配器连接的字符串列表,您应该使用您要显示的名称初始化相关 position 中的字符串项。 Then call Adapter.notifyDataSetChanged to refresh all UI elements in the ListView with the updated list.然后调用 Adapter.notifyDataSetChanged 用更新后的列表刷新 ListView 中的所有 UI 元素。

It seems, that you never update the String instance in your Adapter list看来,您永远不会更新适配器列表中的 String 实例

You issue is two-fold.你的问题是双重的。

  1. First you are not extracting the updated data from the database (you could assume that the underlying data has been update bit that is risky).首先,您没有从数据库中提取更新的数据(您可以假设基础数据已被更新,这是有风险的)。
  2. You are not refreshing the Listview with the changes, so it shows the data it knows about.您没有使用更改刷新 Listview,因此它显示了它知道的数据。

I'd suggest utilising a CursorAdapter which can simplify matters as Cursor Adapters are designed for use with Cursors and they especially make all data readily available via the adpater as the Cursor is typically positioned at the appropriate row (eg when using onItemClick and onItemLongClick)我建议使用CursorAdapter可以简化问题,因为 Cursor 适配器设计用于光标,它们特别使所有数据都可以通过适配器轻松获得,因为 Cursor 通常位于适当的行(例如,当使用 onItemClick 和 onItemLongClick 时)

The following is an example based upon your code that utilises the SimpleCursorAdapter changing the database and the listview when an item in the list is clicked (to demostrate clicking the same row instead of changing the test to Done it reverses the text so it will will flip for each click).以下是一个基于您的代码的示例,该代码利用SimpleCursorAdapter在单击列表中的项目时更改数据库和列表视图(演示单击同一行而不是将测试更改为 Done 它会反转文本,因此它将翻转每次点击)。

However, to use a Cursor Adapoter you MUST have a column named _id and that column should be a unique integer (should really be a long rather than int) and typically it would be an alias of the rowid (ie defined using _id INTEGER PRIMARY KEY (with or without AUTOINCREMENT, best without)). However, to use a Cursor Adapoter you MUST have a column named _id and that column should be a unique integer (should really be a long rather than int) and typically it would be an alias of the rowid (ie defined using _id INTEGER PRIMARY KEY (有或没有自动增量,最好没有))。 As such there is a constant BaseColumns._ID that contains the value _id .因此,有一个常量 BaseColumns._ID 包含值_id

First the DatabaseHelper (subclass of SQLiteOpenHelper) in this case DatabaseHelper.java :-首先是DatabaseHelper (SQLiteOpenHelper 的子类)在这种情况下DatabaseHelper.java :-

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final  int DBVERSION = 1;

    public static final String TABLE_NAME = "mytable";
    /*<<<<<<<<<< id column must be _id (BaseColumns._ID) for Cursor Adapters >>>>>>>>>*/
    public static final String COLID = BaseColumns._ID;
    public static final String COL1 = "mycol1";
    public static final String COL2 = "mycol2";

    public DatabaseHelper(@Nullable Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
                COLID + " INTEGER PRIMARY KEY, " +
                COL1 + " TEXT, " +
                COL2 + " TEXT " +
                ")"
        );
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long insert(String col1, String col2) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COL1,col1);
        cv.put(COL2,col2);
        return db.insert(TABLE_NAME,null,cv);
    }

    public int doneName(String finishedName,int id, String oldName) {

        /*
            Alternative using the update convenience method
            Based upon :-
            String query = "UPDATE " + TABLE_NAME + " SET " + COL2 + " = '" + finishedName + "' WHERE " + COL1 +
                " = '" + id + "'" + " AND " + COL2 + " = '" + oldName + "'";

                writes the SQL for you.
                protects against SQL Injection
                returns the number of rows updated
         */
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COL2,finishedName);
        return db.update(TABLE_NAME,cv,COLID + "=? AND " + COL2 + "=?",new String[]{String.valueOf(id),oldName});
    }

    public Cursor getAll() {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.query(TABLE_NAME,null,null,null,null,null,null);
    }
}
  • Three custom methods insert (inserts a row), getAll (returns a Cursor with all the rows) and your doneName method (rewritten to take advantage the the update convenience method).三个自定义方法insert (插入一行)、 getAll (返回包含所有行的 Cursor)和您的doneName方法(重写以利用方便的更新方法)。

  • You may notice the absence of any methods to convert extracted data into a List/ArrayList/Array of objects.您可能会注意到没有任何方法可以将提取的数据转换为 List/ArrayList/Array 对象。 This is because there is no need when using a Cursor adapter.这是因为在使用 Cursor 适配器时不需要。

The activity MainActivity.java活动MainActivity.java

public class MainActivity extends AppCompatActivity {

    ListView mListView;
    DatabaseHelper th;
    Cursor csr;
    SimpleCursorAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = this.findViewById(R.id.listview);
        th = new DatabaseHelper(this);
        addSomeTestData();
        manageAdapter();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        csr.close(); //<<<<<<<<<< Should always close Cursors when done with them
    }

    private void manageAdapter() {
        /* This handles but the initialisation and the refreshing of the Listview */
        /* First time it is called it initialises the Adapter and Listview */
        /* On subsequent calls it refreshes the ListView */
        csr = th.getAll();
        if (adapter == null) {
            adapter = new SimpleCursorAdapter(
                    this,
                    android.R.layout.simple_expandable_list_item_2,csr,
                    new String[]{
                            DatabaseHelper.COL1,
                            DatabaseHelper.COL2
                    },
                    new int[]{
                            android.R.id.text1,
                            android.R.id.text2},
                    0
            );
            mListView.setAdapter(adapter);
            mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    if (th.doneName(
                            /* reverses string to test multiple updates of the same row */
                            new StringBuilder(csr.getString(csr.getColumnIndex(DatabaseHelper.COL2))).reverse().toString()
                            /* "Done" */,
                            (int )id /* NOTE ID IS PASSED to onItemClick FOR CURSOR ADAPTER */,
                            csr.getString(csr.getColumnIndex(DatabaseHelper.COL2)) /* NOTE Oldname isn't required as ID will identify the row */
                    ) > 0) {
                        manageAdapter(); //<<<<<<<<< after updating refresh the Cursor and the ListView
                        Toast.makeText(view.getContext(),"Updated OK.",Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(view.getContext(),"Not Updated!!!",Toast.LENGTH_SHORT).show();
                    }
                }
            });
        } else {
            adapter.swapCursor(csr);
        }
    }

    private void addSomeTestData() {
        //Add some data but only if none exists
        if (DatabaseUtils.queryNumEntries(th.getWritableDatabase(),DatabaseHelper.TABLE_NAME) > 0) return;
        th.insert("TEST1 COL1","TEST1 COL2");
        th.insert("TEST2 COL1","TEST2 COL2");
        th.insert("TEST3 COL1","TEST3 COL2");
        th.insert("TEST4 COL1","TEST4 COL2");
        th.insert("TEST5 COL1","TEST5 COL2");
    }
}
  • Note that you can use your own layouts with SimpleCursorAdapter (4th (String[]) and 5th (int[]) are used to specify the column that the data comes from and the id of the respective view into which the data goes to )请注意,您可以将自己的布局与 SimpleCursorAdapter 一起使用(第 4 个(String[])和第 5 个(int[])用于指定数据来自的列以及数据进入相应视图的 id)

Result:-结果:-

When initially run you get:-最初运行时,您会得到:-

在此处输入图像描述

Clicking a row and you get:-单击一行,您将获得:-

在此处输入图像描述

If you then click all rows you get:-如果然后单击您获得的所有行:-

在此处输入图像描述

And so on.等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM