i wrote a FragmentActivity with a ViewPager, i did not want to use the actionbar for the tabs (because i did not want the tabs to be positioned over the menu) and also not the PagerTabStrip solution, because i could not customize it as i wanted.
so i wrote an own linearlayout as tabs container:
<LinearLayout
android:id="@+id/main_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="horizontal" >
</LinearLayout>
with an View.OnClickListener for each of each tab
OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(final View view) {
mapTabs.get(lastSelectedTab).setSelected(false);
view.setSelected(true);
Runnable runnable = new Runnable() {
@Override
public void run() {
int index = Integer.parseInt(view.getTag().toString());
FragmentActivity.setTab(index);
lastSelectedTab = index;
}
};
handler.post(runnable);
}
};
}
public static void setTab(int index) {
FragmentActivity.viewPager.setCurrentItem(index, true); // true or false does not make any difference
}
this is the method i wrote to add the single tabs to the tab container (main_tabs):
private void addTab(LayoutInflater inflater, ViewGroup tabs, int imageId, View.OnClickListener onClickListener) {
inflater.inflate(R.layout.main_tab, tabs);
int index = tabs.getChildCount() - 1;
ImageView ivTab = (ImageView) tabs.getChildAt(index);
ivTab.setTag(String.valueOf(index)); // stored the tab index
ivTab.setImageResource(imageId);
ivTab.setOnClickListener(onClickListener);
mapTabs.put(index, ivTab); // add an imageview to the tab
}
i used the runnalbe so that i see the highlighting of the tab immediately, and not after the slight delay when the new page appears. i also stored the last selected tab in order to deselect it when the new one gets selected.
i store all tabs in a map in order to access them later for selection.
this is the OnPageChangeListener i wrote (to highlight the associated tab):
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
mapTabs.get(position).setSelected(true); // selected the tag asociated with the current visible page
mapTabs.get(lastSelectedTab).setSelected(false); // deselectes the last selected tab
lastSelectedTab = position;
ListFragment<?> item = FragmentActivity.fragmentAdapter.getItem(position);
setTitle(item.getTitle());
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
everything works fine, i am just not clear about the performance:
when i scroll to the next page, everything goes very fast and smooth. the next page appears immediately without any dealy; only the menu in the action bar (created in the onCreateOptionsMenu(Menu menu, MenuInflater inflater) method of each Fragment) appears with a slight delay (about 500-700 ms).
but when i click on one of the tabs, the selected page appears not immediately but with a slight delay (actually the same time the menu needs to appear as mentioned above: menu and page appear together at the same time). bzw. this happens also when i use the tabstrip solution.
i guess if its possible to achieve a delay-less page change by scrolling, it should be possible somehow to achieve the same performance for the tab clicks.
but what do i do wrong? and is there a possibility to make the menu appear immediately just like the pages when scrolling? can the different menus not be cached just like the pages?
the solution was extremely simple. i just had to keep all my 4 tabs in the ViewPager so that they don't need to get recreated (and therefore don't cause the short delay after each tab-clicki). i just had to add following lines to the onCreate method.
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setOffscreenPageLimit(4);