#cursor #android-contentprovider
#курсор #android-contentprovider
Вопрос:
Что за вопрос! Чтобы описать это более четко: я использую фрагменты, и моя цель — иметь текстовое представление, которое показывает общую сумму столбца таблицы базы данных. Эта общая сумма должна обновляться каждый раз, когда таблица обновляется различными способами (удаление, вставка, обновление). Без contentprovider я бы написал метод в своем классе DBHelper, который возвращал бы значение. Но проблема начинается.Действительно сложно (пока невозможно) фрагментарно обновлять текстовое представление программно. Поэтому мне нравится использовать contentprovider, потому что он всегда информирует мои listviews об изменениях без какой-либо дополнительной работы с моей стороны. В этом случае (contentprovider) Я должен (имхо) использовать методы загрузчика onCreateLoader() и onLoadFinished() с помощью cursorloader и uri. Но все они возвращают объект cursor, и я ничего не могу прикрепить к этому одному textview. После всех дней работы над listviews и contentproviders мое мышление, возможно, слишком «масштабно», так что я не могу увидеть простое решение для простого textview. Если таковой имеется…
Ответ №1:
Я нашел, по крайней мере, одно обходное решение. Был бы признателен, если кто-нибудь знает лучшее решение.
Чтобы использовать Loader, вам нужно переопределить 3 метода:
- onCreateLoader(идентификатор int, связка arg1)
- onLoadFinished(загрузчик загрузчика, курсор курсора) и
- onLoaderReset(загрузчик arg0)
Итак, допустим, у нас есть один телевизор TextView, который должен быть обновлен через ContentProvider.
в onCreateLoader():
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
String select = "where _id=" id; //id is definied earlier in this program
loader = new CursorLoader(getActivity(),
MaterialContentProvider.READ_SINGLE_MATSTAMM_URI, null, select, null, null);
}
return loader;
}
MaterialContentProvider.READ_SINGLE_MATSTAMM_URI — это мой URI, который показывает ContentProvider, какую таблицу БД использовать и как. В этом случае я получу один результат.
Это мы получим асинхронно с помощью onLoadFinished(), и вот мой обходной путь:
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
final TextView tv = (TextView) View.findViewById(R.id.mytextview);
tv.setText(cursor.getString(cursor.getColumnIndex("myColumn")));
}
С этого момента ваш телевизор TextView будет обновляться каждый раз, когда содержимое изменяется в таблице, на которую нацелен uri в onCreateLoader(). «Хитрость» заключается в том, чтобы не отдавать курсор, как вы обычно делаете (с помощью чего-то вроде «adapter.swap (cursor)»), потому что там нет ничего с адаптером. Чтобы получить общую сумму столбца, вы должны получить все строки этого специального столбца с помощью курсора (что означает, что у вас другой uri).
Ответ №2:
Я использовал подход, как показано здесь. По сути, вам нужно Handler
отправить строку из Cursor
пользовательского интерфейса. И вам также нужно перейти на первую позицию Cursor
:
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
if (cursor.moveToFirst()) {
final String text = cursor.getString(cursor.getColumnIndex(""myColumn));
final TextView tv = (TextView) View.findViewById(R.id.mytextview);
handler.post(new Runnable() {
public void run() {
tv.setText(text);
}
});
}
}
И не забывайте, что вы должны очистить пользовательский интерфейс при Cursor
сбросе.
@Override
public void onLoaderReset(Loader<Cursor> loader) {
final TextView tv = (TextView) View.findViewById(R.id.mytextview);
handler.post(new Runnable() {
public void run() {
tv.setText("");
}
});
}