Урок 136. CursorLoader

Обсуждение уроков
Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Урок 136. CursorLoader

Сообщение doter.ua » 13 окт 2015, 17:44

ViewPager, Glide.
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

Nik_VS
Сообщения: 2
Зарегистрирован: 13 окт 2015, 12:12

Re: Урок 136. CursorLoader

Сообщение Nik_VS » 14 окт 2015, 13:07

Большое спасибо!

correptum
Сообщения: 7
Зарегистрирован: 19 сен 2015, 15:57

Re: Урок 136. CursorLoader

Сообщение correptum » 19 окт 2015, 22:19

Доброго времени суток.
В начале пути изучения.
Есть тема Урок 110. Android 3. Fragments. DialogFragment - диалог и Урок 136. CursorLoader.
Задача: Прочитать БД и передать в диалоговое окно.
Привожу код MainActivity

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

                cursor = db.readyDB("auto", null, selection, selectionArgs, null, null, null);
                userAdapter = new SimpleCursorAdapter(this, R.layout.auto, cursor, fromStr, toInt, 0);
                dialog.show(getFragmentManager(), "dialog");
Этот адаптер надо прочитать в auto.java

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

public class auto extends DialogFragment implements OnClickListener {
    final String LOG_TAG = "myLogs";

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        getDialog().setTitle(R.string.auto);
        View view = inflater.inflate(R.layout.auto, null);
        return view;
    }
И вот тут загвоздка. Я потерялся. Как получить в auto.java этот адаптер?
Последний раз редактировалось correptum 19 окт 2015, 22:34, всего редактировалось 1 раз.

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

Re: Урок 136. CursorLoader

Сообщение Foenix » 19 окт 2015, 22:26

а никак. Создавать адаптер нужно по уроку прямо в диалоге, если тебе там нужен список. !передать бд" в диалог - как-то неправильно звучит.
R.id.team

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

correptum
Сообщения: 7
Зарегистрирован: 19 сен 2015, 15:57

Re: Урок 136. CursorLoader

Сообщение correptum » 19 окт 2015, 22:30

Foenix писал(а):а никак. Создавать адаптер нужно по уроку прямо в диалоге, если тебе там нужен список. !передать бд" в диалог - как-то неправильно звучит.
Передать выборку в диалог, даже более точнее - cursor.

Тогда я еще больше потерялся. Буду разбираться.

Может есть понятно расписанная инфа по данному вопросу?

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

Re: Урок 136. CursorLoader

Сообщение Foenix » 19 окт 2015, 22:53

все делается аналогично активити, только в фрагменте диалога.
R.id.team

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

correptum
Сообщения: 7
Зарегистрирован: 19 сен 2015, 15:57

Re: Урок 136. CursorLoader

Сообщение correptum » 20 окт 2015, 00:06

Foenix писал(а):все делается аналогично активити, только в фрагменте диалога.
т.е. мне в auto.jave создавать запрос к БД и т.д.?

Как я понимаю.
Создал отдельный layout и java класс для диалогового окна.
В классе я прописываю вывод диалогового окна и должен прописать SimpleCursorAdapter. SimpleCursorAdapter должен получить cursor, который формируется в основной layout. Значит надо организовать как-то передачу этого cursor.
Либо формировать cursor непосредственно в java диалогового окна. НО тогда необходимо передать из основного layout условия для чтения БД.

Объясните, плиз, как тут мне быть.

kosikov2006
Сообщения: 1
Зарегистрирован: 01 окт 2015, 18:07

Re: Урок 136. CursorLoader

Сообщение kosikov2006 » 07 ноя 2015, 14:52

Моя база примерно 2-3 секунды обрабатывает запрос, могу ли я отобразить круглый прогресс перед показом списка? Почему-то никак не получается.

Я попробовал поставить круглый прогресс на layout. Он у всегда видимый (всегда крутится).
Выполняю по нажатию кнопки вот этот код и он почемуто выполняется в UI-потоке, прогресс перестает крутиться пока идет обработка.

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

        db = new DB(this, null);
        db.open();

        // формируем столбцы сопоставления
        String[] from = {"fio", "adr", "prich", "datr", "p_u"};
        int[] to = new int[] { R.id.tvText1, R.id.tvText2, R.id.tvText3, R.id.tvText4, R.id.tvText5 };

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

        // создаем лоадер для чтения данных
        getSupportLoaderManager().initLoader(0, null, this);
Может как-то можно перенести этот код в отдельный поток. У меня не получилось - функции матерятся на LoaderCallbacks.


