#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 Listexercises; 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; в начале класса
Комментариев нет:
Отправить комментарий