Страница 1 из 1
Обновление экрана при удалении данных из базы
Добавлено: 16 авг 2012, 17:09
powercat
Строится список из данных базы.
Далее по контекстному меню удаляется один из пунктов списка, из базы он пропадает, все ОК.
Непонятно, как удалить этот пункт из списка теперь так, чтобы он "пропал" с экрана сразу. Вот как я сделал (тут все работает):
Код: Выделить всё
db = SQLiteDatabase.openDatabase(pathToDB, null, SQLiteDatabase.OPEN_READWRITE);
cursor=db.query("mainTable", null, null, null, null, null, null);
startManagingCursor(cursor);
if (cursor.moveToFirst()){
String[] from=new String[]{"Поле","pathToFile"};
int[]to =new int[]{R.id.tvText,R.id.ivImg};
scAdapter=new SimpleCursorAdapter(this,R.layout.item,cursor,from,to);
lvМойСписок.setAdapter(scAdapter);
registerForContextMenu(lvМойСписок);
}else{
//Если строк нет
.........
}
db.close();
А это обработка контекста
Код: Выделить всё
public boolean onContextItemSelected(MenuItem item){
switch (item.getItemId()){
case R.id.delete:
db = SQLiteDatabase.openDatabase(pathToDB, null, SQLiteDatabase.OPEN_READWRITE);
AdapterContextMenuInfo adapterContextMenuInfo=(AdapterContextMenuInfo)item.getMenuInfo();
db.delete("mainTable","_id = "+adapterContextMenuInfo.id,null);
db.close();
Далее извращенный кусок...сильно подозреваю, что можно сделать как-то проще...мой вариант работает как надо, но это изврат ((( Т.е. я еще раз обращаюсь к базе, получаю курсор и строю список, т.е. почти скопированный вышеприведенный код.
db = SQLiteDatabase.openDatabase(pathToDB, null, SQLiteDatabase.OPEN_READWRITE);
cursor=db.query("mainTable", null, null, null, null, null, null);
startManagingCursor(cursor);
if (cursor.moveToFirst()){
String[] from=new String[]{"nameOfPlant","pathToFile"};
int[]to =new int[]{R.id.tvText,R.id.ivImg};
scAdapter=new SimpleCursorAdapter(this,R.layout.item,cursor,from,to);
lvМойСписок.setAdapter(scAdapter);
registerForContextMenu(lvМойСписок);
}else{
//Если строк нет
......... }
db.close();
break;
}
return super.onContextItemSelected(item);
}
Re: Обновление экрана при удалении данных из базы
Добавлено: 16 авг 2012, 17:21
rezak90
в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
Re: Обновление экрана при удалении данных из базы
Добавлено: 16 авг 2012, 20:48
neoksi
rezak90 писал(а):в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
А у меня вопрос, вот при изменении в БД мой контент провайдер курсору отправляет Notify об изменении данных, активити его ловит и обновляет в самом курсоре данные, а теперь суть вопроса, как мне узнать что данные в курсоре обновлены и что-то сделать по этому случаю?
Re: Обновление экрана при удалении данных из базы
Добавлено: 17 авг 2012, 09:51
powercat
rezak90 писал(а):в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
А смотрел инфу по этому методу, но не понял, куда его прикрутить...попробовал в разные места поставить - нифига...И еще непонятно - что-то после этого метода надо писать или до него? можно готовый код?
Re: Обновление экрана при удалении данных из базы
Добавлено: 17 авг 2012, 10:44
neoksi
powercat писал(а):rezak90 писал(а):в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
А смотрел инфу по этому методу, но не понял, куда его прикрутить...попробовал в разные места поставить - нифига...И еще непонятно - что-то после этого метода надо писать или до него? можно готовый код?
Вчитался в код и понял, что обновления курсора не будет в этом случае, так как работа идет напрямую с БД и при изменении данных, никто не сообщает курсору, что данные обновились. Тут отсутствует прослойка в качестве ContentProvider'а, который как раз и берет на себя функцию по уведомлению о вносимых изменениях в БД. Советую прочитать 101 урок, он как раз все описывает. Обратите особое внимание там на URI, с помощью них, как раз и передаются сообщения об обновлениях.
П.С. Сам сейчас разбираюсь с похожим, изучаю работу с Observer, чтоб отказаться от CursorAdapter'а.
Re: Обновление экрана при удалении данных из базы
Добавлено: 17 авг 2012, 12:41
k.chaiko
подскажите как юзать notifyDataSetChanged с кастомным адаптером ?? ато у меня не работает никак...(
Re: Обновление экрана при удалении данных из базы
Добавлено: 17 авг 2012, 12:50
rezak90
k.chaiko писал(а):подскажите как юзать notifyDataSetChanged с кастомным адаптером ?? ато у меня не работает никак...(
та так же как и с обычным... например: идёт загрузка нескольких файлов, загрузили один файл - вызвали adapter.notifyDataSetChanged() и после каждой загруки и т.д.
Re: Обновление экрана при удалении данных из базы
Добавлено: 17 авг 2012, 13:48
powercat
neoksi писал(а):powercat писал(а):rezak90 писал(а):в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
А смотрел инфу по этому методу, но не понял, куда его прикрутить...попробовал в разные места поставить - нифига...И еще непонятно - что-то после этого метода надо писать или до него? можно готовый код?
Вчитался в код и понял, что обновления курсора не будет в этом случае, так как работа идет напрямую с БД и при изменении данных, никто не сообщает курсору, что данные обновились. Тут отсутствует прослойка в качестве ContentProvider'а, который как раз и берет на себя функцию по уведомлению о вносимых изменениях в БД. Советую прочитать 101 урок, он как раз все описывает. Обратите особое внимание там на URI, с помощью них, как раз и передаются сообщения об обновлениях.
П.С. Сам сейчас разбираюсь с похожим, изучаю работу с Observer, чтоб отказаться от CursorAdapter'а.
Ну...может не не вчитался до конца? Там каждый раз запрашивается новый курсор из базы. Вопрос в том, как удалить ПУНКИ из СПИСКА...т.е. как сказать списку, что вот данный пункт не нужен? В моем примере список строится один раз, потом при клике - удаление из базы записи и ПЕРЕПОСТРОЕНИЕ списка...но ведь наверняка можно просто УДАЛИТЬ пункт у текущего, без перепостроения....
Re: Обновление экрана при удалении данных из базы
Добавлено: 17 авг 2012, 14:05
neoksi
powercat писал(а):
Ну...может не не вчитался до конца? Там каждый раз запрашивается новый курсор из базы. Вопрос в том, как удалить ПУНКИ из СПИСКА...т.е. как сказать списку, что вот данный пункт не нужен? В моем примере список строится один раз, потом при клике - удаление из базы записи и ПЕРЕПОСТРОЕНИЕ списка...но ведь наверняка можно просто УДАЛИТЬ пункт у текущего, без перепостроения....
Ну да, второй кусок кода не осознал в полной мере =)
1) Объявите курсор как переменную класса, а не метода.
2) Вместо дублирования и пересоздания списка заново, выполните
cursor.requery();, должен автоматом все обновить.
cursor.requery(); вместо этого кода:
Код: Выделить всё
db = SQLiteDatabase.openDatabase(pathToDB, null, SQLiteDatabase.OPEN_READWRITE);
cursor=db.query("mainTable", null, null, null, null, null, null);
startManagingCursor(cursor);
if (cursor.moveToFirst()){
String[] from=new String[]{"nameOfPlant","pathToFile"};
int[]to =new int[]{R.id.tvText,R.id.ivImg};
scAdapter=new SimpleCursorAdapter(this,R.layout.item,cursor,from,to);
lvМойСписок.setAdapter(scAdapter);
registerForContextMenu(lvМойСписок);
}else{
//Если строк нет
......... }
db.close();
Должно получиться следующее:
Код: Выделить всё
cursor.requery();
if (cursor.moveToFirst()){
//Если строки есть
}else{
//Если строк нет
}
Re: Обновление экрана при удалении данных из базы
Добавлено: 17 авг 2012, 14:22
powercat
Ну хорошо...а дальше? Основной вопрос не в курсоре, а в списке ))) курсор...да хрен с ним ))) или это и есть способ сократить код - а список все ж перестраивать снова?
Re: Обновление экрана при удалении данных из базы
Добавлено: 17 авг 2012, 14:32
neoksi
powercat писал(а):Ну хорошо...а дальше? Основной вопрос не в курсоре, а в списке ))) курсор...да хрен с ним ))) или это и есть способ сократить код - а список все ж перестраивать снова?
Курсор завязывается с адаптером, при первом создании списка.
Метод
requery():
1) Перезапросит данные из БД
2) Вызовет метод notifyDataSetChanged() у всех адаптеров, к которым он привязан
3) Адаптер, при исполнении notifyDataSetChanged() перерисует канву отображения
И ничего не нужно мудрить