Тут даже скорее другая проблема. Сейчас сделал без лоадера. Та же проблема.
Оказывается обработка базы данных происходит мгновенно, а вот построение ListView идёт 2-3 секунды и соответственно вызывает остановку прогресса.
Можно ли от этого избавиться, или вместо прогресса придется всётаки использовать статичный TextView с текстом "Построение списка..."?

lexx
Сообщения: 4
Зарегистрирован: 10 май 2015, 23:55

Re: Урок 136. CursorLoader

Сообщение lexx » 15 дек 2015, 16:56

можно ли взамен onCreate/onDestroy создавать и закрывать БД в onResumed/onPaused. При нажатии кнопки Home, принятии входного звонка активити уходит из видимости и база висит открытой, если юзать onResumed/onPaused такого не происходит

t0psecret
Сообщения: 7
Зарегистрирован: 27 янв 2016, 14:16

Re: Урок 136. CursorLoader

Сообщение t0psecret » 10 фев 2016, 17:37

подскажите, чем отличаются классы

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

import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
от

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

import android.content.CursorLoader;
import android.content.Loader;
Со вторыми, программа ругается, то ей MainActivity не нравится, то не может MyCursorLoader в Cursor преобразовать.
С виду, реализация их одинакова, отличаются комментарии к классам, в библиотеке support.v4 там написано про какой-то фреймворк.

yume
Сообщения: 6
Зарегистрирован: 20 мар 2016, 14:44

Re: Урок 136. CursorLoader

Сообщение yume » 20 мар 2016, 14:48

Доброго времени суток.
Есть такая задача: содержимое тоже, что и в уроке 136, но имеются две кнопки, при нажатии на которые меняется база данных. Как обновить содержимое listView? Так как при нажатии, допустим, на вторую кнопку (к ней привязана бд, но не та, которая грузиться по дефолту), добавляется запись в эту, вторую бд, однако в listView данные остаются от первой таблицы, которая загружается по дефолту.

upd: getSupportLoaderManager().restartLoader().

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

Re: Урок 136. CursorLoader

Сообщение Foenix » 20 мар 2016, 23:30

yume писал(а):Доброго времени суток.
Есть такая задача: содержимое тоже, что и в уроке 136, но имеются две кнопки, при нажатии на которые меняется база данных. Как обновить содержимое listView? Так как при нажатии, допустим, на вторую кнопку (к ней привязана бд, но не та, которая грузиться по дефолту), добавляется запись в эту, вторую бд, однако в listView данные остаются от первой таблицы, которая загружается по дефолту.

upd: getSupportLoaderManager().restartLoader().
используя контент провайдер посылай нотифай там именно тому набору данных, который выбирается в листвью. Тогда оно само обновится и не нужно будет рестартовать лоадер, что неправильно.
R.id.team

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

yume
Сообщения: 6
Зарегистрирован: 20 мар 2016, 14:44

Re: Урок 136. CursorLoader

Сообщение yume » 22 мар 2016, 15:09

Foenix писал(а):используя контент провайдер посылай нотифай там именно тому набору данных, который выбирается в листвью. Тогда оно само обновится и не нужно будет рестартовать лоадер, что неправильно.
Спасибо.

Ещё такой вопрос: как выводить список таким образом, чтобы добавленные записи были вверху, а не снизу?

Кошки Рулят
Сообщения: 9
Зарегистрирован: 15 мар 2016, 03:10

Re: Урок 136. CursorLoader

Сообщение Кошки Рулят » 22 мар 2016, 20:37

yume писал(а):
Ещё такой вопрос: как выводить список таким образом, чтобы добавленные записи были вверху, а не снизу?
Запрос поправить

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

    public Cursor getAllData() {
        return mDB.query(TABLE, null, null, null, null, null, "_id DESC");//null
    }

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

Re: Урок 136. CursorLoader

Сообщение Foenix » 23 мар 2016, 12:03

yume писал(а):
Foenix писал(а):используя контент провайдер посылай нотифай там именно тому набору данных, который выбирается в листвью. Тогда оно само обновится и не нужно будет рестартовать лоадер, что неправильно.
Спасибо.

Ещё такой вопрос: как выводить список таким образом, чтобы добавленные записи были вверху, а не снизу?
Для этого и для других вещей всегда обычно в таблице завожу поле с датой создания/редактирования записи. Потом по нему сортируй, например, и все.
R.id.team

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

yume
Сообщения: 6
Зарегистрирован: 20 мар 2016, 14:44

Re: Урок 136. CursorLoader

Сообщение yume » 24 мар 2016, 00:12

Кошки Рулят писал(а):Запрос поправить

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

    public Cursor getAllData() {
        return mDB.query(TABLE, null, null, null, null, null, "_id DESC");//null
    }
