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

Обсуждение уроков
Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

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

Сообщение KamiSempai » 27 янв 2015, 17:44

aleksbim писал(а): Список выведен путем выборки из БД.
Теперь элементы не удаляются через контекстное меню.
http://developer.android.com/reference/ ... tChanged()
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

K_Vladimir
Сообщения: 36
Зарегистрирован: 28 июн 2015, 03:13

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

Сообщение K_Vladimir » 08 июл 2015, 17:13

1. Скажите, а как по SQLite запросу изменить строку в БД по _id, например txt из урока?
Типа mDB.execSQL(........)
Или только с помощью mDB.update(DB_TABLE, cv, COLUMN_ID + " = ?", new String[]{str_id});?

2. Можно уточнить по уроку что именно делает метод startManagingCursor(cursor);?
Что делает activity с cursor при смене LifeCycle?

3. Поясните пожалуйста по cursor.requery();:

cursor = db.getAllData();
Вызывает
public Cursor getAllData() {
return mDB.query(DB_TABLE, null, null, null, null, null, null);
}
Здесь же просто вбиваем таблицу в сursor? Или присваиваем метод нашему сursor?
Потому что непонятно откуда метод cursor.requery(); знает с какой БД работать, и как себя перезаполнить??? Мы же, например, могли заполнять cursor используя query с выборкой по значению полей. Тогда requery будет с такой же выборкой?

Спасибо.

Аватара пользователя
webprog26
Сообщения: 1
Зарегистрирован: 02 июл 2015, 14:08
Откуда: UA

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

Сообщение webprog26 » 10 июл 2015, 17:32

При попытке добавить возможность редактирования содержимого строки ListView по нажатию пункта контекстного меню программа валится из за того, что cursor = null (строка 111). Помогите. пожалуйста, что-то не могу вкурить, в чем проблема.

Код MainActivity.java
[syntax=java]
package com.example.webprog26.editablelistview;

import android.app.Activity;
import android.app.LoaderManager;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.widget.Toast;

import java.util.concurrent.TimeUnit;


public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor>{

ListView lvText;
DB db;
SimpleCursorAdapter scAdapter;
private Cursor cursor;

//REQUEST_CODE для отправки запроса в EditActivity на редактирование записей
final int REQUEST_CODE_NEW_TEXT = 0;
final int REQUEST_CODE_EDIT_TEXT = 1;

//ID для контекстного меню
private static final int CM_DELETE_ID = 1;
private static final int CM_EDIT_ID = 2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//открываем подключение к БД
db = new DB(this);
db.openDB();

//формируем столбцы сопоставления
String[] from = new String[]{DB.COLUMN_TEXT};
int[] to = new int[]{R.id.tvText};

//создаем адаптер и настраиваием список
scAdapter = new SimpleCursorAdapter(this, R.layout.item, null, from, to, 0);
lvText = (ListView) findViewById(R.id.lvText);
lvText.setAdapter(scAdapter);


//добавляем к списку контекстное меню
registerForContextMenu(lvText);

//создаем лоадер для чтения данных
getSupportLoaderManager().initLoader(0, null, this);
}

//обработка нажатия кнопки


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

switch(id)
{
case R.id.menu_add:
intent = new Intent(this, EditActivity.class);
startActivityForResult(intent, REQUEST_CODE_NEW_TEXT);
break;
}
return super.onOptionsItemSelected(item);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, CM_EDIT_ID, 0, R.string.context_menu_edit);
menu.add(0, CM_DELETE_ID, 0, R.string.context_menu_delete);
}

@Override
public boolean onContextItemSelected(MenuItem item) {

AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

switch(item.getItemId())
{
case CM_EDIT_ID:
cursor.moveToPosition(acmi.position);
Intent intent = new Intent(this, EditActivity.class);
intent.putExtra(DB.COLUMN_ID, acmi.id);
intent.putExtra(DB.COLUMN_TEXT, cursor.getString(cursor.getColumnIndexOrThrow(DB.COLUMN_TEXT)));
startActivityForResult(intent, REQUEST_CODE_EDIT_TEXT);
break;
case CM_DELETE_ID:
db.deleteSingleData(acmi.id);
getSupportLoaderManager().getLoader(0).forceLoad();
}
return super.onContextItemSelected(item);
}



