ListView из SQLite с кнопками - PullRequest
       10

ListView из SQLite с кнопками

0 голосов
/ 13 сентября 2018

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

 public void loadStudentstoAttend()
    {

        ArrayList<HashMap<String, String>> userList = GetAllStudentstolist();

        ListAdapter adapter = new SimpleAdapter(this, userList, R.layout.row_add_attend,new String[]{"name","roll","semester"}, new int[]{R.id.tv_attend_name, R.id.tv_attend_roll, R.id.tv_attend_sem});
        lv.setAdapter(adapter);
    }
    //GEt All Students to listview to add attendance
    public ArrayList<HashMap<String, String>> GetAllStudentstolist(){
        ArrayList<HashMap<String, String>> userList = new ArrayList<>();
        //String sem="'First'";
        try{
            SQLiteDatabase db = MyDB.getInstance(this).getReadableDatabase();


            String query = "SELECT * FROM Students WHERE semester='"+etSem.getText()+"'";
            Cursor cursor = db.rawQuery(query,null);
            if(cursor.moveToFirst()) {
                while (cursor.moveToNext()) {
                    HashMap<String, String> user = new HashMap<>();
                    user.put("name", cursor.getString(0));
                    user.put("roll", cursor.getString(1));
                    user.put("semester", cursor.getString(2));

                    userList.add(user);
                }
            }

        }
        catch (Exception e){
            Toast.makeText(this, "Error ", Toast.LENGTH_SHORT).show();
        }
        return  userList;
    }

Это пользовательский макет для ListView

1 Ответ

0 голосов
/ 14 сентября 2018

Вот один из способов, который использует SimpleCursorAdapter и XML onClick (некоторые не советуют использовать это, но его довольно просто использовать).

Поскольку используется адаптер Cursor, для этого требуется, чтобы в таблице был столбец с именем _id

Так что в любом случае решение может быть: -

MyDB.java (Помощник по базе данных): -

public class MyDB extends SQLiteOpenHelper {

    public static final String DBNAME = "students";
    public static final int DBVERSION = 1;
    public static final String TBNAME = "students";
    public static final String COl_ID = BaseColumns._ID;
    public static final String COl_NAME = "name";
    public static final String COl_ROLL = "roll";
    public static final String COL_SEMESTER = "semester";

    SQLiteDatabase mDB;

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

    @Override
    public void onCreate(SQLiteDatabase db) {

        String crtsql = "CREATE TABLE IF NOT EXISTS " + TBNAME + "(" +
                COl_ID + " INTEGER PRIMARY KEY," +
                COl_NAME + " TEXT," +
                COl_ROLL + " TEXT," +
                COL_SEMESTER + " TEXT" +
                ")";
        db.execSQL(crtsql);

    }

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

    }

    public long addStudent(String name, String roll, String semster) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COl_NAME,name);
        cv.put(COl_ROLL,roll);
        cv.put(COL_SEMESTER,semster);
        return db.insert(TBNAME,null,cv);
    }

    public Cursor getStudentList() {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.query(TBNAME,null,null,null,null,null,null);
    }

    public int changeStudent(String id, String newname) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COl_NAME,newname);
        String whereclause = COl_ID + "=?";
        String[] whereargs = new String[]{id};
        return db.update(TBNAME,cv,whereclause,whereargs);
    }
}
  • Примечание COL_ID (вам это не нужно, поскольку вы можете получить базовый rowid , но это, скорее всего, будет более болезненно, _id - это все, что вам нужно, чтобы иметь возможность определить строку).
  • Метод addStudent позволяет добавить учащегося.
  • Метод getStudentList возвращает всех студентов в виде курсора (весь столбец)
  • Метод changeStudent изменит имя ученика (для демонстрации)

Макет (очевидно, адаптируемый по мере необходимости) row_add_attend.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/hidden_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"/>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/roll"
            android:layout_width="0dp"
            android:layout_weight="5"
            android:layout_height="match_parent" />
        <Button
            android:id="@+id/Present"
            android:layout_width="0dp"
            android:layout_weight="2"
            android:layout_height="match_parent"
            android:text="PRESENT"
            android:onClick="clickedPresent"/>
        <Button
            android:id="@+id/Absent"
            android:layout_width="0dp"
            android:layout_weight="2"
            android:layout_height="match_parent"
            android:text="ABSENT"
            android:onClick="clickedAbsent"/>
    </LinearLayout>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/name"
            android:layout_width="0dp"
            android:layout_weight="7"
            android:layout_height="match_parent" />
        <Button
            android:id="@+id/leave"
            android:layout_width="0dp"
            android:layout_weight="2"
            android:layout_height="match_parent"
            android:text="LEAVE"/>
    </LinearLayout>
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/semester"
            android:layout_width="0dp"
            android:layout_weight="5"
            android:layout_height="match_parent" />
    </LinearLayout>
</LinearLayout>
  • Примечание android:onClick="clickedPresent" для кнопки PRESENT и android:onClick="clickedAbsent" для кнопки ABSENT.

Активность (в данном случае MainActivity): -

public class MainActivity extends AppCompatActivity {

    ListView mLV;
    MyDB mDB;
    SimpleCursorAdapter mSCA;
    Cursor mStudentList;
    Button mPresent,mAbsent,mLeave;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mDB = new MyDB(this);
        addStudents();
        mLV = this.findViewById(R.id.listview);
        handleAdapter();
        mLV.setAdapter(mSCA);
    }

    private void handleAdapter() {
        mStudentList = mDB.getStudentList();
        if (mSCA == null) {
            String[] fromcolumns = new String[]{MyDB.COl_NAME,MyDB.COl_ROLL,MyDB.COL_SEMESTER,MyDB.COl_ID};
            int[] toviews = new int[]{R.id.name,R.id.roll,R.id.semester,R.id.hidden_id};
            mSCA = new SimpleCursorAdapter(this,R.layout.row_add_attend,mStudentList,fromcolumns,toviews,0);
        } else {
            mSCA.swapCursor(mStudentList);
        }
    }

    private void addStudents() {
        if (DatabaseUtils.queryNumEntries(mDB.getWritableDatabase(),MyDB.TBNAME) == 0) {
            mDB.addStudent("John","12345","First");
            mDB.addStudent("James","543","Second");
        }
    }

    public void clickedPresent(View view) {
        LinearLayout lv = (LinearLayout) view.getParent().getParent();
        String id = ((TextView) lv.findViewById(R.id.hidden_id)).getText().toString();
        String name = ((TextView) lv.findViewById(R.id.name)).getText().toString();
        String roll = ((TextView) lv.findViewById(R.id.roll)).getText().toString();
        String semester = ((TextView) lv.findViewById(R.id.semester)).getText().toString();
        Toast.makeText(this,
                "PRESENT CLICKED ID is " + id +
                        " Name is " +  name +
                        " Roll is " + roll +
                        " Semester is " + semester
                ,Toast.LENGTH_SHORT).show();
    }

    public void clickedAbsent(View view) {
        LinearLayout lv = (LinearLayout) view.getParent().getParent();
        String id = ((TextView) lv.findViewById(R.id.hidden_id)).getText().toString();
        String newname = ((TextView) lv.findViewById(R.id.name)).getText().toString() + " is Absent";
        mDB.changeStudent(id,newname);
        handleAdapter();
    }

        // Should close Cursor when done with it
        @Override
        protected void onDestroy() {
            super.onDestroy();
            mStudentList.close();
        }
}
  • Обратите внимание , что имена методов (clickedPresent и clickedAbsent) ДОЛЖНЫ совпадать с тем, что закодировано в макете. Подпись также должна принимать вид.

Выполнение вышеуказанного и нажатие кнопки «НАСТОЯЩЕЕ» приводит к тому, что тост отображает соответствующую информацию. Нажатие на кнопку «ОТСУТСТВУЕТ» изменяет имя соответствующего учащегося, чтобы добавить «отсутствует» в базу данных, а также обновить вид списка, чтобы показать новые данные.

Конечно, вы можете использовать onClick в XML со связанным методом в Activity с SimpleAdapter. Обратите внимание , что LinearLayout lv = (LinearLayout) view.getParent().getParent(); должен отражать иерархию и типы / контейнеры, используемые в вашем макете.

Дополнительно

комментарий: -

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

Это довольно просто, так как все, что вам нужно сделать, это установить цвет фона для представления, которое передается методу onCLick.

Однако, если вы просто сделаете это, это приведет к постоянному изменению этой кнопки, и, таким образом, если вы нажмете все 3 кнопки (отметьте только 2 «присутствующие» и «отсутствующие», используемые в данном примере), то все три будут изменены.

Таким образом, чтобы преодолеть это, вы можете установить фон других кнопок на исходный фон (оригинал не слишком легко найти, поэтому, вероятно, проще установить фон с известным цветом в макете (не сделано в примере ниже, но предполагается, что FFAAAAAA)).

Однако основная логика может быть проблематичной. Что вы хотите сделать, это вопрос, который вы должны задать себе. Если вы устанавливаете состояние в БД, то в тот момент, когда вы нажимаете кнопку, возможно, все в порядке, так как последняя нажатая кнопка будет указывать состояние. Однако, если вы захотите, например, обработать кнопку в соответствии с ее состоянием позже, у вас возникнут проблемы с определением состояния кнопки, поскольку они не предназначены для этой цели.

В любом случае, при условии, что динамическая / реальная обработка в реальном времени разрешена только с одним разрешенным состоянием (выбранная кнопка), достаточно просто изменить методы clickedPresent и clickedAbsent в соответствии с: -

public void clickedPresent(View view) {
    LinearLayout lv = (LinearLayout) view.getParent().getParent();
    String id = ((TextView) lv.findViewById(R.id.hidden_id)).getText().toString();
    String name = ((TextView) lv.findViewById(R.id.name)).getText().toString();
    String roll = ((TextView) lv.findViewById(R.id.roll)).getText().toString();
    String semester = ((TextView) lv.findViewById(R.id.semester)).getText().toString();
    Toast.makeText(this,
            "PRESENT CLICKED ID is " + id +
                    " Name is " +  name +
                    " Roll is " + roll +
                    " Semester is " + semester
            ,Toast.LENGTH_SHORT).show();
    lv.findViewById(R.id.Absent).setBackgroundColor(0xFFAAAAAA); //<<<<<<<<<< ADDED TO set other button (repeat this leave button)
    view.setBackgroundColor(0xFF0000FF); //<<<<<<<<<< ADDED to set selected button colour
}

public void clickedAbsent(View view) {
    LinearLayout lv = (LinearLayout) view.getParent().getParent();
    String id = ((TextView) lv.findViewById(R.id.hidden_id)).getText().toString();
    String newname = ((TextView) lv.findViewById(R.id.name)).getText().toString() + " is Absent";
    lv.findViewById(R.id.Present).setBackgroundColor(0xFFAAAAAA);
    view.setBackgroundColor(0xFF0000FF);
    mDB.changeStudent(id,newname);
    handleAdapter();
}

Вот пример, где первая имеет «Присутствует» как выбранный в данный момент (последний нажал), а вторая имеет «Отсутствует» (обратите внимание, что другая кнопка немного темнее серого, чем нетронутая кнопка «Оставить», показывая, как FFAAAAAA был применен в качестве фона цвет): -

enter image description here

...