Задать вопрос
Fotonick
@Fotonick
android-er (Навальный отменит налоги фрилансерам)

Как обновить фрагмент после AsyncTask, вызванного кнопкой в адаптере?

UPDATE! Решение, которое посоветовал Mickey Mouse оказалось с подвохом. Во-первых у 8-го элемента списка параметр position может оказаться равным например 1. Я так понимаю position это порядковый номер не во всём списке, а только среди видимых элементов на экране. Во-вторых при разной скорости пролистывания значение position у одного и того же элемента может быть разным. Например если пролистывать медленно, то последний элемент списка получает position=1, а если пролистать быстро, то position=2. Я так понимаю это зависит от того какой уже существующий элемент списка будет повторно использоваться для новопоказавшегося. В конечном итоге при обработке нажатия на кнопку из arraylist извлекаются данные не того элемента который нужен. Подскажите как исправить это решение, или как совсем переписать обработку кнопок, чтобы извлекались верные данные.

Есть одна активити. В ней через NavigationDrawer меняются фрагменты с содержимым. Есть один фрагмент со списком приложений в Listview. Каждый пункт Listview содержит в себе три кнопки.

d09162e407a24e4eab72fcee0ee72776.png

Нажатие на кнопки обрабатываю так

фрагмент адаптера
--------------------------------
            holder.appAccept = (Button) convertView.findViewById(R.id.appAccept);
            holder.appAccept.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });

            holder.appEdit = (Button) convertView.findViewById(R.id.appEdit);
            holder.appEdit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });

            holder.appDelete = (Button) convertView.findViewById(R.id.appDelete);
            holder.appDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    whatAction = "delete";

                    AlertDialog.Builder alertDialog = new AlertDialog.Builder(parent.getContext());
                    alertDialog.setTitle("Удалить приложение");
                    alertDialog.setMessage("Вы действительно хотите удалить приложение?");

                    alertDialog.setPositiveButton("Удалить", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {

                            new AdminDecision(position, whatAction, parent.getContext()).execute();
                            MySingleton ms = MySingleton.getInstance();
                            Boolean adminResult = ms.getAdminResult();
                            String feedInput = ms.getAppsUpdate();

                        }
                    });

                    alertDialog.setNegativeButton("Отмена", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    });
                    alertDialog.show();
                }
            });
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
            holder.appIcon.setVisibility(View.INVISIBLE);
        }
-------------------------


Например при нажатии на кнопку удалить вызывается Asynctask, который удаляет приложение из базы. Так вот проблема в том что я никак не могу обновить этот фрагмент со списком приложений после окончания асинктаска (реально приложения в базе уже нет, а во фрагменте ничего не изменилось).
Получается такая последовательность вызовов - фрагмент(заполнение данных при создании)-адаптер-асинктаск удаления-асинктаск получения нового списка данных. Фрагмент, адаптер и два асинтаска разделены в разные файлы.

В конце последнего асинктаска решил записывать статус успешного окончания и полученные данные в синглтон, чтобы иметь возможность вытащить их из любой активити.

@Override
        protected void onPostExecute(Void aVoid) {

            MySingleton ms = MySingleton.getInstance();
            ms.setAppsUpdate(jsonFeed.toString());
            ms.setAdminResult(adminResult);
        }


Пытался обновлять фрагмент вызывая OnResume (пересоздавая фрагмент заново с повторным запросом данных), но оказалось, что AlertDialog (для подтверждения намерения удалить один из пунктов в списке) не вызывает у фрагмента OnPause, а другого автоматического обновления фрагмента не придумал.

Подскажите как быть. Кажется я тут наворотил....
  • Вопрос задан
  • 1137 просмотров
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 2
@MikkiMouse
У вас же в адаптере должны быть данные, список этих самых приложений которыми заполняется ListView?
После завершения AsyncTask вам нужно удалить "приложение" из данных адаптера и вызвать notifyDataSetChanged.
Ответ написан
Fotonick
@Fotonick Автор вопроса
android-er (Навальный отменит налоги фрилансерам)
Решение от MikkiMouse

в адаптер добавил
private Callbacks callbacks;

    public interface Callbacks {
        void onAppAccept(int position);

        void onAppEdit(int position);

        void onAppDelete(int position);
    }

    public void setCallbacks(Callbacks callbacks) {
        this.callbacks = callbacks;
    }


там же в адаптере обработчик кнопки вызывает один из методов
holder.appEdit = (Button) convertView.findViewById(R.id.appEdit);
            holder.appEdit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    callbacks.onAppEdit(position);

                }
            });


Во фрагменте перед назначением адаптера

oneAppAdminAdapter = new OneAppAdminAdapter(AllAppsAdminFragment.this, allAppsList);

                        oneAppAdminAdapter.setCallbacks(new OneAppAdminAdapter.Callbacks() {
                            @Override
                            public void onAppAccept(int position) {

                               //вызов асинтаска принятия
                            }

                            @Override
                            public void onAppEdit(int position) {                                

                               //вызов фрагмента редактирования
                            }

                            @Override
                            public void onAppDelete(int position) {
                               //вызов асинтаска удаления
                            }
                        });

                        setListAdapter(oneAppAdminAdapter);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы