Как исправить «Одни и те же данные становятся доступными для всех элементов списка просмотра» - PullRequest
0 голосов
/ 25 декабря 2018

При щелчке элемента Listview данные, относящиеся к этому элементу Listview, должны быть доступны для него из базы данных SQLite, но становятся доступными данные всех элементов Listview.Как мне исправить это?

Main2Activity:

position = intent.getIntExtra("position",0);

 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String text = listView.getItemAtPosition(position).toString();
            Toast.makeText(Main2Activity.this, ""+text, Toast.LENGTH_SHORT).show();


        }
    });

  add_data.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String place = editText.getText().toString();
            if(!place.equals("")&& databaseHelper1.insertData1(place)){
                editText.setText("");
                listItem.clear();
                viewData1();
            } else
            {
                Toast.makeText(Main2Activity.this, "Data not added", Toast.LENGTH_SHORT).show();
            }

        }
    });
}

private void viewData1() {

    Cursor cursor = databaseHelper1.viewData1(position);

    if(cursor.getCount()==0){

        Toast.makeText(this, "No data to show", Toast.LENGTH_SHORT).show();
    }else
    {
        while(cursor.moveToNext()){

            listItem.add(cursor.getString(0));
        }
        listView.setAdapter(adapter);

    }

}

DatabaseHelper: Это мои таблицы:

private static final String CREATE_TABLE = "CREATE TABLE " +      DB_TABLE + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + NAME
        + " TEXT " + ")";
private static final String CREATE_TABLE1 = "CREATE TABLE " + DB_TABLE1 + " (" + ID1 + " INTEGER PRIMARY KEY AUTOINCREMENT, "+
        PLACE + " TEXT " + " , " + ID + " INTEGER REFERENCES " + DB_TABLE + ")";

Моя функция insertData:

public boolean insertData1(String place) {

    SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
    ContentValues contentValues1 =  new ContentValues();
    contentValues1.put(PLACE,place);


    long result1 = sqLiteDatabase.insert(DB_TABLE1,null,contentValues1);
    return result1 != -1;
}

Моя функция viewData:

public Cursor viewData1(int position)
{
    SQLiteDatabase sqLiteDatabase = this.getReadableDatabase();
    Cursor cursor = null;

    if (position==0) {
    String query = "Select " + DB_TABLE1 + "." + PLACE + " from " + DB_TABLE1;
        cursor= sqLiteDatabase.rawQuery(query, null);

}
    if (position==1) {
        String query = "Select " + DB_TABLE1 + "." + PLACE + " from " + DB_TABLE1;
        cursor= sqLiteDatabase.rawQuery(query, null);

    }
    return cursor;
}

С помощью этого кода я получаю все данные из базы данных, доступные для позиции Listitem, независимо от того, является ли она позицией 0 или 1.Фактическим выводом должно быть то, что все данные соответствуют элементу, по которому щелкнули.

1 Ответ

0 голосов
/ 25 декабря 2018

Для доступа к элементу из ListView вы устанавливаете onItemClickListener ListView, и вызывается метод onItemClick .

onItemClick передается 4 параметра: -

  1. AdapterView элемента, по которому был выполнен щелчок,
  2. просмотра с использованием AdapterView, который былщелкнул,
  3. положение в списке выбранного элемента в качестве смещения (т. е. 0 - первый элемент, 1 - второй и т. д.) и
  4. , если адаптер является адаптером курсора.идентификатор строки, по которой щелкнули (), если это не Adpater курсора, тогда это значение будет таким же, как позиция, за исключением того, что это long, а не int.

Как выне используя CursorAdapter, а List / ArrayListAdapter, тогда можно использовать позицию с помощью метода getItemAtPositition Адаптера для извлечения строки выбранного элемента.Вы можете, если эта строка уникальна, использовать ее для получения строки, связанной с этим элементом.Если он не уникален, то нет реального способа точно определить, какая строка связана с элементом.

Это одна из проблем, связанных с использованием / извлечением отображаемой строки, она не идеальна и дополнительноэто требует дополнительной работы.

Вы можете, извлекая строку из Курсора, также извлечь id и поместить его в массив длинных позиций, а затем получить доступ к этому массиву длинных в соответствии с положением.С помощью id вы можете запросить таблицу для получения этой строки из базы данных.

У вас может быть класс, который определяет объект, представляющий строку, включая id строки и затем имеют ArrayList, и в этом случае метод getItemAtPosition может вернуть объект, включающий id (и, возможно, все значения, исключающие необходимость доступа к базе данных).

Возможно, самый простой способ - использовать адаптер курсора, в этом случае курсор будет доступен (и правильно расположен), а 4-й параметр будет id выбранного элемента.Однако для этого необходимо, чтобы для столбца id использовалось указанное имя столбца, то есть столбец должен иметь имя _id .Этого можно достичь, переименовав столбец ID1 или поочередно указав ID1 и псевдоним, используя ключевое слово AS .

Рабочий пример

Кажется, в вашем коде есть несколько проблем и довольно много пропусков.Таким образом, вот рабочий пример, основанный на вашем коде.

В этом примере будет отображаться ListView с 5 строками, причем каждая строка состоит из данных обеих таблиц в соответствии с отношением.При щелчке по элементу будут отображаться значения, лежащие в основе.

