Урок 52. SimpleCursorAdapter, пример использования

Обсуждение уроков
Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 31 июл 2013, 13:32

Greatergood писал(а):про showDialog() понял, разобрался все нормуль, а вот про Лоадер этот пока все в тумане. ну спасибо за помощь все-равно.
для меня точно так же, я пока в процессе перехода.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

AlexInclude
Сообщения: 5
Зарегистрирован: 07 авг 2013, 10:09

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение AlexInclude » 07 авг 2013, 10:30

Сделал всё, как в уроке, бился целый день - не работает.
Причём сперва написал вывод в лист через ArrayAdapter - работает. Заменил на SimpleCursorAdapter с обвязкой - не работает.
Пробовал выводить результаты запросов к базе в лог - запросы отрабатывают, данные именно те, что я ожидаю.
Пробовал идти дебаггером по коду - весь мой код отрабатывает, а когда управление уходит куда-то глубоко в кишки Android-а - выскакивает NullPointerException. Забавно, что до создания в базе колонки "_id" вываливался эксепшен "field _id is missing".

Собственно, код:

MainActivity

[syntax=java]public class MainActivity extends Activity {
private static final String EXPENSE_DATE = "expenseDate";
private static final String EXPENSE_SOURCE = "expenseSource";
private static final String EXPENSE_TARGET = "expenseTarget";
private static final String EXPENSE_SUM = "expenseSum";

DBHelper dbHelper;
SQLiteDatabase DB;

SimpleCursorAdapter scAdapter;
ListView lvData;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

dbHelper = new DBHelper(this);
DB = dbHelper.getWritableDatabase();

String[] from = { EXPENSE_DATE, EXPENSE_SOURCE, EXPENSE_TARGET, EXPENSE_SUM };
int[] to = { R.id.expenseDate, R.id.expenseSource, R.id.expenceTarget, R.id.expenseSum };
Cursor cursor = DB.query("expenses", null, null, null, null, null, null);
startManagingCursor(cursor);
scAdapter = new SimpleCursorAdapter(this, R.layout.item_expense, cursor, from, to);
lvData = (ListView) findViewById(R.id.expensesList);
lvData.setAdapter(scAdapter);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}[/syntax]

DBHelper

[syntax=java]public class DBHelper extends SQLiteOpenHelper {

private static final String DB_TABLE_EXPENSES = "expenses";

public DBHelper(Context c) {
super(c, "hydracash", null, 1);
}

public void addExpense(SQLiteDatabase dbHandle, String expenseDate, String expenseSource,
String expenseTarget, double expenseSum, int id) {

ContentValues cv = new ContentValues();
cv.put("expenseDate", expenseDate);
cv.put("expenseSource", expenseSource);
cv.put("expenseTarget", expenseTarget);
cv.put("expenseSum", expenseSum);
cv.put("_id", id);

dbHandle.insert(DB_TABLE_EXPENSES, null, cv);
}

@Override
public void onUpgrade(SQLiteDatabase dbHandle, int oldVer, int newVer) {
// TODO Auto-generated method stub

}

@Override
public void onCreate(SQLiteDatabase dbHandle) {
dbHandle.execSQL("create table " + DB_TABLE_EXPENSES + " ("
+ "_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "expenseDate TEXT,"
+ "expenseSource TEXT,"
+ "expenseTarget TEXT,"
+ "expenseSum REAL" + ");");

addExpense(dbHandle, "20.07.2013", "Кошелёк", "Спиртное и сопутствующее", 370.5, 1);
addExpense(dbHandle, "20.07.2013", "Дебетка ВТБ24", "Кабаки и общепит", 1400, 2);
addExpense(dbHandle, "21.07.2013", "Кошелёк", "Продажные женщины", 4500.99, 3);
addExpense(dbHandle, "20.07.2013", "Кошелёк", "Азартные игры", 890, 4);
addExpense(dbHandle, "20.07.2013", "Кошелёк", "Транспорт", 60, 5);
}
}[/syntax]

