Question

I've got an activity that implements ActionBar.TabListener to provide 3 tabs for navigation. In one of the tabs I've introduced a RatingBar for rating of the element. Currently, changing the rating triggers a toast confirming the rating selected.

When rotating the orientation of the device, this toast is triggered again, even though the rating has not changed - I know I am probably redrawing the fragment for this tab (though in that case I do not understand why the rating persists) but I don't understand how to stop it. I tried to check the SavedInstanceState in OnCreateView but if I only apply the listener when it is not null, rotating the device removes the listener completely.

Activity onCreate

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_view_pub);

    Intent intent = getIntent();

    pubname = intent.getStringExtra(MainActivity.PUB);

    setTitle(pubname);

    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());

    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });

    // For each of the sections in the app, add a tab to the action bar.
    for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
        actionBar.addTab(actionBar.newTab()
                .setText(mSectionsPagerAdapter.getPageTitle(i))
                .setTabListener(this));
    }

    actionBar.setSelectedNavigationItem(1);
}

FragmentPAgerAdapter Class

public class SectionsPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return DirectionsFragment.newInstance(position + 1);
            case 1:
                return DetailsFragment.newInstance(position + 1);
            case 2:
                return RelationsFragment.newInstance(position + 1);
        }
        return null;            
    }

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

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return getString(R.string.title_section1);
            case 1:
                return getString(R.string.title_section2);
            case 2:
                return getString(R.string.title_section3);
        }
        return null;
    }
}

DetailsFragment Class

public static class DetailsFragment extends Fragment {

    private static final String ARG_SECTION_NUMBER = "section_number";

    public static DetailsFragment newInstance(int sectionNumber) {
        DetailsFragment fragment = new DetailsFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

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

        View rootView = inflater.inflate(R.layout.fragment_pub_details, container, false);
        RatingBar ratingBar = (RatingBar)rootView.findViewById(R.id.rating);
        ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener(){
            public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {

                Toast.makeText(ratingBar.getContext(),"Your Selected Ratings  : " + String.valueOf(rating),Toast.LENGTH_LONG).show();

            }
        });
        return rootView;

    }
}

What obvious trick have I missed?

Was it helpful?

Solution

OK, so I've altered the onRatingChanged function to only fire it's contents if the fromUser boolean is true - obviously when the system redraws the tab it's then not firing the toast;

ratingBar.setOnRatingBarChangeListener(new OnRatingBarChangeListener(){
    public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
        if(fromUser){
            Toast.makeText(ratingBar.getContext(),"Your Selected Ratings  : " + String.valueOf(rating),Toast.LENGTH_LONG).show();
        } 
    }
});

What I'm uncomfortable with is that I don't know if this is a hack, or if this is intended android process - my tabs are clearly being destroyed and rebuilt - is this for layout purposes or is my implementation flawed?

I'm struggling to understand best practice so please feel free to point out the 'right way' if this is not it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top