2

I have a FragmentActivity with different Fragments inside which can be switched through a NavigationDrawer.

Roman Nurik's original code was written with a FragmentActivity but I need it inside a Fragment...

This is my Activity (shortened):

public class MainActivity extends FragmentActivity implements
    PageFragmentCallbacks, ReviewFragment.Callbacks, ModelCallbacks {

// those are the methods I took from the sample
@Override
public void onPageTreeChanged() {
    mCurrentPageSequence = mWizardModel.getCurrentPageSequence();
    recalculateCutOffPage();
    mStepPagerStrip.setPageCount(mCurrentPageSequence.size() + 1); // + 1 =
                                                                    // review
                                                                    // step
    mPagerAdapter.notifyDataSetChanged();
    updateBottomBar();
}

private static void updateBottomBar() {
    int position = mPager.getCurrentItem();
    if (position == mCurrentPageSequence.size()) {
        mNextButton.setText(R.string.finish);
        mNextButton.setBackgroundResource(R.drawable.finish_background);
        mNextButton.setTextAppearance(myContext,
                R.style.TextAppearanceFinish);
    } else {
        mNextButton.setText(mEditingAfterReview ? R.string.review
                : R.string.next);
        mNextButton
                .setBackgroundResource(R.drawable.selectable_item_background);
        TypedValue v = new TypedValue();
        myContext.getTheme().resolveAttribute(
                android.R.attr.textAppearanceMedium, v, true);
        mNextButton.setTextAppearance(myContext, v.resourceId);
        mNextButton.setEnabled(position != mPagerAdapter.getCutOffPage());
    }

    mPrevButton
            .setVisibility(position <= 0 ? View.INVISIBLE : View.VISIBLE);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mWizardModel.unregisterListener(this);
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBundle("model", mWizardModel.save());
}

@Override
public AbstractWizardModel onGetModel() {
    return mWizardModel;
}

@Override
public void onEditScreenAfterReview(String key) {
    for (int i = mCurrentPageSequence.size() - 1; i >= 0; i--) {
        if (mCurrentPageSequence.get(i).getKey().equals(key)) {
            mConsumePageSelectedEvent = true;
            mEditingAfterReview = true;
            mPager.setCurrentItem(i);
            updateBottomBar();
            break;
        }
    }
}

@Override
public void onPageDataChanged(Page page) {
    if (page.isRequired()) {
        if (recalculateCutOffPage()) {
            mPagerAdapter.notifyDataSetChanged();
            updateBottomBar();
        }
    }
}

@Override
public Page onGetPage(String key) {
    return mWizardModel.findByKey(key);
}

private static boolean recalculateCutOffPage() {
    // Cut off the pager adapter at first required page that isn't completed
    int cutOffPage = mCurrentPageSequence.size() + 1;
    for (int i = 0; i < mCurrentPageSequence.size(); i++) {
        Page page = mCurrentPageSequence.get(i);
        if (page.isRequired() && !page.isCompleted()) {
            cutOffPage = i;
            break;
        }
    }

    if (mPagerAdapter.getCutOffPage() != cutOffPage) {
        mPagerAdapter.setCutOffPage(cutOffPage);
        return true;
    }

    return false;
}
}

This is my Fragment code:

public static class MyFragment extends Fragment {

