Страницы

Поиск по вопросам

воскресенье, 15 марта 2020 г.

Обновление ListView после удаления item

#java #android #база_данных #listview #android_fragment


Здравствуйте. Никак не получается обновить ListView.

Он находится во фрагментах.

При добавлении записи все отлично, ListView обновляется.

Но после удаления приходится листать фрагменты влево, вправо, чтобы удаленные записи
пропали.

Надеюсь тут достаточно информации...

помогите пожалуйста!

Программист я так себе... Не ругайте сильно если че...

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

    


Ответы

Ответ 1



Пересоздавать адаптер не нужно. Т.е. вызов populateListView() лишний. notifyDataSetChanged() достаточно для обновления списка. Смысла в вызове invalidateViews() нет. Этот метод предназначен для обновления вьюшек, может быть вызван если меняются сами view (например, при переходе в action mode решите поменять фон или шрифты, отступы и т.д.), а не данные. Остальное правильное поведение при изменении данных осуществляется через notifyDataSetChanged(). В общем много лишнего, но даже решив проблему с обновлением, все равно придется переписывать. А именно, касаемо requery и прочего кода в олдскульном стиле, то правильная работа с курсорами и адаптерами нынче реализуется через Loader'ы (см. статья на StartAndroid'е). В частности комментарий к устаревшему методу requery говорит, что правильно пересоздавать курсор (в другом потоке) и вызывать adapter.changeCursor(newCursor). Выполняя requery (а изначально получив и передав в адаптер курсор) в основном потоке, вы можете получить ANR (скорее всего на новых api оно скоро просто не будет собираться)... Loader'ы помогают с этим делом.

Комментариев нет:

Отправить комментарий