DatabaseHelper.java: -

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;
    public static final String DB_TABLE = "dbtable";
    public static final String DB_TABLE1 = "dbtable1";
    public static final String COL_TABLE_ID = BaseColumns._ID;
    public static final String COL_TABLE_NAME = "name";
    public static final String COL_TABLE1_ID1 = BaseColumns._ID;
    public static final String COL_TABLE1_ID1_ALTERNATIVE = DB_TABLE1 + "_" + COL_TABLE1_ID1; //alternative column name so no ambiguity
    public static final String COl_TABLE1_PLACE = "place";
    public static final String COL_TABLE1_ID = "id";

    SQLiteDatabase mDB;



    //Note AUTOINCREMENT removed not needed/inefficient

    private static final String CREATE_TABLE = "CREATE TABLE " +      DB_TABLE + " (" +
            COL_TABLE_ID + " INTEGER PRIMARY KEY, " +
            COL_TABLE_NAME + " TEXT " +
            ")";
    private static final String CREATE_TABLE1 = "CREATE TABLE " + DB_TABLE1 + " (" +
            COL_TABLE1_ID1 + " INTEGER PRIMARY KEY, " + //(limits 1 to 1 relationship, due to needing to be unique)
            COl_TABLE1_PLACE + " TEXT " + " , " +
            COL_TABLE1_ID + " INTEGER REFERENCES " + DB_TABLE + "(" +
            COL_TABLE_ID +
            ")" +
            ")";

    public DatabaseHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    // Foreign kjey support need to be turned on
    @Override
    public void onConfigure(SQLiteDatabase db) {
        super.onConfigure(db);
        db.setForeignKeyConstraintsEnabled(true);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE);
        db.execSQL(CREATE_TABLE1);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    public long insertTableRow(String name) {
        ContentValues cv = new ContentValues();
        cv.put(COL_TABLE_NAME,name);
        return mDB.insert(DB_TABLE,null,cv);
    }

    public long insertTable1Row(long table_reference, String place) {
        ContentValues cv = new ContentValues();
        cv.put(COL_TABLE1_ID,table_reference);
        cv.put(COl_TABLE1_PLACE,place);
        return mDB.insert(DB_TABLE1,null,cv);
    }

    public Cursor getAllFromBothTables() {
        String table = DB_TABLE + " JOIN " + DB_TABLE1 + " ON " + DB_TABLE + "." + COL_TABLE_ID + " = " + DB_TABLE1 + "." + COL_TABLE1_ID;
        String[] columns = new String[]{
                DB_TABLE + "." + COL_TABLE_ID,
                DB_TABLE + "." + COL_TABLE_NAME,
                DB_TABLE1 + "." + COL_TABLE1_ID1 + " AS " + COL_TABLE1_ID1_ALTERNATIVE,
                DB_TABLE1 + "." + COl_TABLE1_PLACE,
                DB_TABLE1 + "." + COL_TABLE1_ID
        };
        return mDB.query(table,columns,null,null,null,null,null);
    }
}

Main2Activity.java

public class Main2Activity extends AppCompatActivity {

    DatabaseHelper DatabaseHelper1;
    ListView listview;
    SimpleCursorAdapter mSCA;
    Cursor mCsr;
    Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        setContentView(R.layout.activity_main2);
        listview = this.findViewById(R.id.mylistview);
        DatabaseHelper1 = new DatabaseHelper(this);
        addSomeTestData();
        handleListView();
    }

    private void addSomeTestData() {
        if (DatabaseUtils.queryNumEntries(DatabaseHelper1.getWritableDatabase(),DatabaseHelper.DB_TABLE) > 0) return;
        DatabaseHelper1.insertTableRow("Fred");
        DatabaseHelper1.insertTableRow("Mary");
        DatabaseHelper1.insertTableRow("Sue");
        DatabaseHelper1.insertTable1Row(1,"London");
        DatabaseHelper1.insertTable1Row(2,"New York");
        DatabaseHelper1.insertTable1Row(3,"Sydney");
        DatabaseHelper1.insertTable1Row(1,"Paris");
        DatabaseHelper1.insertTable1Row(1,"Toronto");
    }

    private void handleListView() {
        mCsr = DatabaseHelper1.getAllFromBothTables();
        DatabaseUtils.dumpCursor(mCsr);
        if (mSCA == null) {
            mSCA = new SimpleCursorAdapter(
                    this,
                    android.R.layout.simple_list_item_2,mCsr,
                    new String[]{
                            DatabaseHelper.COL_TABLE_NAME,
                            DatabaseHelper.COl_TABLE1_PLACE
                    },
                    new int[]{android.R.id.text1,android.R.id.text2},
                    0
            );
            listview.setAdapter(mSCA);
            listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    Toast.makeText(
                            mContext,
                            "You clicked on name = " + mCsr.getString(mCsr.getColumnIndex(DatabaseHelper.COL_TABLE_NAME)) +
                                    " place = " + mCsr.getString(mCsr.getColumnIndex(DatabaseHelper.COl_TABLE1_PLACE)) +
                                    " id of TABLE is " + String.valueOf(l) +
                                    " id of TABLE from cursor is " + String.valueOf(mCsr.getLong(mCsr.getColumnIndex(DatabaseHelper.COL_TABLE_ID))) +
                                    " id of TABLE1 is " + String.valueOf(mCsr.getLong(mCsr.getColumnIndex(DatabaseHelper.COL_TABLE1_ID1_ALTERNATIVE))),
                            Toast.LENGTH_SHORT).show();
                }
            });
        } else {
            mSCA.swapCursor(mCsr);
        }
    }
}

Когда вышеописанное выполняется, оно выглядит следующим образом:-

enter image description here

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