@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bundle extras = data.getExtras();
switch(requestCode)
{
case REQUEST_CODE_NEW_TEXT:
String text = extras.getString(DB.COLUMN_TEXT);
db.addData(text);
//код, для вывода записи на экран
getSupportLoaderManager().getLoader(0).forceLoad();
}
}

@Override
protected void onDestroy() {
super.onDestroy();
db.closeDB();
}
public Loader<Cursor> onCreateLoader(int id, Bundle bundle)
{
return new MyCursorLoader(this, db);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
{
scAdapter.swapCursor(cursor);
}

public void onLoaderReset(Loader<Cursor> loader){}

static class MyCursorLoader extends CursorLoader
{
DB db;
public MyCursorLoader(Context context, DB db)
{
super(context);
this.db = db;
}
public Cursor loadInBackground()
{
Cursor cursor = db.getAllData();
try
{
TimeUnit.SECONDS.sleep(3);
}catch (InterruptedException e)
{
e.printStackTrace();
}
return cursor;
}
}
}

[/syntax]

OrcSin
Сообщения: 8
Зарегистрирован: 18 дек 2014, 12:45

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

Сообщение OrcSin » 30 июл 2015, 21:47

startManagingCursor стал deprecated. Подправите пожалуйста урок.

K_Vladimir
Сообщения: 36
Зарегистрирован: 28 июн 2015, 03:13

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

Сообщение K_Vladimir » 31 июл 2015, 10:08

OrcSin писал(а):startManagingCursor стал deprecated. Подправите пожалуйста урок.
Там же сказано, что теперь нужно Loader использовать. Урок 136 http://startandroid.ru/ru/uroki/vse-uro ... oader.html

niklas1987
Сообщения: 3
Зарегистрирован: 06 мар 2015, 22:41

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

Сообщение niklas1987 » 23 авг 2015, 10:25

Здравствуйте. Научился я тут запросы отправлять, запрашивать... все ок. При добавлении записи в ListView проблем нет, ListView обновляется , но при удалении из него, никак не могу его обновить во Fragment'е. Приходится листать фрагменты, чтобы item из ListView пропал...

Пробовал по всякому... вот последний код

[syntax=java]
int currentPosition;
ListView lvSimple;
View view = inflater.inflate(R.layout.fragment, null);
Cursor c;

static PageFragment newInstance(int page) {
currentPosition = page;
PageFragment pageFragment = new PageFragment();
Bundle arguments = new Bundle();
arguments.putInt(ARGUMENT_PAGE_NUMBER, page);
pageFragment.setArguments(arguments);
return pageFragment;
}

public void populateListView(int i) {
c = myDB.getMonthRows();
switch (i){
case 0:
c = myDB.getMonthRows();
Log.d("ME", "0 block");
break;
case 1:
Log.d("ME", "1 block");
c = myDB.getAllRows();
break;
case 2:
c = myDB.getMonthRows();
Log.d("ME", "2 block");
break;
case 3:
c = myDB.getMonthRows();
Log.d("ME", "3 block");
break;
}
String[] fromFieldNames = new String[]{DBAdapter.KEY_DATE, DBAdapter.KEY_AREA, DBAdapter.KEY_PASSENGER};
int[] toViewsID = new int[]{R.id.tvItemDate, R.id.tvItemArea, R.id.tvItemPassenger};
SimpleCursorAdapter myC = new SimpleCursorAdapter(view.getContext(), R.layout.item, c, fromFieldNames, toViewsID, 0);
myC.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if (columnIndex == 1) {
String createDate = cursor.getString(columnIndex);
textView = (TextView) view;
textView.setText(dateFormat(createDate));
return true;
}
return false;
}
});
if(c!=null){
c.requery();
}
lvSimple = (ListView)view.findViewById(R.id.lvSimple);
myC.notifyDataSetChanged();
lvSimple.setAdapter(myC);
lvSimple.invalidateViews();
registerForContextMenu(lvSimple);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, CM_DELETE_ID, 0, R.string.delete_record);
}

public boolean onContextItemSelected(MenuItem item) {
if (item.getItemId() == CM_DELETE_ID) {
// получаем из пункта контекстного меню данные по пункту списка
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
// извлекаем id записи и удаляем соответствующую запись в БД
myDB.deleteRow(acmi.id);
myC.notifyDataSetChanged();
populateListView(currentPosition);
return true;
}
return super.onContextItemSelected(item);
}
[/syntax]

