Элемент списка просмотра студии Android изменить - PullRequest
0 голосов
/ 05 ноября 2019

Может ли кто-нибудь помочь мне с изменением названия элемента в списке? Я понятия не имею, как это сделать. Я использую базу данных 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 );
    }

. После этого в своей деятельности я установил 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();
                }}
        });

Ответы [ 2 ]

0 голосов
/ 05 ноября 2019

Вы выдаете в два раза.

  1. Сначала вы не извлекаете обновленные данные из базы данных (можно предположить, что базовые данные были битом обновления, который является рискованным).
  2. Вы не обновляете Listview с помощьюизменения, поэтому он показывает данные, о которых он знает.

Я бы предложил использовать CursorAdapter , который может упростить вопросы, поскольку адаптеры курсоров предназначены для использования с курсорами, и они особенносделать все данные легкодоступными через adpater, поскольку курсор обычно располагается в соответствующей строке (например, при использовании onItemClick и onItemLongClick)

Ниже приведен пример, основанный на вашем коде, который использует SimpleCursorAdapter изменение базы данных и списка при щелчке по элементу в списке (для деморации щелчка по той же строке вместо изменения теста на «Завершено» текст переворачивается, поэтому при каждом щелчке он будет переворачиваться).

Однако, чтобы использовать Cursor Adapoter, вы ДОЛЖНЫ иметь столбец с именем _id , и этот столбец должен быть уникальным целым числом (в действительности это должно быть long, а не int), и обычно это будет псевдоним rowid (то есть определяется с помощью _id INTEGER PRIMARY KEY (с AUTOINCREMENT или без него, лучше всего без)). Таким образом, существует постоянный BaseColumns._ID, который содержит значение _id .

Сначала 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);
    }
}
  • Три пользовательских метода insert (вставляет строку), getAll (возвращает курсор со всемистрок) и ваш метод doneName (переписан для использования удобного метода обновления).

  • Вы можете заметить отсутствие каких-либо методов для преобразования извлеченных данных вList / ArrayList / Массив объектов. Это связано с тем, что при использовании адаптера Cursor нет необходимости.

Активность 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");
    }
}
  • Обратите внимание, чтоВы можете использовать свои собственные макеты с SimpleCursorAdapter (4-й (String []) и 5-й (int []) используются для указания столбца, в который данные поступают из , и идентификатора соответствующего представления, в которое данныеидет до )

Результат: -

При первом запуске вы получаете: -

enter image description here

Нажав на строку, вы получите: -

enter image description here

Если щелкнуть все строки, вы получите: -

enter image description here

и т. Д.

0 голосов
/ 05 ноября 2019

Боюсь, вы не обновляете экземпляр соответствующего элемента адаптера. Если у вас есть список строк, которые прикреплены к этому адаптеру ListView, вы должны инициализировать элемент String в соответствующей позиции с именем, которое вы хотите показать. Затем вызовите Adapter.notifyDataSetChanged, чтобы обновить все элементы пользовательского интерфейса в ListView с обновленным списком.

Кажется, что вы никогда не обновляете экземпляр String в своем списке адаптеров

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...