vital
vital

Reputation: 1348

Different titles for each fragment in my viewpager

I am using a viewpager "tabs + swipe" and I would like to set different titles in the actionBar for each fragment so that when I switch, title changes.

I tried several things without success, only the last title displays... and does not change anymore when I switch...

Upvotes: 14

Views: 14868

Answers (3)

Malek Libya
Malek Libya

Reputation: 11

@Override
        public void onPageSelected(int position) {
            tabHost.setSelectedNavigationItem(position);
            if (position == 0){
                setTitle(R.string.where_is_the_bus);
            }
            else if (position == 1){
                setTitle(R.string.bus_card);
            }
            else if (position == 2){
                setTitle(R.string.favo);
            }

You can make it like this "it's easy right?"

Upvotes: 1

mixel
mixel

Reputation: 25846

Though the question is a bit outdated I would suggest my solution. Scenario: tabs+swipe and every tab have fragment navigation stack. So action bar title can be changed not only through switching and swiping tabs but with navigation in every tab. To provide title per fragment I declared TitleProvider interface, so if fragment has custom title it must implement this interface.

public interface TitleProvider {
    CharSequence getTitle();
}

Below there is custom FragmentPagerAdapter, that handles switching, swiping, navigation and title update:

public class TabsAdapter extends FragmentPagerAdapter implements
        TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
    private final FragmentActivity activity;
    private final TabHost tabHost;
    private final ViewPager viewPager;
    private final ArrayList<Fragment> fragments = new ArrayList<Fragment>();
    private final Hashtable<Fragment, Stack<Class<?>>> fragmentBackstack = new Hashtable<Fragment, Stack<Class<?>>>();

    static class DummyTabFactory implements TabHost.TabContentFactory {
        private final Context context;

        public DummyTabFactory(Context context) {
            this.context = context;
        }

        @Override
        public View createTabContent(String tag) {
            View v = new View(context);
            v.setMinimumWidth(0);
            v.setMinimumHeight(0);
            return v;
        }
    }

    public TabsAdapter(FragmentActivity activity, TabHost tabHost,
                       ViewPager pager) {
        super(activity.getSupportFragmentManager());
        this.activity = activity;
        this.tabHost = tabHost;
        viewPager = pager;
        tabHost.setOnTabChangedListener(this);
        viewPager.setAdapter(this);
        viewPager.setOnPageChangeListener(this);
    }

    public void addTab(String tag, int drawableId, Fragment fragment,
                       int tabIndicatorId) {
        TabSpec tabSpec = tabHost.newTabSpec(tag);
        tabSpec.setContent(new DummyTabFactory(activity.getApplicationContext()));

        View tabIndicator = LayoutInflater.from(
                activity.getApplicationContext()).inflate(tabIndicatorId,
                tabHost.getTabWidget(), false);
        TextView title = (TextView) tabIndicator.findViewById(R.id.tab_title);

        if (fragment instanceof TitleProvider) {
            title.setText(((TitleProvider) fragment).getTitle());
        }

        ImageView icon = (ImageView) tabIndicator.findViewById(R.id.tab_icon);
        icon.setImageResource(drawableId);

        tabSpec.setIndicator(tabIndicator);

        fragments.add(fragment);
        tabHost.addTab(tabSpec);
        notifyDataSetChanged();
    }

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

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getItemPosition(Object object) {
        int returnCode;
        if (fragments.contains(object)) {
            returnCode = POSITION_UNCHANGED;
        } else {
            returnCode = POSITION_NONE;
        }
        return returnCode;
    }

    @Override
    public void onTabChanged(String tabId) {
        int position = tabHost.getCurrentTab();
        viewPager.setCurrentItem(position);
        updateTitle();
    }

    @Override
    public void onPageScrolled(int position, float positionOffset,
                               int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        // Unfortunately when TabHost changes the current tab, it kindly
        // also takes care of putting focus on it when not in touch mode.
        // The jerk.
        // This hack tries to prevent this from pulling focus out of our
        // ViewPager.
        TabWidget widget = tabHost.getTabWidget();
        int oldFocusability = widget.getDescendantFocusability();
        widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
        tabHost.setCurrentTab(position);
        widget.setDescendantFocusability(oldFocusability);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    public void navigate(Fragment fromFragment, Fragment toFragment) {
        startUpdate(viewPager);

        FragmentTransaction transaction = activity.getSupportFragmentManager()
                .beginTransaction();
        transaction.remove(fromFragment);
        transaction.commit();

        Stack<Class<?>> backstack;
        if (fragmentBackstack.containsKey(fromFragment)) {
            backstack = fragmentBackstack.get(fromFragment);
            fragmentBackstack.remove(fromFragment);
        } else {
            backstack = new Stack<Class<?>>();
        }
        backstack.push(fromFragment.getClass());
        fragmentBackstack.put(toFragment, backstack);

        fragments.set(fragments.indexOf(fromFragment), toFragment);
        finishUpdate(viewPager);
        notifyDataSetChanged();
        updateTitle();
    }

    public Boolean navigateBack() {
        startUpdate(viewPager);
        Fragment fromFragment = fragments.get(viewPager.getCurrentItem());

        if (!fragmentBackstack.containsKey(fromFragment))
            return false;
        Stack<Class<?>> backstack = fragmentBackstack.get(fromFragment);
        if (backstack.isEmpty())
            return false;

        fragmentBackstack.remove(fromFragment);
        Fragment toFragment = Fragment.instantiate(activity, backstack.pop()
                .getName());
        fragmentBackstack.put(toFragment, backstack);

        fragments.set(fragments.indexOf(fromFragment), toFragment);

        FragmentTransaction transaction = activity.getSupportFragmentManager()
                .beginTransaction();
        transaction.remove(fromFragment);
        transaction.commit();

        finishUpdate(viewPager);
        notifyDataSetChanged();
        updateTitle();
        return true;
    }

    protected Fragment getCurrentFragment() {
        return fragments.get(viewPager.getCurrentItem());
    }

    protected void updateTitle() {
        Fragment fragment = getCurrentFragment();
        if (fragment instanceof TitleProvider) {
            activity.setTitle(((TitleProvider) fragment).getTitle());
        }
    }
}

Upvotes: 3

UgglyNoodle
UgglyNoodle

Reputation: 3047

First, make your activity implement an OnPageChangeListener.

Then, when you create your ViewPager, you can use mViewPager.setOnPageChangeListener(this) so that your activity will receive callbacks when the page changes.

Finally, you need to implement the OnPageChangeListener callbacks. Your onPageSelected() method should be something like this:

@Override
public abstract void onPageSelected(int position) {
    setTitle(getTitleFromPosition(position));
}

The other two callbacks can be empty.

Upvotes: 31

Related Questions