Foenix писал(а):Для этого и для других вещей всегда обычно в таблице завожу поле с датой создания/редактирования записи. Потом по нему сортируй, например, и все.
Благодарю!

Prefixx
Сообщения: 6
Зарегистрирован: 26 май 2015, 06:03

Re: Урок 136. CursorLoader

Сообщение Prefixx » 29 мар 2016, 16:19

Третий день разбираюсь с кастомизацией.
Задача внутри каждого элемента ListView передать и отбразить значение своего SeekBar.
Взял как в уроке Кастомный адаптер. С кнопками нет проблем. А вот с SeekBar прошу помочь показать как его увязать с TextView.

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

class TmpSimpleCursorAdapter extends SimpleCursorAdapter {
        public TmpSimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
            super(context, layout, c, from, to, flags);
        }

        @Override
        public View newView(Context _context, Cursor _cursor, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) _context.getSystemService(_context.LAYOUT_INFLATER_SERVICE);
            View view = inflater.inflate(R.layout.row_item_temperature, parent, false);
            return view;
        }

        @Override
        public void bindView(View view, Context Context, final Cursor cursor) {
            String title = cursor.getString(cursor.getColumnIndex(DBTemperature.COLUMN_TITLE));
            roomTitleTmp = (TextView) view.findViewById(R.id.roomTitleTmp);
            roomTitleTmp.setText(title);
            temperature = (TextView) view.findViewById(R.id.roomTemperature);
            adjust = (TextView) view.findViewById(R.id.adjustTemperature);
            SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekBar);
            adjust.setText("+" + seekBar.getProgress());
            seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                int progress = 0;
                @Override
                public void onProgressChanged(SeekBar seekBar, int progressValue, boolean fromUser) {
                    progress = progressValue;
                    adjust.setText("+" + progress);
                    Log.d(MEGA, "Progress Changed");
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
                    Log.d(MEGA, "Progress Started");
                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                    Log.d(MEGA, "Progress Stopped");
                }

            });

        }
    }
Логи работают нормально.

====================================
Изменил адаптер на обычный, расширенный с ViewBinder

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

public class FragmentTemperatureDB extends Fragment implements LoaderCallbacks<Cursor> {

    ListView lvTemperature;
    DBTemperature dbHelperTmp;
    SimpleCursorAdapter dataAdapterTmp;
    int LIST_TMP_ID = 0;

    ActionMode tmpActionMode;
    private int operatePosition = 0;
    final static String MEGADOR = "megadr";

    public FragmentTemperatureDB() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View vTemperatures = inflater.inflate(R.layout.fragment_thermal, container, false);
        // Initialize data for ListView
        dbHelperTmp = new DBTemperature(FragmentTemperatureDB.this.getActivity());
        dbHelperTmp.open();
        String[] from = new String[] {  DBTemperature.COLUMN_TITLE,
                                        DBTemperature.COLUMN_CURRENT_TEMP,
                                        DBTemperature.COLUMN_ADJUST_TEMP};
        int[] to = new int[] {  R.id.roomTitleTmp,
                                R.id.roomTemperature,
                                R.id.adjustTemperature};
        // Setup Adapter for ListView
        dataAdapterTmp = new SimpleCursorAdapter(FragmentTemperatureDB.this.getActivity(),
                R.layout.row_item_temperature, null, from, to, LIST_TMP_ID);
        dataAdapterTmp.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
            public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
                if (columnIndex == cursor.getColumnIndex(DBTemperature.COLUMN_ADJUST_TEMP)) {
                    int adjustProgress = cursor.getInt(columnIndex);
                    SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekBar);
                    ((TextView) view).setText("++" + adjustProgress);
                    seekBar.setProgress(adjustProgress);
                    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                        @Override
                        public void onProgressChanged(SeekBar seekBar, int progressValue, boolean fromUser) {
                            ((TextView) view).setText("+" + progressValue);
                            Log.d(MEGADOR, "Progress Changed: " + "+" + progressValue);
                        }
                        @Override
                        public void onStartTrackingTouch(SeekBar seekBar) {
                            Log.d(MEGADOR, "Progress Started:");
                        }
                        @Override
                        public void onStopTrackingTouch(SeekBar seekBar) {
                            Log.d(MEGADOR, "Progress Stopped");
                        }
                    });
                    return true;
                }
                return false;
            }
        });
        lvTemperature = (ListView) vTemperatures.findViewById(R.id.temperatureListView);
        lvTemperature.setAdapter(dataAdapterTmp);
        setHasOptionsMenu(true);
        lvTemperature.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int pos, long id) {
                operatePosition = pos;
                tmpActionMode = FragmentTemperatureDB.this.getActivity().startActionMode(new ActionBarCallBack());

                return true;
            }
        });
        // Make loader for getting data
        getLoaderManager().initLoader(LIST_TMP_ID, null, this);
        // Inflate the layout for this fragment
        return vTemperatures;
    }