    public MyFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main_dummy3,
                container, false);

        if (savedInstanceState != null) {
            mWizardModel.load(savedInstanceState.getBundle("model"));
        }

        mWizardModel.registerListener(this);

        mPagerAdapter = new MyPagerAdapter(fragmentManager1);
        mPager = (ViewPager) rootView.findViewById(R.id.pager);
        mPager.setAdapter(mPagerAdapter);
        mStepPagerStrip = (StepPagerStrip) rootView
                .findViewById(R.id.strip);
        mStepPagerStrip
                .setOnPageSelectedListener(new StepPagerStrip.OnPageSelectedListener() {
                    @Override
                    public void onPageStripSelected(int position) {
                        position = Math.min(mPagerAdapter.getCount() - 1,
                                position);
                        if (mPager.getCurrentItem() != position) {
                            mPager.setCurrentItem(position);
                        }
                    }
                });

        mNextButton = (Button) rootView.findViewById(R.id.next_button);
        mPrevButton = (Button) rootView.findViewById(R.id.prev_button);

        mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                mStepPagerStrip.setCurrentPage(position);

                if (mConsumePageSelectedEvent) {
                    mConsumePageSelectedEvent = false;
                    return;
                }

                mEditingAfterReview = false;
                updateBottomBar();
            }
        });

        mNextButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mPager.getCurrentItem() == mCurrentPageSequence.size()) {
                    DialogFragment dg = new DialogFragment() {
                        @Override
                        public Dialog onCreateDialog(
                                Bundle savedInstanceState) {
                            return new AlertDialog.Builder(getActivity())
                                    .setMessage(
                                            R.string.submit_confirm_message)
                                    .setPositiveButton(
                                            R.string.submit_confirm_button,
                                            null)
                                    .setNegativeButton(
                                            android.R.string.cancel, null)
                                    .create();
                        }
                    };
                    dg.show(fragmentManager1, "place_order_dialog");
                } else {
                    if (mEditingAfterReview) {
                        mPager.setCurrentItem(mPagerAdapter.getCount() - 1);
                    } else {
                        mPager.setCurrentItem(mPager.getCurrentItem() + 1);
                    }
                }
            }
        });

        mPrevButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mPager.setCurrentItem(mPager.getCurrentItem() - 1);
            }
        });

        onPageTreeChanged();
        updateBottomBar();

        return rootView;
    }

    public class MyPagerAdapter extends FragmentStatePagerAdapter {
        private int mCutOffPage;
        private Fragment mPrimaryItem;

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int i) {
            if (i >= mCurrentPageSequence.size()) {
                return new ReviewFragment();
            }

            return mCurrentPageSequence.get(i).createFragment();
        }

        @Override
        public int getItemPosition(Object object) {
            if (object == mPrimaryItem) {
                return POSITION_UNCHANGED;
            }

            return POSITION_NONE;
        }

        @Override
        public void setPrimaryItem(ViewGroup container, int position,
                Object object) {
            super.setPrimaryItem(container, position, object);
            mPrimaryItem = (Fragment) object;
        }

        @Override
        public int getCount() {
            return 6;
            // return Math.min(mCutOffPage + 1,
            // mCurrentPageSequence.size() + 1);
        }

        public void setCutOffPage(int cutOffPage) {
            if (cutOffPage < 0) {
                cutOffPage = Integer.MAX_VALUE;
            }
            mCutOffPage = cutOffPage;
        }

        public int getCutOffPage() {
            return mCutOffPage;
        }
    }
}

I get the following errors: The method registerListener(ModelCallbacks) in the type AbstractWizardModel is not applicable for the arguments (MainActivity.MyFragment)

and: Cannot make a static reference to the non-static method onPageTreeChanged() from the type MainActivity

What can I do to fix those errors?

user754730
  • 1,341
  • 5
  • 31
  • 62

2 Answers2

0

Try changing:

registerListener(this)

for

registerListener(getActivity())

The other error, as you can read from the message, your fragment is static and you are calling onPageTreeChanged() that is in the MainActivity, which is not static. You could keep a reference to the MainActivity this way:

First in your Fragment declare a variable of type ModelCallbacks:

ModelCallbacks mModelCallback;

Then, override the Fragment's onAttach method, and set the reference:

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);

try {
    mModelCallback = (ModelCallbacks)activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
            + " must implement ModelCallbacks");
    }
}

Finally, instead of calling directly onPageTreeChanged() from the fragment, change the line for:

mModelCallback.onPageTreeChanged();

That should solve your errors.

Dr NotSoKind
  • 225
  • 1
  • 5
  • 14
  • Are you aware of how to implement the callbacks inside of the fragment itself? It seems to expect the callbacks to be implemented inside of the activity, not the fragment. Thanks anyways! – Ernani Joppert Dec 19 '14 at 05:48
0

This is most likely too late a response. But in case someone else falls victim of a similar issue:

Your fragment doesn't seem to implement the necessary callbacks. That explains the case where it wasn't applicable to the registerListener method. You should implement these PageFragmentCallbacks, ReviewFragment.Callbacks, ModelCallbacks callbacks. Particularly, registerListener(ModelCallbacks) requires that whatever parameter you supply (your fragment in this case) implements the ModelCallbacks interface

Kingsley Adio
  • 728
  • 5
  • 16