Re: Обновление экрана при удалении данных из базы
Добавлено: 17 авг 2012, 14:40
powercat
ок, благодарю, щас буду тренироваться )))
Re: Обновление экрана при удалении данных из базы
Добавлено: 20 авг 2012, 01:04
neoksi
powercat писал(а):ок, благодарю, щас буду тренироваться )))
Я лично покопался в исходниках SDK и более менее понял механизм Observer, в результате у меня получилось реализовать следующий механизм:
N-ый курсор -> Массив с данными -> Свой адаптер -> View
В результате получилось, что у меня может быть привязано к одному адаптеру любое количество курсоров, и при их обновлении, обновляются автоматом данные отображения.
На каждый курсор я вешаю 2 наблюдателя:
Код: Выделить всё
myCursor.registerContentObserver(new CursorChangeObserver); // (Observer) Наблюдатель выполняется, когда курсор узнал об обновлении данных
myCursor.registerDataSetObserver(new CursorDataSetObserver); // (Observer) Наблюдатель выполняется, когда данные в курсоре обновились
CursorChangeObserver у меня обновляет курсор методом
requery() и сообщает, что данные обновились.
CursorDataSetObserver срабатывает когда обновился курсор и он наполняет новыми данными массив, а массив при обновлении цепляет обновление адаптера и далее.
Re: Обновление экрана при удалении данных из базы
Добавлено: 20 авг 2012, 09:22
powercat
Это для меня пока шоппц сложно.
requery у меня что-то не работает ))) вместо него просто делаю перезапрос курсора:
Код: Выделить всё
cursor=db.query("mainTable", null, null, null, null, null, null);
scAdapter.changeCursor(cursor);
Re: Обновление экрана при удалении данных из базы
Добавлено: 20 авг 2012, 10:53
neoksi
powercat писал(а):Это для меня пока шоппц сложно.
requery у меня что-то не работает ))) вместо него просто делаю перезапрос курсора:
Код: Выделить всё
cursor=db.query("mainTable", null, null, null, null, null, null);
scAdapter.changeCursor(cursor);
Как показал
мой опыт, если реквери не срабатывает, то значит, сам где-то накосячил =) У меня это было закрытие БД, при которой курсор терял доступ к данным =)
Re: Обновление экрана при удалении данных из базы
Добавлено: 20 авг 2012, 11:05
powercat
да запросто...первый раз с базой работаю...