Androro
Сообщения: 1
Зарегистрирован: 22 фев 2016, 21:59

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

Сообщение Androro » 22 фев 2016, 22:31

Здравствуйте!

В ListView не работает контекстное меню. Проблема именно в item XML.

[syntax=xml]<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llitem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/number"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:textSize="27sp" />

<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="27sp" />

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right" >

<CheckBox
android:id="@+id/otmetka"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

</LinearLayout>[/syntax]

Если удалить
[syntax=xml]<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right" >

<CheckBox
android:id="@+id/otmetka"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>[/syntax]
, то работает.

То есть при заданной компоновке item не работает меню. У контекстного меню есть ограничения?

aleksbim
Сообщения: 81
Зарегистрирован: 02 фев 2013, 02:52

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

Сообщение aleksbim » 27 сен 2016, 14:50

Как можно на примере урока в Layout для пункта списка item.xml добавить еще один TextView, и вставлять в него программно текст?
Просто так не получается:
TextView text=(TextView) findViewById(R.id.text);
text.setText("текст");

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

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

Сообщение Foenix » 27 сен 2016, 22:15

для списков есть ListView, RecyclerView..
Если нужн просто 1 элемент добавить, не парься, а сделай два, один невидимый, и если надо делай видимым.
Добавлять нужно как объекты создают, если уж очень нужно new TextView()... а потом все-все параметры лэйаута задать программно, если ты с этим справишься, конечно.
R.id.team

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

aleksbim
Сообщения: 81
Зарегистрирован: 02 фев 2013, 02:52

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

Сообщение aleksbim » 10 окт 2016, 14:33

Придется справиться. Изначально текст в item.xml брался из strings. Сейчас нужно из preference, так как я понял, strings программно не меняется. Проще конечно создать еще колонку в БД, но текст во всех строках списка должен быть одинаковым, что наверное неправильно.
Подскажите пжл. чуть подробней.
TextView text=new TextView(). Что и как дальше, пока в голову не приходит.

Explo
Сообщения: 7
Зарегистрирован: 03 дек 2015, 17:05

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

Сообщение Explo » 28 апр 2017, 12:42

Добрый день.
Вобщем такая ситация. Нажимаю на MainActivity кнопку и по интенту грузится вторая актвити
ее код:

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

public class HistoryActivity extends Activity {
    ListView listView;
    Cursor cursor;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_history);
 
        listView = (ListView) findViewById(R.id.listView); // он должен заполнится из базы данных
 
        DataBase dataBase = new DataBase(this);
        final SQLiteDatabase sqLiteDatabase = dataBase.getWritableDatabase();
 
 
        String[] from = new String[]{"searchWord", "searchLang"};  пишу поля которые мне нужны для отображения- я так это понял
        int[] to = new int[]{R.id.searchText, R.id.translated}; // пишу id куда должны вставится поля описаные выше
 
        cursor = sqLiteDatabase.query("history", null, null, null, null, null, null); // получаю курсор
        startManagingCursor(cursor);
 
 
        // создаю адаптер 
        SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(this, R.layout.item, cursor, from, to);
 
           // прикрепляю адаптер      
        listView.setAdapter(simpleCursorAdapter);
    }
класс БД :

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



public class DataBase extends SQLiteOpenHelper {
    public DataBase(Context context) {
        super(context, "db", null, 1);
    }
 
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table history(_id integer primary key autoincrement,searchWord text,searchLang text,translatedWord text,translatedLang text)");
        Log.d("bd","create");
    }
 
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 
    }
}
и при загрузке активити приложение вылетает с ошибко:

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

04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime: FATAL EXCEPTION: main
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime: Process: com.example.ya, PID: 16134
04-27 18:44:53.988 16134-16134/com.example.ya E/Androi[b]dRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ya/com.example.ya.Activities.HistoryActivity}: java.lang.IllegalArgumentException: column '_id' does not exist[/b]
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at android.app.ActivityThread.access$800(ActivityThread.java:144)
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135)
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5221)
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
04-27 18:44:53.988 16134-16134/com.example.ya E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)

Ответить