Nexus
Nexus

Reputation: 85

notifyDataSetChanged Method Takes Away Smooth Scrolling From Tabs

I am currently using Material Design in an Android app that I am making. In this app, I am using the Material Design tab layout to display some information that I am receiving. However when I tap the tabs, the animation is not smooth, and it is very abrupt. Sliding to go to the other tab, however is very smooth.

    mTabLayout = (TabLayout) findViewById(R.id.chem_tab_layout);
    mGenericAdapter = new GenericPagerAdapter(getSupportFragmentManager());
    mPager = (ViewPager) findViewById(R.id.view_pager);
    mPager.setAdapter(mGenericAdapter);

    //Notice how the Tab Layout links with the Pager Adapter
    mTabLayout.setTabsFromPagerAdapter(mGenericAdapter);

    //Notice how The Tab Layout and View Pager object are linked
    mTabLayout.setupWithViewPager(mPager);
    mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout){

        @Override
        public void onPageSelected(int position) {
            mGenericAdapter.notifyDataSetChanged();
        }

    });

That is my code for setting the adapter, etc.

This is my custom adapter code for the tabs:

class GenericPagerAdapter extends FragmentStatePagerAdapter {

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

@Override
public Fragment getItem(int position) {
    ChemGridActivity.MyFragment myFragment = new ChemGridActivity.MyFragment();
    return myFragment;
}

@Override
public int getCount() {
    return 3; //returns number of tabs that need to be created
}

@Override
public CharSequence getPageTitle(int position) {

    if (position == 0) return "Chemistry";
    if (position == 1) return "Mathematics";
    if (position == 2) return "Physics";

    else return null;
}

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

I feel that the choppy transition between tabs is caused by the overriden method onPageSelected method when I add onPageChangeListener. What do I add to this method to make tapping on tabs a smoother animation?

Upvotes: 1

Views: 787

Answers (1)

Nick Cardoso
Nick Cardoso

Reputation: 21753

Without knowing much about the internals of your classes, I imagine the problem is not that you have a listener, but what you are doing inside that listener.

In the case of most adapters notifyDataSetChanged() will cause it to re-render the entire view again (including all pages).

Seeing as you haven't specified what the intent here with the notification is, it's hard to tell you how you can do this in an alternative way, but you do need to do something less intensive if you want the animation to remain smooth.

I suspect you just want to change which fragment is shown, in which case just use the FragmentManager where necessary, remembering to reuse fragments which have already been seen once.

EDIT Based on additional info in comments

@Override
public Fragment getItem(int position) {
    //POSITION_SOMETHINHG would be one of a set of constants to indicate hwa to display
    return ChemGridActivity.MyFragment.newInstance(ChemGridActivity.MyFragment.POSITION_SOMETHINHG);
}

public class ChemGridActivity.MyFragment ... {

    private static final String KEY_DISPLAY_TYPE = "KEY_DISPLAY_TYPE";

    public static final int POSITION_SOMETHINHG = 11111;

    public static MyFragment newInstance(int display) {
        MyFragment f = new MyFragment();
        Bundle bund = new Bundle();
        bund.putInt(KEY_DISPLAY_TYPE, display);
        f.setArguments(bund);
        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        if (args != null) {
            mDisplay = args.getInt(KEY_DISPLAY_TYPE, 0);
        }
    }

    @Override
    public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.my_layout, container, false);
        //TODO: change something based on mDisplay 
        return view;
    }

Upvotes: 0

Related Questions