stepstone-tech / android-material-stepper

This library allows to use Material steppers inside Android applications.
Apache License 2.0
1.78k stars 261 forks source link

java.lang.UnsupportedOperationException: Required method instantiateItem was not overridden #158

Closed bohoffi closed 7 years ago

bohoffi commented 7 years ago

Make sure these boxes are checked before submitting your issue - thank you!

Using your library I got the mentioned exception but there were no instructions to override the mentioned method.

Include the following:

Steps to reproduce

Implementation:

public class BookUpdateWizardDialog
        extends BaseDialogFragment
        implements StepperLayout.StepperListener {

    @BindView(R.id.wizard)
    StepperLayout mStepper;

    public static BookUpdateWizardDialog newInstance() {
        return new BookUpdateWizardDialog();
    }

    @Override
    protected int layoutId() {
        return R.layout.dialog_book_update_wizard;
    }

    @Override
    protected void prepareView(View view) {
        super.prepareView(view);

        mStepper.setListener(this);
        mStepper.setAdapter(new WizardAdapter(getActivity()));
    }

    @Override
    public void onCompleted(View completeButton) {
        Toast.makeText(getActivity(), "onCompleted!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError(VerificationError verificationError) {
        Toast.makeText(getActivity(), "onError! -> " + verificationError.getErrorMessage(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onStepSelected(int newStepPosition) {
        Toast.makeText(getActivity(), "onStepSelected! -> " + newStepPosition, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onReturn() {
        dismiss();
    }

    private static abstract class BaseWizardStepFragment extends Fragment implements Step {

        private Unbinder mUnbinder;

        @LayoutRes
        protected abstract int layoutId();

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {

            View view = inflater.inflate(layoutId(), container, false);
            this.mUnbinder = ButterKnife.bind(this, view);

            this.prepareView(view);

            return view;
        }

        protected void prepareView(View view) {

        }

        @Override
        public void onDestroyView() {
            super.onDestroyView();
            mUnbinder.unbind();
        }
    }

    public static class WizardProviderStepFragment extends BaseWizardStepFragment {

        public static WizardProviderStepFragment newInstance() {
            return new WizardProviderStepFragment();
        }

        @Override
        protected int layoutId() {
            return R.layout.wizard_step_provider;
        }

        @Override
        public VerificationError verifyStep() {
            //return null if the user can go to the next step, create a new VerificationError instance otherwise
            return null;
        }

        @Override
        public void onSelected() {

        }

        @Override
        public void onError(@NonNull VerificationError error) {

        }
    }

    private static class WizardAdapter extends AbstractStepAdapter {

        private static final SparseArray<BaseWizardStepFragment> steps;

        static {
            steps = new SparseArray<>();
            steps.put(0, WizardProviderStepFragment.newInstance());
        }

        WizardAdapter(@NonNull Context context) {
            super(context);
        }

        @Override
        public Step createStep(int position) {
            return steps.get(position);
        }

        @Override
        public Step findStep(int position) {
            return steps.get(position);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            return super.instantiateItem(container, position);
        }

        @Override
        public int getCount() {
            return steps.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return false;
        }
    }
}

Reproduction

Stacktrace

java.lang.UnsupportedOperationException: Required method instantiateItem was not overridden
  at android.support.v4.view.PagerAdapter.instantiateItem(PagerAdapter.java:178)
  at android.support.v4.view.PagerAdapter.instantiateItem(PagerAdapter.java:111)
  at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1002)
  at android.support.v4.view.ViewPager.populate(ViewPager.java:1150)
  at android.support.v4.view.ViewPager.populate(ViewPager.java:1084)
  at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
  at android.view.View.measure(View.java:21783)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6549)
  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
  at android.view.View.measure(View.java:21783)
  at android.widget.LinearLayout.measureVertical(LinearLayout.java:958)
  at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
  at android.view.View.measure(View.java:21783)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6549)
  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
  at android.view.View.measure(View.java:21783)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6549)
  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
  at android.view.View.measure(View.java:21783)
  at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6549)
  at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
  at com.android.internal.policy.DecorView.onMeasure(DecorView.java:699)
  at android.view.View.measure(View.java:21783)
  at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2409)
  at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1497)
  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1750)
  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1385)
  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6722)
  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:886)
  at android.view.Choreographer.doCallbacks(Choreographer.java:698)
  at android.view.Choreographer.doFrame(Choreographer.java:633)
  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:872)
  at android.os.Handler.handleCallback(Handler.java:769)
  at android.os.Handler.dispatchMessage(Handler.java:98)
  at android.os.Looper.loop(Looper.java:164)
  at android.app.ActivityThread.main(ActivityThread.java:6540)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Expected behaviour

zawadz88 commented 7 years ago

Hi @bohoffi, I think the issue here is that you're not extending a fragment adapter. Please see https://github.com/stepstone-tech/android-material-stepper/blob/master/README.md#extend-abstractfragmentstepadapter AbstractFragmentStepAdapter should be used if your steps are also Fragments

bohoffi commented 7 years ago

Ok, was my fault. It seems I just overread Fragment in the adapter class' name ...