Стектрейс
08-07 07:04:32.329: E/AndroidRuntime(335): FATAL EXCEPTION: main
08-07 07:04:32.329: E/AndroidRuntime(335): java.lang.RuntimeException: Unable to start activity ComponentInfo{flush/flush.MainActivity}: java.lang.NullPointerException
08-07 07:04:32.329: E/AndroidRuntime(335): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
08-07 07:04:32.329: E/AndroidRuntime(335): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-07 07:04:32.329: E/AndroidRuntime(335): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-07 07:04:32.329: E/AndroidRuntime(335): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08-07 07:04:32.329: E/AndroidRuntime(335): at android.os.Handler.dispatchMessage(Handler.java:99)
08-07 07:04:32.329: E/AndroidRuntime(335): at android.os.Looper.loop(Looper.java:123)
08-07 07:04:32.329: E/AndroidRuntime(335): at android.app.ActivityThread.main(ActivityThread.java:3683)
08-07 07:04:32.329: E/AndroidRuntime(335): at java.lang.reflect.Method.invokeNative(Native Method)
08-07 07:04:32.329: E/AndroidRuntime(335): at java.lang.reflect.Method.invoke(Method.java:507)
08-07 07:04:32.329: E/AndroidRuntime(335): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-07 07:04:32.329: E/AndroidRuntime(335): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-07 07:04:32.329: E/AndroidRuntime(335): at dalvik.system.NativeStart.main(Native Method)
08-07 07:04:32.329: E/AndroidRuntime(335): Caused by: java.lang.NullPointerException
08-07 07:04:32.329: E/AndroidRuntime(335): at flush.MainActivity.onCreate(MainActivity.java:37)
08-07 07:04:32.329: E/AndroidRuntime(335): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-07 07:04:32.329: E/AndroidRuntime(335): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
08-07 07:04:32.329: E/AndroidRuntime(335): ... 11 more
Выделенная строка лога, flush.MainActivity.onCreate(MainActivity.java:37) - это закрывающая операторная скобка обработчика onCreate.

Пишется под API 10 (2.3.3), но пробовал запустить под 4.3. Отличие только в том, что Eclipse начинает ругаться на deprecated в части startManagingCursor и конструктора SimpleCursorAdapter.

Ааааа, где ошибка?

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 07 авг 2013, 12:52

ошибка, скорее всего, вот тут lvData.setAdapter(scAdapter); не образуется lvData
в сомнительных случаях нужно не копаться наугад, а дебаггером пройтись да и все.

и странный у тебя DBHelper, ни версии БД, ни апгрейда..
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

AlexInclude
Сообщения: 5
Зарегистрирован: 07 авг 2013, 10:09

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение AlexInclude » 07 авг 2013, 13:58

Foenix писал(а):ошибка, скорее всего, вот тут lvData.setAdapter(scAdapter); не образуется lvData
в сомнительных случаях нужно не копаться наугад, а дебаггером пройтись да и все.

и странный у тебя DBHelper, ни версии БД, ни апгрейда..
Установка адаптера прямо буква в букву взята из урока, сейчас ещё раз посмотрел - там так же написано:

[syntax=java] // создааем адаптер и настраиваем список
scAdapter = new SimpleCursorAdapter(this, R.layout.item, cursor, from, to);
lvData = (ListView) findViewById(R.id.lvData);
lvData.setAdapter(scAdapter);[/syntax]

Что значит "Не образуется lvData"? Про дебаггер я писал - весь мой код он отрабатывает, NPE вылазит уже где-то в mainloop.

DBHelper я-то дорисую, мне бы урок запустить :(.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 07 авг 2013, 14:01

может не образовываться, он же отсюда инфлейтится R.id.expensesList, а не из кода урока.

Просто не понятно, если ты хэлпер не дорисовал, как же у тебя там без update-а образовались нужные _id?
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

AlexInclude
Сообщения: 5
Зарегистрирован: 07 авг 2013, 10:09

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение AlexInclude » 07 авг 2013, 14:08

Foenix писал(а):может не образовываться, он же отсюда инфлейтится R.id.expensesList, а не из кода урока.

Просто не понятно, если ты хэлпер не дорисовал, как же у тебя там без update-а образовались нужные _id?
Вот код activity_main.xml:

[syntax=xml]<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/expensesList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

</ListView>

</LinearLayout>[/syntax]

Clean и ребилд делал, автодополнение по R.id. в меню мой expensesList выводит. Более того, в варианте с ArrayAdapter всё работает.

Нужные _id дорисовались после грубого удаления файла базы через file explorer и, соответственно, отработки приведённого в хелпере onCreate :).

AlexInclude
Сообщения: 5
Зарегистрирован: 07 авг 2013, 10:09

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение AlexInclude » 07 авг 2013, 14:21

Foenix писал(а):может не образовываться, он же отсюда инфлейтится R.id.expensesList, а не из кода урока.
Нашёл. Действительно, findViewById(R.id.expensesList) возвращал null, а вот его я через watch не углядел.

Блин, идиота кусок :(.

Не хватало строчки setContentView(R.layout.activity_main); в начале onCreate в активити. Добавил строчку - заработало.

Вариант с ArrayAdapter работал потому что там лист был лейаутом, а не контролом.

В любом случае спасибо!

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 07 авг 2013, 14:45

не страшно
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Fogg
Сообщения: 7
Зарегистрирован: 18 авг 2013, 10:04

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Fogg » 18 авг 2013, 10:32

Собрал такой же проект, как и в уроке. Вылетают вот такие ошибки.

Эти, про main.xml, в Console:
[2013-08-18 11:16:41 - DB_SimpleCursorAdapter_18.08.13] W/ResourceType( 2692): Bad XML block: header size 85 or total size 5566832 is larger than data size 0
[2013-08-18 11:16:41 - DB_SimpleCursorAdapter_18.08.13] B:\Android\DB_SimpleCursorAdapter_18.08.13\res\menu\main.xml:3: error: Error: No resource found that matches the given name (at 'title' with value '@string/action_settings').

А эти - в MainActivity:

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

// формируем столбцы сопоставления
    String[] from = new String[] { DB.COLUMN_IMG, DB.COLUMN_TXT };
    int[] to = new int[] { R.id.ivImg, R.id.tvText };
// - ivImg cannot be resolved or is not a field
// - tvText cannot be resolved or is not a field
Ну и подобные, связанные, на мой взгляд, с нехотящим изменяться файлом R.java. В QuickFix предлагается создать соответствующие поля или константы. Но тогда Console кричит, что R.java был вручную изменён.

Помогите, пожалуйста, устранить ошибки.

AlexInclude
Сообщения: 5
Зарегистрирован: 07 авг 2013, 10:09

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение AlexInclude » 18 авг 2013, 10:38

Fogg писал(а):Собрал такой же проект
Build - Clean up, build - rebuild all.
Если не поможет, надо в main.xml добавить какой-нибудь элемент, и тут же его удалить.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 18 авг 2013, 11:09

Fogg писал(а):Собрал такой же проект, как и в уроке. Вылетают вот такие ошибки.

Эти, про main.xml, в Console:
[2013-08-18 11:16:41 - DB_SimpleCursorAdapter_18.08.13] W/ResourceType( 2692): Bad XML block: header size 85 or total size 5566832 is larger than data size 0
[2013-08-18 11:16:41 - DB_SimpleCursorAdapter_18.08.13] B:\Android\DB_SimpleCursorAdapter_18.08.13\res\menu\main.xml:3: error: Error: No resource found that matches the given name (at 'title' with value '@string/action_settings').

А эти - в MainActivity:

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

// формируем столбцы сопоставления
    String[] from = new String[] { DB.COLUMN_IMG, DB.COLUMN_TXT };
    int[] to = new int[] { R.id.ivImg, R.id.tvText };
// - ivImg cannot be resolved or is not a field
// - tvText cannot be resolved or is not a field
Ну и подобные, связанные, на мой взгляд, с нехотящим изменяться файлом R.java. В QuickFix предлагается создать соответствующие поля или константы. Но тогда Console кричит, что R.java был вручную изменён.

Помогите, пожалуйста, устранить ошибки.
Если это действительно не глюк эклипса (что маловероятно), то приведи тут xml ресурсы приложения своего, а так же ресурс со строковой константой.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Fogg
Сообщения: 7
Зарегистрирован: 18 авг 2013, 10:04

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Fogg » 18 авг 2013, 14:34

Foenix писал(а):
Fogg писал(а):Собрал такой же проект, как и в уроке. Вылетают вот такие ошибки.
Эти, про main.xml, в Console:
[2013-08-18 11:16:41 - DB_SimpleCursorAdapter_18.08.13] W/ResourceType( 2692): Bad XML block: header size 85 or total size 5566832 is larger than data size 0
[2013-08-18 11:16:41 - DB_SimpleCursorAdapter_18.08.13] B:\Android\DB_SimpleCursorAdapter_18.08.13\res\menu\main.xml:3: error: Error: No resource found that matches the given name (at 'title' with value '@string/action_settings').
А эти - в MainActivity:

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

// формируем столбцы сопоставления
    String[] from = new String[] { DB.COLUMN_IMG, DB.COLUMN_TXT };
    int[] to = new int[] { R.id.ivImg, R.id.tvText };
// - ivImg cannot be resolved or is not a field
// - tvText cannot be resolved or is not a field
Ну и подобные, связанные, на мой взгляд, с нехотящим изменяться файлом R.java. В QuickFix предлагается создать соответствующие поля или константы. Но тогда Console кричит, что R.java был вручную изменён.
Помогите, пожалуйста, устранить ошибки.
Если это действительно не глюк эклипса (что маловероятно), то приведи тут xml ресурсы приложения своего, а так же ресурс со строковой константой.
main.xml

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical">
	<Button
	 android:layout_width="wrap_content"
	 android:layout_height="wrap_content"
	 android:onClick="onButtonClick"
	 android:text="@string/add_record">
	</Button>
	<ListView
	 android:id="@+id/lvData"
	 android:layout_width="match_parent"
	 android:layout_height="wrap_content">
	</ListView>
</LinearLayout>
item.xml

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="horizontal">
	<ImageView
	 android:id="@+id/ivImg"
	 android:layout_width="wrap_content"
	 android:layout_height="wrap_content"
	 android:src="@drawable/ic_launcher">
	</ImageView>
	<TextView
	 android:id="@+id/tvText"
	 android:layout_width="wrap_content"
	 android:layout_height="wrap_content"
	 android:layout_gravity="center_vertical"
	 android:layout_marginLeft="10dp"
	 android:text=""
	 android:textSize="18sp">
	</TextView>
</LinearLayout>
strings.xml

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

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SimpleCursorAdapter</string>
<string name="add_record">Добавить запись</string>
<string name="delete_record">Удалить запись</string>
</resources>
Всё остальное не трогал.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 18 авг 2013, 14:50

сейчас посмотрю

Строки action_settings в strings нету.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 18 авг 2013, 14:53

запомни такую вещь. Если только, у тебя где-нибудь в xml ошибка, то R не будет создаваться, или пересоздаваться.
Т.е. если что-то в R не так, ищи ошибку в xml своих..
такова жизнь..
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Fogg
Сообщения: 7
Зарегистрирован: 18 авг 2013, 10:04

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Fogg » 21 авг 2013, 17:55

Спасибо, заработало.

Дошёл до загвоздки. Подскажите, пожалуйста, как обращаться из функций внутри DB.java к текстовому полю базы данных.
Я придумал DB.COLUMN_TXT.valueOf(id).toString()
Думаю, есть что-то лучше.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 21 авг 2013, 21:50

не совсем поняла чтоз начит из DB, но я обращаюсь так
c.getString(c.getColumnIndex("name"))
если там целое, допустим, то
c.getInt(c.getColumnIndex("name"))
где с - это курсор - результат выборки из таблиц. По-другому к данным таблицы ты вряд ли обратишься, кроме как через такой вот курсор.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Fogg
Сообщения: 7
Зарегистрирован: 18 авг 2013, 10:04

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Fogg » 21 авг 2013, 22:27

Foenix писал(а):не совсем поняла что значит из DB, но я обращаюсь так
c.getString(c.getColumnIndex("name"))
если там целое, допустим, то
c.getInt(c.getColumnIndex("name"))
где с - это курсор - результат выборки из таблиц. По-другому к данным таблицы ты вряд ли обратишься, кроме как через такой вот курсор.
Эх, не очень понял. Попробовал применить - вылетает.
На этом уроке описывался класс DB, который для удобства был вынесен в отдельный файл DB.java.
Я пишу для этого класса метод, который будет изменять поле int в строке, определяемой по id. Т.е. на входе - id и num.

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

public class DB {
    ...  
  public static final String COLUMN_ID = "_id";
  public static final String COLUMN_IMG = "num";
  public static final String COLUMN_TXT = "txt";
     ... 
  public void setNum(long id, int issue) {
	ContentValues cv = new ContentValues();
	cv.put(COLUMN_TXT, ___ );
	cv.put(COLUMN_IMG, issue);
        mDB.update(DB_TABLE, cv, COLUMN_ID + " = " + id, null);  }
Что нужно поставить на месте ___, чтобы всё было хорошо?

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 22 авг 2013, 06:43

туда нужно вписать числовое значение этого поля. Только я не поняла почему ты говоришь int, если это у тебя какой-то текст?
но я так поняла - тебе нужно что-то другое туда?
Объясни
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Fogg
Сообщения: 7
Зарегистрирован: 18 авг 2013, 10:04

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Fogg » 22 авг 2013, 07:46

Foenix писал(а):туда нужно вписать числовое значение этого поля. Только я не поняла почему ты говоришь int, если это у тебя какой-то текст?
но я так поняла - тебе нужно что-то другое туда?
Объясни
Ну, у нас таблица базы данных имеет 2 столбца - int и String. Пишу функцию, которая изменяет в определённой строке поле int. Для этого внутри этого метода создаю ContentValues, в который копирую имеющееся текстовое поле String в данной строке таблицы базы данных и новое значение поля int в этой же строке. Затем подставляю получившийся объект ContentValues в функцию update.
Как при копировании

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

cv.put(COLUMN_TXT, ___ ); 
обратиться к имеющемуся текстовому полю String?

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 52. SimpleCursorAdapter, пример использования

Сообщение Foenix » 22 авг 2013, 07:56

а... поняла кажется
у тебя неверное понимание происходящего. При update строки таблицы не нужно знать или "копировать" все ее поля, нужно заменять те, которые тебя интересуют, т.е. эту строку просто убери.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Ответить