Теперь почему-то SeekBar не может инициализироваться и всплывает ошибка

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

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.SeekBar.setProgress(int)' on a null object reference
                                                                            at com.gigavar.adkmegador01.FragmentTemperatureDB$1.setViewValue(FragmentTemperatureDB.java:67)
java:67 это строка

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

seekBar.setProgress(adjustProgress);
И второе - если раскомментить

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

// ((TextView) view).setText("+" + progressValue);
то пишет, что попытка доступа в inner class к view - ошибка!
Вложения
Снимок экрана 2016-03-29 в 16.10.13.png
Снимок экрана 2016-03-29 в 16.10.13.png (33.77 КБ) 13855 просмотров

Prefixx
Сообщения: 6
Зарегистрирован: 26 май 2015, 06:03

Re: Урок 136. CursorLoader

Сообщение Prefixx » 31 мар 2016, 16:19

Вернулся к кастомному SimpleCursoreAdapter.
На всякий случай поставил ViewHolder (однако, как я понимаю он просто экономит время при обращении к ресурсам).

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

    static class ViewHolder {
        TextView roomTitleTmp;
        TextView adjust;
        TextView temperature;
        SeekBar seekBar;
    }
Получил от SeekBar родительский layout
и уже в нем нашел TextView, который хотел изменить

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

viewHolder.adjust = (TextView) ((View)seekBar.getParent()).findViewById(R.id.adjustTemperature);

В итоге получилось то, что надо:

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

    class TmpSimpleCursorAdapter extends SimpleCursorAdapter {
        public TmpSimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
            super(context, layout, c, from, to, flags);
        }

        ViewHolder viewHolder;
        @Override
        public View newView(Context _context, Cursor _cursor, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) _context.getSystemService(_context.LAYOUT_INFLATER_SERVICE);
            View view = inflater.inflate(R.layout.row_item_temperature, parent, false);
            return view;
        }

        @Override
        public void bindView(View view, Context Context, final Cursor cursor) {
            String title = cursor.getString(cursor.getColumnIndex(DBTemperature.COLUMN_TITLE));
            viewHolder = new ViewHolder();
            viewHolder.roomTitleTmp = (TextView) view.findViewById(R.id.roomTitleTmp);
            viewHolder.roomTitleTmp.setText(title);
            viewHolder.temperature = (TextView) view.findViewById(R.id.roomTemperature);
            viewHolder.adjust = (TextView) view.findViewById(R.id.adjustTemperature);
            viewHolder.seekBar = (SeekBar) view.findViewById(R.id.seekBar);
            viewHolder.adjust.setText("+" + viewHolder.seekBar.getProgress());
            viewHolder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progressValue, boolean fromUser) {
                    viewHolder.adjust = (TextView) ((View)seekBar.getParent()).findViewById(R.id.adjustTemperature);
                    viewHolder.adjust.setText("+" + progressValue);
                    Log.d(MEGA, "Progress Changed");
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
                    Log.d(MEGA, "Progress Started");
                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                    Log.d(MEGA, "Progress Stopped");
                }

            });

        }
    }

netfinity
Сообщения: 13
Зарегистрирован: 07 июл 2015, 19:45

Re: Урок 136. CursorLoader

Сообщение netfinity » 12 апр 2016, 15:00

Все работает, хороший пример.
Но если добавить в item "button", то item перестает выделяться и не возможно удалить item. не работает удаление.
Как это реализовать, я так понял что если добавить button он ожидает действия, а item не работает.
Кто знает почему?

yume
Сообщения: 6
Зарегистрирован: 20 мар 2016, 14:44

Re: Урок 136. CursorLoader

Сообщение yume » 26 апр 2016, 18:09

Всем привет. Решил на основе данного урока потренировать/разобраться в поиске по БД (или сортировке). Почитал/посмотрел, увидел и решил попробовать следующее:

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

sv = (android.widget.SearchView) findViewById(R.id.action_search);
sv.setOnQueryTextListener(new android.widget.SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {

                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                scAdapter.getFilter().filter(newText);

                return false;
            }
});
Слово вводиться в SearchView, находящийся на Menu Bar. В результате получаю краш программы с NullPointerException. Объясните пожалуйста, каким образом можно организовать поиск/сортировку в данной ситуации? Является ли способ описанный выше рабочим и если я что-то не так делаю, то что? Буду очень благодарен любой помощи/примерам.

Ответить