FragmentStatePagerAdapter не обновляет фрагменты при вызове notifyDataSetChanged - PullRequest
0 голосов
/ 30 ноября 2018

Я пытаюсь реализовать динамическое обновление списка в FragmentStatePagerAdapter.У меня есть список нескольких фрагментов, в которых есть переключатели, редактируемый текст и другие фрагменты, имеющие только одно представление.

Теперь логика вращается вокруг фрагмента переключателя, поэтому предположим, что у вас есть список из 10 элементов, а элемент списка, показывающий переключатель, равен 6, и пользователю доступно 2 варианта выбора на переключателефрагмент.Если пользователь выбирает 1-й вариант, то должен отображаться 8-й элемент, а 7-й должен быть пропущен, а если выбран 2-й вариант, должен отображаться 7-й, а затем 9-й.

Я добавил пейджер представления, и с ним связан связанный FragmentStatePagerAdapter.Теперь я смог заполнить список, основываясь на параметре, но когда я обновляю список в адаптере, он не переходит с 6 на 8 и по-прежнему показывает 7.

Может ли кто-нибудь помочь мне с этим вопросом о том, как реализовать механизм переключения в FragmentStatePagerAdapter?

Адаптер

import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.ViewGroup;

import java.util.List;

public class OrderDetailsAdapter extends FragmentPagerAdapter {

    private final Logger log = LoggerFactory.getLogger(OrderDetailsAdapter.class);
    private List<IndexedFragments> adapterList;
    private FragmentManager fragmentManager;

    public OrderDetailsAdapter(FragmentManager fragmentManager, List<IndexedFragments> adapterList) {
        super(fragmentManager);
        this.fragmentManager = fragmentManager;
        this.adapterList = adapterList;
    }

    @Override
    public Fragment getItem(int position) {
        final IndexedFragments indexedFragment = adapterList.get(position);
        return indexedFragment.getFragment();
    }

    @Override
    public int getCount() {
        if (adapterList.isEmpty()) {
            return 0;
        } else {
            return adapterList.size();
        }
    }

    @Override
    public int getItemPosition(@NonNull Object object) {
        return POSITION_NONE;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        log.debug("Destroying fragment position {}", position);
    }

    public void updateList(List<IndexedFragments> indexedFragments) {
        adapterList.clear();
        log.debug("Fragment List OrderDetailsAdapter after clearing {} on {}", adapterList.size(), adapterList);
        adapterList.addAll(indexedFragments);
        log.debug("Fragment List OrderDetailsAdapter after adding indexed fragments {} on {}", adapterList.size(), adapterList);
        notifyDataSetChanged();
    }
}

Класс модели

import android.support.v4.app.Fragment;

import java.io.Serializable;

public class IndexedFragments implements Serializable {

    private final static long serialVersionUID = -304520750038118996L;
    private Integer index;
    private Fragment fragment;
    private boolean isSkippedRequested = false;

    public Integer getIndex() {
        return index;
    }

    public void setIndex(Integer index) {
        this.index = index;
    }

    public Fragment getFragment() {
        return fragment;
    }

    public void setFragment(Fragment fragment) {
        this.fragment = fragment;
    }

    public boolean isSkippedRequested() {
        return isSkippedRequested;
    }

    public void setSkippedRequested(boolean skippedRequested) {
        isSkippedRequested = skippedRequested;
    }
}

FormsActivity

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import javax.inject.Inject;

import dagger.Binds;
import dagger.Module;
import dagger.Subcomponent;
import dagger.android.ActivityKey;
import dagger.android.AndroidInjection;
import dagger.android.AndroidInjector;
import dagger.multibindings.IntoMap;


public class FormsActivity extends AppCompatActivity implements FragmentNavigationListener {

    private static String CHECK_BOX = "checkbox";
    private static String RADIO_BUTTON = "radio";
    private static String TEXT_INPUT = "text";
    private static String NUMERIC_INPUT = "numeric";
    private static String VIDEO_VIEW = "video";
    private static String IMAGE_VIEW = "image";
    private final Logger log = LoggerFactory.getLogger(FormsActivity.class);
    public LinkedHashMap<String, String> stringLinkedHashMap;
    @Inject
    protected BaseRetrofit restRequests;
    @Inject
    protected AppUtils appUtils;
    private FormData formData;
    private ViewPager viewPager;
    private ProgressBar progressBar;
    private Button submitButton;
    private Toolbar toolbar;
    private List<Frmdtl> formDataList;
    private List<IndexedFragments> fragmentList;

    private Context context;

