#java #android #sqlite #recyclerview
Здравствуйте. Пожалуйста, помогите разобраться со следующим.
Есть БД, данные из БД выводятся на CardViewы, которые в свою очередь генерятся в
зависимости от кол-ва записей в БД.
На этих карточках выведены данные полученные из полей БД. И на этих же карточках
присутствует кнопка для удаления записи из БД (нажатие кнопки на карточке удаляет эту
карточку и ту строку, которая послужила источником данных для этой карточки).
Суть в том, что я не понимаю, как реализовать эти кнопки...
Скриншот для наглядности:
Итак, теперь к моей реализации:
Для создания объекта Exercise я создал следующий класс:
package dailytoys.exreminder.DataClasses;
public class Exercise {
public String name;
public String muscleGroup;
public int repeats;
public int ID;
public Exercise(String name, String muscleGroup, int repeats, int ID) {
this.name = name;
this.muscleGroup = muscleGroup;
this.repeats = repeats;
this.ID = ID;
}
}
Вот DBHelper:
package dailytoys.exreminder.DataBaseEx;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper {
String name;
public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
int version) {
super(context, name, factory, version);
this.name = name;
}
public DBHelper(Context context) {
super(context, "exeDB", null, 1);
}
public int getRowsQuantity (String table) throws SQLException {
String countQuery = "SELECT * FROM " + table;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int cnt = cursor.getCount();
return cnt;
}
@Override
public void onCreate(SQLiteDatabase db) {
System.out.println("-------- CREATING TABLES ----------");
db.execSQL("CREATE TABLE EXERCISES (" +
"ID INTEGER PRIMARY KEY AUTOINCREMENT," +
"NAME TEXT," +
"REPEATS INTEGER," +
"MUSCLE_GROUP TEXT" + ");");
...
}
...
}
Собственно, вот Активити, которое отображает карточки:
package dailytoys.exreminder;
import android.app.DialogFragment;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import dailytoys.exreminder.DataBaseEx.DBHelper;
import dailytoys.exreminder.DataClasses.Exercise;
import dailytoys.exreminder.Dialogs.DialogNewExercise;
public class ExercisesActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
/* Данные для добавления на карточки */
private List exercises;
DBHelper dbHelper;
RecyclerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exercises);
...
/* Инициализация БД помощника для построения карточек */
dbHelper = new DBHelper(this);
/* Генерация карточек */
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
initializeData();
initializeAdapter();
...
}
private void initializeData () {
int rows = dbHelper.getRowsQuantity("EXERCISES");
exercises = new ArrayList<>();
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor c = db.query("EXERCISES", null, null, null, null, null, null);
int idColIndex = c.getColumnIndex("ID");
int nameColIndex = c.getColumnIndex("NAME");
int repeatsColIndex = c.getColumnIndex("REPEATS");
int muscleGroupColIndex = c.getColumnIndex("MUSCLE_GROUP");
// Цикл для чтения таблицы БД и записи данных в переменные
for (int i = 0; i < rows; i ++) {
// Дефолтные значения переменных
String name = null, muscleGroup = null;
int repeats = 0; int ID = 0;
// Получение значений из БД
if (c.moveToNext()) {
name = c.getString(nameColIndex);
muscleGroup = c.getString(muscleGroupColIndex);
repeats = c.getInt(repeatsColIndex);
ID = c.getInt(idColIndex);
// добавление в List
exercises.add(new Exercise(name, muscleGroup, repeats, ID));
} else {
// Do nothing
}
}
}
private void initializeAdapter(){
adapter = new RecyclerAdapter((ArrayList)exercises);
mRecyclerView.setAdapter(adapter);
}
public void reloadActivity() {
Intent intent = getIntent();
startActivity(intent);
}
...
}
Карточки генерятся через класс, расширяемый от RecyclerView.Adapter :
package dailytoys.exreminder;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import dailytoys.exreminder.DataClasses.Exercise;
public class RecyclerAdapter extends RecyclerView.Adapter {
private List exercises;
ExerciseViewHolder vh;
public ImageView mDeleteBtn;
public class ExerciseViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView, mTextViewName, mTextViewMusckeGroup, mTextViewRepeats;
public ExerciseViewHolder(View v) {
super(v);
mTextView = (TextView) v.findViewById(R.id.tv_recycler_item);
mTextViewName = (TextView) v.findViewById(R.id.exerciseNameEx);
mTextViewMusckeGroup = (TextView) v.findViewById(R.id.tvMuscleGroup);
mTextViewRepeats = (TextView) v.findViewById(R.id.tvRepeats);
mDeleteBtn = (ImageView) v.findViewById(R.id.deleteBtnEx);
}
}
public RecyclerAdapter(ArrayList exercises) {
this.exercises = exercises;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
@Override
public RecyclerAdapter.ExerciseViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item,
parent, false);
vh = new ExerciseViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(ExerciseViewHolder holder, int position) {
holder.mTextView.setText("ID: " + Integer.toString(exercises.get(position).ID));
holder.mTextViewName.setText(exercises.get(position).name);
holder.mTextViewMusckeGroup.setText(exercises.get(position).muscleGroup);
holder.mTextViewRepeats.setText(Integer.toString(exercises.get(position).repeats));
mDeleteBtn.setTag(exercises.get(position).ID);
}
public ImageView getImgView () {
return mDeleteBtn;
}
@Override
public int getItemCount() {
return exercises.size();
}
}
Ну, и на всякий случай, оставлю разметки карточки, и RecyclerView.
activity_exercises.xml :
content_exercises.xml :
recycler_item.xml :
Ну, и, собственно, для того, чтобы по клику на кнопку "удалить" (та которая ImageView
с изображением корзины) происходило удаление записи по её ID, я решил сетить ей ID.
То есть, вот так:
@Override
public void onBindViewHolder(ExerciseViewHolder holder, int position) {
mDeleteBtn.setTag(exercises.get(position).ID);
}
Но проблема в том, что абсолютно всем экземплярам кнопке (на всех карточках) сетится
один и тот же ID (последняя запись в таблице).
И вопрос в том, как же мне сделать так, чтобы на каждой кнопке висел тег с правильной
айдишкой (которая соответствует информации на карточке).
Ответы
Ответ 1
Попробуйте так: public ExerciseViewHolder(View v) { super(v); mTextView = (TextView) v.findViewById(R.id.tv_recycler_item); mTextViewName = (TextView) v.findViewById(R.id.exerciseNameEx); mTextViewMusckeGroup = (TextView)v.findViewById(R.id.tvMuscleGroup); mTextViewRepeats = (TextView) v.findViewById(R.id.tvRepeats); mDeleteBtn = (ImageView) v.findViewById(R.id.deleteBtnEx); mDeleteBtn.setOnClickListener(this); } @Override public void onClick(View v){ delete(getAdapterPosition()); } } .... public void delete(int position) { exercises.remove(position); notifyItemRemoved(position); } Можете всё в onClick запихать, но советую так оставить, не нужно грузить listner-ы в адаптере, будет удобней расширять потом.Ответ 2
Не надо тэг для этого использовать. У вас mDeleteBtn член класса адаптера и всегда содержит ссылку на последний отрисованный элемент списка. Вам, видимо, хотелось кнопку удаления в разметку каждого элемента добавить. Если так, то получить ID при нажатии на неё вы можете просто по позиции в onBindViewHolderОтвет 3
Возможно ошибка в этом методе @Override public RecyclerAdapter.ExerciseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false); vh = new ExerciseViewHolder(v); return vh; } У вас ViewHolder объявлен переменной класса private Listexercises; ExerciseViewHolder vh; public ImageView mDeleteBtn;э Попробуйте сделать так @Override public RecyclerAdapter.ExerciseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false); ExerciseViewHolder vh = new ExerciseViewHolder(v); return vh; } И удалить строку ExerciseViewHolder vh; в начале класса
Комментариев нет:
Отправить комментарий