Обновление экрана при удалении данных из базы

SQLite, Preferences, файлы, SD, Content Provider, XML, JSON
Ответить
Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Обновление экрана при удалении данных из базы

Сообщение powercat » 16 авг 2012, 17:09

Строится список из данных базы.
Далее по контекстному меню удаляется один из пунктов списка, из базы он пропадает, все ОК.
Непонятно, как удалить этот пункт из списка теперь так, чтобы он "пропал" с экрана сразу. Вот как я сделал (тут все работает):

Код: Выделить всё

		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);
	}

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Обновление экрана при удалении данных из базы

Сообщение rezak90 » 16 авг 2012, 17:21

в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
R.id.team
Политика на форуме запрещена

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Обновление экрана при удалении данных из базы

Сообщение neoksi » 16 авг 2012, 20:48

rezak90 писал(а):в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
А у меня вопрос, вот при изменении в БД мой контент провайдер курсору отправляет Notify об изменении данных, активити его ловит и обновляет в самом курсоре данные, а теперь суть вопроса, как мне узнать что данные в курсоре обновлены и что-то сделать по этому случаю?

Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Re: Обновление экрана при удалении данных из базы

Сообщение powercat » 17 авг 2012, 09:51

rezak90 писал(а):в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
А смотрел инфу по этому методу, но не понял, куда его прикрутить...попробовал в разные места поставить - нифига...И еще непонятно - что-то после этого метода надо писать или до него? можно готовый код?

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Обновление экрана при удалении данных из базы

Сообщение neoksi » 17 авг 2012, 10:44

powercat писал(а):
rezak90 писал(а):в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
А смотрел инфу по этому методу, но не понял, куда его прикрутить...попробовал в разные места поставить - нифига...И еще непонятно - что-то после этого метода надо писать или до него? можно готовый код?
Вчитался в код и понял, что обновления курсора не будет в этом случае, так как работа идет напрямую с БД и при изменении данных, никто не сообщает курсору, что данные обновились. Тут отсутствует прослойка в качестве ContentProvider'а, который как раз и берет на себя функцию по уведомлению о вносимых изменениях в БД. Советую прочитать 101 урок, он как раз все описывает. Обратите особое внимание там на URI, с помощью них, как раз и передаются сообщения об обновлениях.

П.С. Сам сейчас разбираюсь с похожим, изучаю работу с Observer, чтоб отказаться от CursorAdapter'а.

k.chaiko
Сообщения: 21
Зарегистрирован: 02 авг 2012, 17:23

Re: Обновление экрана при удалении данных из базы

Сообщение k.chaiko » 17 авг 2012, 12:41

подскажите как юзать notifyDataSetChanged с кастомным адаптером ?? ато у меня не работает никак...(

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Обновление экрана при удалении данных из базы

Сообщение rezak90 » 17 авг 2012, 12:50

k.chaiko писал(а):подскажите как юзать notifyDataSetChanged с кастомным адаптером ?? ато у меня не работает никак...(
та так же как и с обычным... например: идёт загрузка нескольких файлов, загрузили один файл - вызвали adapter.notifyDataSetChanged() и после каждой загруки и т.д.
R.id.team
Политика на форуме запрещена

Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Re: Обновление экрана при удалении данных из базы

Сообщение powercat » 17 авг 2012, 13:48

neoksi писал(а):
powercat писал(а):
rezak90 писал(а):в общем код не смотрел так как вопрос стоит в том что с бд удаляется значение а с списка нет, соответственно не делаешь обновление списка: notifyDataSetChanged()
А смотрел инфу по этому методу, но не понял, куда его прикрутить...попробовал в разные места поставить - нифига...И еще непонятно - что-то после этого метода надо писать или до него? можно готовый код?
Вчитался в код и понял, что обновления курсора не будет в этом случае, так как работа идет напрямую с БД и при изменении данных, никто не сообщает курсору, что данные обновились. Тут отсутствует прослойка в качестве ContentProvider'а, который как раз и берет на себя функцию по уведомлению о вносимых изменениях в БД. Советую прочитать 101 урок, он как раз все описывает. Обратите особое внимание там на URI, с помощью них, как раз и передаются сообщения об обновлениях.

П.С. Сам сейчас разбираюсь с похожим, изучаю работу с Observer, чтоб отказаться от CursorAdapter'а.
Ну...может не не вчитался до конца? Там каждый раз запрашивается новый курсор из базы. Вопрос в том, как удалить ПУНКИ из СПИСКА...т.е. как сказать списку, что вот данный пункт не нужен? В моем примере список строится один раз, потом при клике - удаление из базы записи и ПЕРЕПОСТРОЕНИЕ списка...но ведь наверняка можно просто УДАЛИТЬ пункт у текущего, без перепостроения....

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Обновление экрана при удалении данных из базы

Сообщение neoksi » 17 авг 2012, 14:05

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{
    //Если строк нет
}

Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Re: Обновление экрана при удалении данных из базы

Сообщение powercat » 17 авг 2012, 14:22

Ну хорошо...а дальше? Основной вопрос не в курсоре, а в списке ))) курсор...да хрен с ним ))) или это и есть способ сократить код - а список все ж перестраивать снова?

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Обновление экрана при удалении данных из базы

