1

I have a ViewPager that contains several Fragments of which I generate and provide a unique layout to. These Fragments are merely placeholders for a static layout that the user is not supposed to interact with. (Similar to a preview page).

Here is the activity that contains the Fragments and the ViewPager:

public class KidPreviewActivity extends FragmentActivity implements IKidPreviewView, PreviewFragment.OnFragmentInteractionListener {

private KidPreviewPresenter mPresenter;
private ViewPager mPager;
private PreviewSlidePagerAdapter mPagerAdapter;
private static final int NUM_PAGES = 6;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_kid_preview);

    // hide navigation bar
    View decorView = getWindow().getDecorView();
    int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_FULLSCREEN;
    decorView.setSystemUiVisibility(uiOptions);


    Button returnToLauncherBtn = (Button) findViewById(R.id.kidPreviewReturnToLauncherBtn);
    EditText emailET = (EditText) findViewById(R.id.kidPreviewParentEmail);

    mPresenter = new KidPreviewPresenter(getApplicationContext());
    mPresenter.attachView(this);

    returnToLauncherBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mPresenter.backToLauncher();
        }
    });
    mPager = (ViewPager) findViewById(R.id.previewPager);
    mPagerAdapter = new PreviewSlidePagerAdapter(getSupportFragmentManager());
    mPager.setAdapter(mPagerAdapter);
    CircleIndicator indicator = (CircleIndicator) findViewById(R.id.cIndicator);
    indicator.setViewPager(mPager);

} //-onCreate

@Override
protected void onDestroy() {
    super.onDestroy();
    if (isFinishing()) {
        mPresenter.destroy();
    }
}


@Override
public void onError(Message msg) {
    Utils.DisplayError(this, msg);
}

@Override
public void onDisconnected() {
    ActivityHelper.handleDisconnected(this);
}


@Override
public void backToLauncher() {
    finish();
}

@Override
public void notifyParents() {

}

@Override
public void onFragmentInteraction(Uri uri) {

}

private class PreviewSlidePagerAdapter extends FragmentStatePagerAdapter {
    public PreviewSlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        PreviewFragment currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_one);
        switch (position) {
            case 0:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_one);
                break;
            case 1:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_two);
                break;
            case 2:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_three);
                break;
            case 3:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_four);
                break;
            case 4:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_five);
                break;
            case 5:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_six);
                break;
        }
        return currentFrag;
    }

    @Override
    public int getCount() {
        return NUM_PAGES;
    }
}

However when loading this activity, I get extremely slow on swiping/sliding the viewpager items.

With messages like:

 04-21 06:56:13.238 1897-1897/com.myApp.myAppDev I/Choreographer: Skipped 97 frames!  The application may be doing too much work on its main thread.
04-21 06:56:14.933 1897-2281/com.myApp.myAppDev E/OpenGLRenderer: GL error:  Out of memory!

Any way to fix this/optimize this so that it doesn't lock up the activity?

I am not sure why it's doing "too much work" on the main thread, as far as I can tell I am not doing much work on the main thread?

Fragment newInstance:

   public static PreviewFragment newInstance(int layoutSelected){
        PreviewFragment fragment = new PreviewFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_LAYOUT, layoutSelected);
        fragment.setArguments(args);
        return fragment;
    }

Other PreviewFragment methods:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        layoutSelected = getArguments().getInt(ARG_LAYOUT);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(layoutSelected, container, false);


}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}
Timothy Frisch
  • 2,995
  • 2
  • 30
  • 64

2 Answers2

0

It seems that you're creating fragments each time (in the getItem function). Instead, you want to create your adapter with a list of Fragments, store them in your adapter, and change the getItem to return the fragment from that list.

private class PreviewSlidePagerAdapter extends FragmentStatePagerAdapter {
  private List<Fragment>  mFragments;
  public PreviewSlidePagerAdapter(FragmentManager fm, List<Fragment> fragments) {
    super(fm);
    mFragments = fragments;
  }

  @Override
  public Fragment getItem(int position) {
    if (mFragments == null) {
      return (null);
    }
    return mFragments.get(position);
  }
}

And to create your adapter from your MainActivity :

List<Fragment> fragmentsList = new ArrayList<>();
fragmentsList.add(PreviewFragment.newInstance(R.layout.kid_preview_flipper_one));
            fragmentsList.add(PreviewFragment.newInstance(R.layout.kid_preview_flipper_two));
            fragmentsList.add(PreviewFragment.newInstance(R.layout.kid_preview_flipper_three));
            fragmentsList.add(PreviewFragment.newInstance(R.layout.kid_preview_flipper_four));
            fragmentsList.add(PreviewFragment.newInstance(R.layout.kid_preview_flipper_five));
            fragmentsList.add(PreviewFragment.newInstance(R.layout.kid_preview_flipper_six));
mPagerAdapter = new PreviewSlidePagerAdapter(getSupportFragmentManager(), fragmentsList);
mPager.setAdapter(mPagerAdapter);
NSimon
  • 5,212
  • 2
  • 22
  • 36
0

Try to change your adapter like this, it will save one call newInstance

    @Override
    public Fragment getItem(int position) {

        PreviewFragment currentFrag = null;
        switch (position) {
            case 1:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_two);
                break;
            case 2:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_three);
                break;
            case 3:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_four);
                break;
            case 4:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_five);
                break;
            case 5:
                currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_six);
                break;
            default:
               currentFrag = PreviewFragment.newInstance(R.layout.kid_preview_flipper_one);
        }
        return currentFrag;
    }

If you post your newInstance methods code, then it will be useful. I think they do many work in the UI thread

UPDATE

As @user3505534 say, try to change parent class from FragmentStatePagerAdapter to FragmentPagerAdapter

Kirill Shalnov
  • 2,216
  • 1
  • 19
  • 21