    private OrderDetailsAdapter orderDetailsAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        AndroidInjection.inject(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_forms);
        context = this;
        Intent intent = getIntent();
        if (intent != null) {
            formData = (FormData) intent.getSerializableExtra(AppConstants.FORMS_ACTIVITY);
        }
        restRequests.setContext(this);
        initializeViews();
        populateFragments(formData);
    }

    @Override
    public void onBackPressed() {
        showAlertDialog();
    }

    private void initializeViews() {
        submitButton = findViewById(R.id.submit_button);
        toolbar = findViewById(R.id.toolbar_main_activity);
        setSupportActionBar(toolbar);
        progressBar = findViewById(R.id.progress_bar_layout);
    }

    private void showAlertDialog() {
        Dialog dialog = new AlertDialogFragment().createWarningDialog(context, getString(R.string.warning),
                getString(R.string.saved_form_data_lost),
                R.string.ok,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int which) {
                        appUtils.getFormAnswersList().clear();
                        finish();
                    }
                });
        dialog.setCanceledOnTouchOutside(true);
        dialog.show();
    }

    @SuppressLint("ClickableViewAccessibility")
    private void populateFragments(FormData formData) {
        formDataList = formData.getOrderDetails().getFrmdtl();
        fragmentList = new ArrayList<>();
        for (Frmdtl frmdtl : formDataList) {
            Fragment fragment = null;
            if (frmdtl.getFieldType().equalsIgnoreCase(TEXT_INPUT)) {
                fragment = createTextFieldFragment(frmdtl, null);
            } else if (frmdtl.getFieldType().equalsIgnoreCase(NUMERIC_INPUT)) {
                fragment = createTextFieldFragment(frmdtl, NUMERIC_TYPE);
            } else if (frmdtl.getFieldType().equalsIgnoreCase(CHECK_BOX)) {
                fragment = createCheckBoxFragment(frmdtl);
            } else if (frmdtl.getFieldType().equalsIgnoreCase(RADIO_BUTTON)) {
                fragment = createRadioButtonFragment(frmdtl);
            } else if (frmdtl.getFieldType().equalsIgnoreCase(VIDEO_VIEW)) {
                fragment = createVideoViewFragment(frmdtl);
            } else if (frmdtl.getFieldType().equalsIgnoreCase(IMAGE_VIEW)) {
                fragment = createImageViewFragment(frmdtl);
            }

            if (fragment != null) {
                IndexedFragments indexedFragments = new IndexedFragments();
                indexedFragments.setFragment(fragment);
                indexedFragments.setIndex(frmdtl.getIndex());
                fragmentList.add(indexedFragments);
            }
        }
        viewPager = findViewById(R.id.fragment_view_pager);
        orderDetailsAdapter = new OrderDetailsAdapter(getSupportFragmentManager(), fragmentList);
        viewPager.setAdapter(orderDetailsAdapter);
        viewPager.setOffscreenPageLimit(0);
    }

    private Fragment createTextFieldFragment(Frmdtl formData, String inputType) {
        FormEditTextFragment formEditTextFragment = new FormEditTextFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable(FORM_DATA, formData);
        bundle.putString(INPUT_TYPE, inputType);
        formEditTextFragment.setArguments(bundle);
        log.debug("Form Data Id for text {}", formData.getId());
        return formEditTextFragment;
    }

    private Fragment createCheckBoxFragment(Frmdtl formData) {
        FormCheckBoxFragment formCheckBoxFragment = new FormCheckBoxFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable(FORM_DATA, formData);
        formCheckBoxFragment.setArguments(bundle);
        log.debug("Form Data Id for check {}", formData.getId());
        return formCheckBoxFragment;
    }

    private Fragment createRadioButtonFragment(Frmdtl frmdtl) {
        FormRadioButtonFragment formRadioButtonFragment = new FormRadioButtonFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable(FORM_DATA, frmdtl);
        bundle.putSerializable(ORDER_DETAILS, formData.getOrderDetails());
        formRadioButtonFragment.setArguments(bundle);
        log.debug("Form Data Id for radio {}", frmdtl.getId());
        return formRadioButtonFragment;
    }

    private Fragment createVideoViewFragment(Frmdtl formData) {
        FormVideoFragment formVideoFragment = new FormVideoFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable(FORM_DATA, formData);
        formVideoFragment.setArguments(bundle);
        log.debug("Form Data Id for video {}", formData.getId());
        return formVideoFragment;
    }

    private Fragment createImageViewFragment(Frmdtl formData) {
        FormImageFragment formImageFragment = new FormImageFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable(FORM_DATA, formData);
        formImageFragment.setArguments(bundle);
        log.debug("Form Data Id for image {}", formData.getId());
        return formImageFragment;
    }

    private void navigateBetweenFragments(int navigation, List<String> stringList, Integer currentIndex) {
        if (navigation == NEXT_NAVIGATION) {

            if (stringList != null && !stringList.isEmpty() && currentIndex != null) {
                processLogicBasedFragments(stringList, currentIndex);
                viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
                return;
            }

            if (viewPager.getCurrentItem() == fragmentList.size() - 1) {
                log.debug("FormData list size {}", formDataList.size());
                log.debug("Moving to {} form", viewPager.getCurrentItem() + 1);
                submitButton.setVisibility(View.VISIBLE);
                submitButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        progressBar.setVisibility(View.VISIBLE);
                        attemptFormUpload();
                    }
                });
            } else {
                viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
            }
        }
        if (navigation == PREVIOUS_NAVIGATION) {
            viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
        }
    }

    private void processLogicBasedFragments(List<String> stringList, Integer currentIndex) {

        List<IndexedFragments> indexedFragmentsList = new ArrayList<>();

        for (int i = 0; i < fragmentList.size(); i++) {
            Integer index = fragmentList.get(i).getIndex();
            if (index.compareTo(currentIndex) <= 0) {
                indexedFragmentsList.add(fragmentList.get(i));
            }
        }

        for (int i = 0; i < fragmentList.size(); i++) {
            IndexedFragments indexedFragments = fragmentList.get(i);
            if (stringList.contains(String.valueOf(indexedFragments.getIndex()))) {
                indexedFragmentsList.add(indexedFragments);
            } else if (!stringList.contains(String.valueOf(indexedFragments.getIndex()))
                    && fragmentList.get(i).getIndex().compareTo(currentIndex) > 0) {
                indexedFragments.setSkippedRequested(true);
                indexedFragmentsList.add(indexedFragments);
            }
        }

        fragmentList.clear();
        log.debug("Fragment List Forms Activity after clearing {} on {}", fragmentList.size(), fragmentList);
        fragmentList.addAll(indexedFragmentsList);
        log.debug("Fragment List Forms Activity after adding indexed fragments {} on {}", fragmentList.size(), fragmentList);

        orderDetailsAdapter.updateList(indexedFragmentsList);
    }

    private void attemptFormUpload() {
        try {
            if (appUtils.isNetworkConnected(context)) {
                uploadForm();
            } else {
                preserveFormDataForFutureUpload();
                Toast.makeText(context, R.string.no_connection, Toast.LENGTH_LONG).show();
                progressBar.setVisibility(GONE);
                finish();
            }
        } catch (IOException e) {
            log.error("Error in attempting to upload form {}", e.fillInStackTrace());
        }
    }

    private void uploadForm() throws UnsupportedEncodingException {
        restRequests.uploadForm(formData.getOrderDetails().getId(),
                String.valueOf(formData.getOrderDetails().getFormId()),
                formData.getOrderDetails().getLatitude(),
                formData.getOrderDetails().getLongitude(),
                appUtils.getFormAnswersList(), new RestRequestListener() {
                    @Override
                    public void onSuccessResponse(String response) {
                        appUtils.getFormAnswersList().clear();
                        progressBar.setVisibility(GONE);
                        finish();
                    }

                    @Override
                    public void onErrorResponse(Throwable t) {
                        appUtils.getFormAnswersList().clear();
                        progressBar.setVisibility(GONE);
                        finish();
                    }
                });
    }

    private void preserveFormDataForFutureUpload() throws IOException {
        OfflineSubmittedOrder offlineSubmittedOrder = new OfflineSubmittedOrder();
        List<FormAnswers> formAnswers = new ArrayList<>(appUtils.getFormAnswersList());
        offlineSubmittedOrder.setFormAnswersList(formAnswers);
        offlineSubmittedOrder.setOrderDetail(formData.getOrderDetails());
        appUtils.getFormAnswersList().clear();
        appUtils.getOfflineSubmittedOrders().add(offlineSubmittedOrder);
        appUtils.writeObject(getApplicationContext(), FORM_ANSWER_LIST_CACHE, appUtils.getOfflineSubmittedOrders());
        appUtils.setSubmissionPending(true);
    }

    @Override
    public void onFragmentNavigationTriggered(int navigation, List<String> stringList, Integer currentIndex) {
        navigateBetweenFragments(navigation, stringList, currentIndex);
    }

    @Subcomponent
    public interface FormsActivitySubcomponent extends AndroidInjector<FormsActivity> {

        @SuppressWarnings({"InnerClassTooDeeplyNested", "ClassNameSameAsAncestorName"})
        @Subcomponent.Builder
        abstract class Builder extends AndroidInjector.Builder<FormsActivity> {
        }
    }

    @SuppressWarnings("InterfaceNeverImplemented")
    @Module(subcomponents = FormsActivity.FormsActivitySubcomponent.class)
    public interface FormsActivityModule {

        @Binds
        @IntoMap
        @ActivityKey(FormsActivity.class)
        AndroidInjector.Factory<? extends Activity>
        bindFormsActivityInjectorFactory(FormsActivity.FormsActivitySubcomponent.Builder builder);
    }
}
...