Сообщение neoksi » 17 авг 2012, 14:32

powercat писал(а):Ну хорошо...а дальше? Основной вопрос не в курсоре, а в списке ))) курсор...да хрен с ним ))) или это и есть способ сократить код - а список все ж перестраивать снова?
Курсор завязывается с адаптером, при первом создании списка.
Метод requery():
1) Перезапросит данные из БД
2) Вызовет метод notifyDataSetChanged() у всех адаптеров, к которым он привязан
3) Адаптер, при исполнении notifyDataSetChanged() перерисует канву отображения

И ничего не нужно мудрить ;)

Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Re: Обновление экрана при удалении данных из базы

Сообщение powercat » 17 авг 2012, 14:40

ок, благодарю, щас буду тренироваться )))

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Обновление экрана при удалении данных из базы

Сообщение neoksi » 20 авг 2012, 01:04

powercat писал(а):ок, благодарю, щас буду тренироваться )))
Я лично покопался в исходниках SDK и более менее понял механизм Observer, в результате у меня получилось реализовать следующий механизм:
N-ый курсор -> Массив с данными -> Свой адаптер -> View
В результате получилось, что у меня может быть привязано к одному адаптеру любое количество курсоров, и при их обновлении, обновляются автоматом данные отображения.
На каждый курсор я вешаю 2 наблюдателя:

Код: Выделить всё

myCursor.registerContentObserver(new CursorChangeObserver); // (Observer) Наблюдатель выполняется, когда курсор узнал об обновлении данных
myCursor.registerDataSetObserver(new CursorDataSetObserver); // (Observer) Наблюдатель выполняется, когда данные в курсоре обновились
CursorChangeObserver у меня обновляет курсор методом requery() и сообщает, что данные обновились.
CursorDataSetObserver срабатывает когда обновился курсор и он наполняет новыми данными массив, а массив при обновлении цепляет обновление адаптера и далее.

Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Re: Обновление экрана при удалении данных из базы

Сообщение powercat » 20 авг 2012, 09:22

Это для меня пока шоппц сложно.
requery у меня что-то не работает ))) вместо него просто делаю перезапрос курсора:

Код: Выделить всё

				cursor=db.query("mainTable", null, null, null, null, null, null);
				scAdapter.changeCursor(cursor);

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Обновление экрана при удалении данных из базы

Сообщение neoksi » 20 авг 2012, 10:53

powercat писал(а):Это для меня пока шоппц сложно.
requery у меня что-то не работает ))) вместо него просто делаю перезапрос курсора:

Код: Выделить всё

				cursor=db.query("mainTable", null, null, null, null, null, null);
				scAdapter.changeCursor(cursor);
Как показал мой опыт, если реквери не срабатывает, то значит, сам где-то накосячил =) У меня это было закрытие БД, при которой курсор терял доступ к данным =)

Аватара пользователя
powercat
Сообщения: 508
Зарегистрирован: 20 июл 2012, 11:31

Re: Обновление экрана при удалении данных из базы

Сообщение powercat » 20 авг 2012, 11:05

да запросто...первый раз с базой работаю...

Ответить