Сохраните состояние в таблицу SQLite через пользовательский адаптер для элементов, которые были добавлены в закладки
Я продвинулся в работе с моим приложением, но я застрял, пытаясь выяснить, что необходимо реализовать для получения состояния кнопки (в этом примере изображения) в моем настраиваемом адаптере из таблицы sqlite, которая будет поддерживать записи для всех строк (с помощью _id) которые были добавлены в закладки.
Ниже, если мой настраиваемый SimpleCursorAdapter позволяет мне изменять вид изображения с помощью setSelected(), теперь мне нужно создать механизм для идентификации элементов, которые были добавлены в закладки, и сохранить его в таблице. Я добавил // комментарии о том, что я планирую делать, но не уверен, как это реализовать...
public class DxSimpleCursorAdapter extends SimpleCursorAdapter {
Context context;
Activity activity;
private DxDbAdapter mDbHelper;
public DxSimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.context=context;
this.activity=(Activity) context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
View row = super.getView(position, convertView, parent);
ImageView image = (ImageView) row.findViewById(R.id.fav);
//Query for _id of row item and see if there is an entry for it on the favourite table
//Then change ImageView to being selected image (yellow star)
//Else leave default image (greyed out)
image.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
ImageView fav = (ImageView) v.findViewById(R.id.fav);
fav.setImageResource(R.drawable.ic_fav);
long rowID = (Long) v.getTag();
Toast toast = Toast.makeText(context, "" + rowID, Toast.LENGTH_SHORT);
toast.show();
mDbHelper = new DxDbAdapter(context);
int result = mDbHelper.isFav(rowID);
if (result == 0) {
v.setSelected(true);
}
else {
v.setSelected(false);
}
}
});
return row;
}
}
Кроме того, у меня есть адаптер для моей базы данных, который я создаю функции, чтобы иметь возможность добавлять любимые записи в таблицу, но я не знаю, как я могу вызвать БД, когда в пользовательском адаптере курсора или если мне нужно идти об этом по-другому.
public class DxDbAdapter {
public static final String DIAG_ID = "_id";
public static final String DIAG_CAT = "category";
public static final String DIAG_SUB = "subcategory";
public static final String DIAG = "diagnosis";
public static final String DIAG_CODE = "diagcode";
public static final String FAV_CODE = "edid";
private static final String DATABASE_NAME = "dx";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
protected static Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper (Context context) {
super(context, DATABASE_NAME, null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String s;
try {
Toast.makeText(mCtx, "1", 2000).show();
InputStream in = mCtx.getResources().openRawResource(R.raw.sql);
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(in, null);
NodeList statements = doc.getElementsByTagName("statement");
for (int i=0; i<statements.getLength(); i++) {
s = statements.item(i).getChildNodes().item(0).getNodeValue();
db.execSQL(s);
}
} catch (Throwable t) {
Toast.makeText(mCtx, t.toString(), 50000).show();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS DiagLookups");
onCreate(db);
}
}
public DxDbAdapter(Context context) {
this.mCtx = context;
}
public DxDbAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDb.close();
}
public Cursor fetch(int level, String param) {
Cursor cursor = null;
switch (level) {
case 0:
cursor = mDb.rawQuery("Select distinct _id, diagnosis, diagcode, favourite From DiagLookup Where category = ? order by diagnosis asc", new String[]{""+param});
break;
case 1:
cursor = mDb.rawQuery("Select distinct _id, diagnosis, diagcode, favourite From DiagLookup Where subcategory = ? order by diagnosis asc", new String[]{""+param});
break;
}
return cursor;
}
public Cursor fetchFavs() {
Cursor cursor = mDb.rawQuery("Select distinct _id, diagnosis, diagcode, favourite From DiagLookup Where favourite = 1 order by diagnosis asc", null);
return cursor;
}
public int isFav(Long param) {
Cursor cursor = mDb.rawQuery("Select favourite From DiagLookup Where _id = ?", new String[]{""+param});
int result = cursor.getInt(cursor.getColumnIndex(FAV));
return result;
}
Моя структура таблицы выглядит следующим образом:
CREATE TABLE IF NOT EXISTS Lookup (
_id INTEGER PRIMARY KEY,
category VARCHAR(150),
subcategory VARCHAR(150),
diagnosis VARCHAR(150),
diagcode VARCHAR(150),
favourite INTEGER)
У меня есть listactivity, который я создаю БД и открываю () его. Оттуда я извлекаю () данные в курсор и передаю их в мой DxSimpleCursorAdapter.
Любое руководство будет с благодарностью.
Спасибо
1 ответ
Вы должны реализовать bindView()
и newView()
методы, так что вы будете иметь доступ к курсору. В newView()
Вы раздуваете макет:
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context); // you should put this in the constructor so you don't do it every time the newView() method is called
View row = inflater.inflate(R.layout.row_layout, null);
// even implement the view holder pattern for a small performance boost
ViewHolder holder = new ViewHolder();
holder.image = (ImageView) row.findViewById(R.id.the_id_of_the_image);
row.setTag(holder);
return row;
}
ViewHolder
это класс в вашем адаптере, который будет содержать представления, поэтому мы не ищем весь макет каждый раз, когда хотим получить доступ к представлениям строк:
class ViewHolder {
ImageView image;
// other views that you have in your row layout
}
Затем реализовать bindView()
метод:
@Override
public void bindView(View v, Context con, Cursor cursor) {
ViewHolder holder = (ViewHolder) v.getTag() //retrieve the holder with the row views
// set the current image status
int status = cursor.getInt(cursor.getColumnIndex(FAV_CODE)); // get the status( I don't know how you store the favorite status, I assumed is an int in the FAV_CODE column, 1 for favorite, 0 for unpicked yet)
if (status == 1) {
// the user set as favorite
holder.image.setImageResource(R.drawable.favorite); // set the favorite drawable
} else {
// this isn't a favorite so put the default image
holder.image.setImageResource(R.drawable.normal); // set the normal drawable
}
//get the row id from the cursor that we will pass in the onClick method as a tag for the image
long id = cursor.getLong(cursor.getColumnIndex(DIAG_ID));
holder.image.setTag(new Long(id));
// set the image listener
holder.image.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
long rowID = (Long) v.getTag();
//there is no need to find the view, and you don't modify the imageview image from here
// query the database to find the row with the _id equal to rowID
// find out what value we have in the column with the image status (either 1 or 0 meaning favorite or not favorite)
// update the row with the new status (if you have 1 in the database then update the status with 0 , if you have 0 in the database then update the value with 1)
//call notifyDatasetChanged on the adapter to let the adapter know about the update, I don't know if this call will work with SimpleCursorAdapter, you may have to set a new adapter on the ListView with a new cursor.
}
});
}