I have implemented tab layout in android.I have 3 tabs-settings, clock, lost devices. While scrolling, the contents of tab get updated, but not the headings.But if I chose any tab heading, the content get displayed.
When I start the app, it shows 3 tabs. Suppose current highlighted tab is clock. When I scroll right, the contents of settings tab is displayed, but the current highlighted tab is still clock. It should be settings as per my need.
my code is
This is the main activity->
public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener{
//This is our tablayout
private TabLayout tabLayout;
//This is our viewPager
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Adding toolbar to the activity
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing the tablayout
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
//Adding the tabs using addTab() method
tabLayout.addTab(tabLayout.newTab().setText("clock"));
tabLayout.addTab(tabLayout.newTab().setText("settings"));
tabLayout.addTab(tabLayout.newTab().setText("lost devices"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
//Initializing viewPager
viewPager = (ViewPager) findViewById(R.id.pager);
//Creating our pager adapter
Pager adapter = new Pager(getSupportFragmentManager(), tabLayout.getTabCount());
//Adding adapter to pager
viewPager.setAdapter(adapter);
//Adding onTabSelectedListener to swipe views
tabLayout.setOnTabSelectedListener(this);
}
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
}
Pager->
public class Pager extends FragmentStatePagerAdapter {
//integer to count number of tabs
int tabCount;
//Constructor to the class
public Pager(FragmentManager fm, int tabCount) {
super(fm);
//Initializing tab count
this.tabCount= tabCount;
}
//Overriding method getItem
#Override
public Fragment getItem(int position) {
//Returning the current tabs
switch (position) {
case 0:
clock tab1 = new clock();
return tab1;
case 1:
settings tab2 = new settings();
return tab2;
case 2:
map tab3 = new map();
return tab3;
default:
return null;
}
}
//Overriden method getCount to get the number of tabs
#Override
public int getCount() {
return tabCount;
}
}
It is due to TabLayout and ViewPager is separate each other. You need to update their status in case of one of them make change. You have done with update ViewPager status when tab is selected. But vice versa you need to update Tablayout when ViewPager scroll.
Add listener for viewPager: viewPager.addOnPageChangeListener(this);. It will require you implement some methods.
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// don't use in that's case
}
#Override
public void onPageSelected(int position) {
// update Tablayout here
TabLayout.Tab tab = tabLayout.getTabAt(position);
if (tab != null) {
tab.select();
}
}
#Override
public void onPageScrollStateChanged(int state) {
// don't use in that's case
}
Don't forget to remove the listener if no longer use it
viewPager.removeOnPageChangeListener(this);
Hope it help !
you have setup your viewpager with tab layout. add this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
.....
......
....
//Adding adapter to pager
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
//Adding onTabSelectedListener to swipe views
tabLayout.setOnTabSelectedListener(this);
}
Related
I am having trouble with below code, i have 5 tabs in my application and when i am trying to switch through them i just noticed that onCreateView is called multiple times. Now first i did saw multiple post about similar issue where multiple times onCreateView is called, but mine is lit bit different, in my application onCreateView is called based on number of tabs i am switching. For example if i am DOWNLOAD tab and i switch to FAVORITE, onCreateView will be called 3 times. If i do same action from settings it will be called 4 times. Same thing happens with CANDIDATE and other tab.
Similar Posts -
1 - OnCreateView called multiple times / Working with ActionBar and Fragments
2 - Android fragment OnCreateView called twice
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private Boolean exit = false;
private static final int REQUEST = 112;
private Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
TextView mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
setSupportActionBar(toolbar);
mTitle.setText(toolbar.getTitle());
getSupportActionBar().setDisplayShowTitleEnabled(false);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
mContext = MainActivity.this;
setupTabIcons();
}
#Override
protected void onResume()
{
super.onResume();
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(getResources().getDrawable(R.drawable.settings));
tabLayout.getTabAt(1).setIcon(getResources().getDrawable(R.drawable.download));
tabLayout.getTabAt(2).setIcon(getResources().getDrawable(R.drawable.register));
tabLayout.getTabAt(3).setIcon(getResources().getDrawable(R.drawable.profile));
tabLayout.getTabAt(4).setIcon(getResources().getDrawable(R.drawable.favwhite));
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new SettingsFragment(), getResources().getString(R.string.settings_tab));
adapter.addFragment(new DownloadFragment(), getResources().getString(R.string.download_tab));
adapter.addFragment(new RegisterFragment(), getResources().getString(R.string.register_tab));
adapter.addFragment(new ProfileFragment(), getResources().getString(R.string.profile_tab));
adapter.addFragment(new ProfileFragment(), getResources().getString(R.string.favorites_tab));
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(0);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
Update -
To add more when it is run 4 times the data on screen is 4 times which is duplicate.
Fragement Code -
public class RegisterFragment extends Fragment{
public RegisterFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_register, container, false);
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
getFragmentManager().beginTransaction().detach(this).attach(this).commit();
}
}
}
By default view pager load the fragment in the following order.
Currently selected position fragment. Visible
Cache for the (selected position - 1) fragment, if any. Not visible
Cache for the (selected position + 1) fragment, if any. Not visible
Reason for this is, to make smooth animation from one fragment to another without lagging, view pager caches the previous and the next fragment. To confirm this log the position in the getItem() method in the view pager adapter.
As a result of above. When launching activity your viewpager is loading position 0 and 1. ie loading 2 fragment. There is no fragment in -1 position.
In bottom navigation with three tabs (Home, Dashboard, Notifications). Each bottom navigation tab is a fragment. The first tab ie. Home fragment contains another top navigation tabs having four tabs (Tab 1, Tab 2, Tab 3, Tab 4).
The problem
When navigate from Home tab to Notifications tab directly and come back to Home tab, Tab1/which ever tab previously selected tab (top navigation tabs) the content of the tab is not loaded.
When swipe the tabs from Tab 1 (Home fragment tab) all the way to Notification tab and swipe back, on reaching the Tab 4 the content of the tab is not loaded and on first swipe from Tab 4 to Tab 3 the swipe does not take to Tab 3. The tab indicator just move a little and on second swipe it goes to Tab 3 as expected.
The app contains a lot of code so I'll just link the full code to Github.
For quick reference here are my codes
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
NavigationView navigationView;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
viewPager.setCurrentItem(0);
return true;
case R.id.navigation_dashboard:
viewPager.setCurrentItem(1);
return true;
case R.id.navigation_notifications:
viewPager.setCurrentItem(2);
return true;
}
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Hide the activity toolbar
getSupportActionBar().hide();
//Initializing viewPager
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
final BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
switch (position){
case 0:
navigation.setSelectedItemId(R.id.navigation_home);
break;
case 1:
navigation.setSelectedItemId(R.id.navigation_dashboard);
break;
case 2:
navigation.setSelectedItemId(R.id.navigation_notifications);
break;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void setupViewPager(ViewPager viewPager) {
BottomNavPagerAdapter adapter = new BottomNavPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FirstFragment());
adapter.addFragment(new SecondFragment());
adapter.addFragment(new ThirdFragment());
viewPager.setAdapter(adapter);
}
}
FirstFragment.java (Home)
public class FirstFragment extends Fragment {
private TabLayout tabLayout;
private ViewPager firstViewPager;
public FirstFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_first, container, false);
firstViewPager = (ViewPager) rootView.findViewById(R.id.viewpager_content);
tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(firstViewPager);
setupViewPager(firstViewPager);
return rootView;
}
private void setupViewPager(ViewPager viewPager) {
TabViewPagerAdapter adapter = new TabViewPagerAdapter(getActivity().getSupportFragmentManager());
adapter.addFragment(new Tab1Fragment(), "Tab 1");
adapter.addFragment(new Tab1Fragment(), "Tab 2");
adapter.addFragment(new Tab1Fragment(), "Tab 3");
adapter.addFragment(new Tab1Fragment(), "Tab 4");
viewPager.setAdapter(adapter);
}
}
Questions
What's wrong in code ?
How to solve this issues? (The layout is a requirement) or is there any better approach to come up with the layout from the screenshot?
Actually, it is a common mistake - you're using FragmentManager of your Activity inside the fragment, but since this fragment contains another child fragments you have to use FragmentManager of the fragment itself. So the fix is simple - you just have to change getActivity().getSupportFragmentManager() to getChildFragmentManager() inside your fragments, so the code will be:
private void setupViewPager(ViewPager viewPager) {
TabViewPagerAdapter adapter = new TabViewPagerAdapter(getChildFragmentManager());
...
...
viewPager.setAdapter(adapter);
}
And this should work as expected.
Try use getChildFragmentManager() instance of getSupportFragmentManager().
So my app is in RTL, and with that, the tabs are now ordered from right to left..!
..But when I swipe to slide between the tabs, it contradicts the common sense, so I want to reverse it..! see the picture to see the problem..!
What I want is..! > when I'm in Tab1 and then I swipe from left to right I want it to slide to Tab 2 and so on..!
is that possible..!?
THE CODE
My Customer ViewPager
public class CustomViewPager extends android.support.v4.view.ViewPager{
private boolean enabled;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.enabled = true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onTouchEvent(event);
}
return false;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onInterceptTouchEvent(event);
}
return false;
}
public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
}
My TabActivity (Helper Class)
public class TabbedActivity extends BaseActivity {
//I extend BaseActivity to avoid repeating UI code like toolbar and stuff..
protected CustomViewPager viewPager;
public OrdersAdapter adapter;
public TabLayout tabs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tabs.setTabGravity(TabLayout.GRAVITY_FILL);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabs));
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
setTabSelected(tab);
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
public void setTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
public void addTab(int title) {
tabs.addTab(tabs.newTab().setText(getString(title)));
}
}
My Activity that contains the Tablayout and has three fragments, one for each tab.
public class MyOrders extends TabbedActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_orders);
tabs = (TabLayout) findViewById(R.id.tab_layout);
addTab(R.string.NewOrderTabTitle); //tab1
addTab(R.string.MyOrderTabTitle); // tab2
addTab(R.string.FinOrderTabTitle); //tab3
adapter = new OrdersAdapter(getSupportFragmentManager(), tabs.getTabCount());
viewPager = (CustomViewPager) findViewById(R.id.pager);
viewPager.setPagingEnabled(true);
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
super.onCreate(savedInstanceState);
}
}
Update
#regev avraham
adding the tabs in the reverse order, and then use
viewPager.setCurrentItem(adapter.getCount() - 1); to select the last
tab.
based on your comment, here's what I did in the Activity that has tablayout
//code...
tabs = (TabLayout) findViewById(R.id.tab_layout);
addTab(R.string.FinOrderTabTitle); //tab3
addTab(R.string.MyOrderTabTitle); // tab2
addTab(R.string.NewOrderTabTitle); //tab1
//code...
viewPager.setCurrentItem(adapter.getCount() - 1);
you can check this Lib
https://github.com/diego-gomez-olvera/RtlViewPager
and implement as below
dependencies {
...
compile 'com.booking:rtlviewpager:1.0.1'
}
just add this instead of Viewpager
<com.booking.rtlviewpager.RtlViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I kind of faced this problem developing a RTL app. Here's what to do:
Add tabs in reverse order :
tabLayout.addTab(tabLayout.newTab().setText("Tab2");
tabLayout.addTab(tabLayout.newTab().setText("Tab1");
Customize ViewPager Adapter to return Fragments in reverse order :
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment2 f2 = new Fragment2();
return f2;
case 1:
Fragment1 f1 = new Fragment1();
return f1;
default:
return null;
}
}
Select the last tab index at OnCreate :
TabLayout.Tab tab = tabLayout.getTabAt(1);
tab.select();
Set direction of TabLayout to LTR :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
tabLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
}
And finally your onTabSelected event should looks like this :
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
It works well.
This is a little tricky, the android viewPager from right to left has a little bug, only the page titles are from right to left and the pages themselves don't.
In order to fix this, what I did was using the regular left to right layout and adding the tabs in the reverse order, and then use viewPager.setCurrentItem(adapter.getCount() - 1); to select the last tab.
This is how the result should look like:
https://drive.google.com/open?id=0B0FzrLgjet7pSE9lMFFFT0JiekE
where size is the first tab, the display is the second and so on
To keep RTL behavior and the LTR behavior you should use this:
Configuration config = getResources().getConfiguration();
if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL)
{
//use the RTL trick here
}
else
{
//use the regular case here
}
If your minSdkVersion is 17+ you can do this to the tab layout:
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
Now, You can do it in efficient way with a similar widget (support RTL paging-swipe).
It will automatically change the swipe direction according to the system local or you can set it manually.
Android has developed a new widget named ViewPager2
ViewPager2 is an improved version of the ViewPager,it offers
enhanced functionality and addresses common difficulties with using
ViewPager.
You can follow these simple steps to create ViewPager2 integrated with TabLayout.
in layout_main.xml use this code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="#string/app_name">
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutDirection="locale"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Create adapter class with name PagerAdapter:
public class PagerAdapter extends FragmentStateAdapter {
public PagerAdapter(FragmentActivity fm) {
super(fm);
}
#NonNull
#Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return YourFragment1.newInstance();
case 1:
return YourFragment2.newInstance();
}
return null;
}
#Override
public int getItemCount() {
return 2;
}
}
In MainActivity (using view binding to get views from xml files):
public class MainActivity extends AppCompatActivity {
//Tabs titles
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2};
//Binding object
private ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Inflate layout
binding = ActivityMainBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
//Get TabLayout View
TabLayout tabs = binding.tabs;
//Get the viewPager View
ViewPager2 viewPager = binding.viewPager;
//Adapter for ViewPager
PagerAdapter pagerAdapter = new PagerAdapter(this);
//Set Adapter for ViewPager
viewPager.setAdapter(pagerAdapter);
//Integrate TabLayout with ViewPager
//i use it to get tabs titles
new TabLayoutMediator(tabs, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
//set the title for the tab at position index
tab.setText(getResources().getString(TAB_TITLES[position]));
}
}).attach();
}
}
These resources I have used (you can read for more details):
Create ViewPager2 from start : this link.
Migrate from ViewPager to ViewPager2 : this link.
I hope I helped with this.
The simplest way is using this one line of code :
tabLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
for RTL ordering of your tabs, you should do it in pager :
viewPager.setCurrentItem(adapter.getCount());
thanks to : arash-hatemi
You can set ViewPager rotationY to 180 degree and set rotationY of the child views on instantiateItem method to 180 degree.
Example:
ViewPager viewPager = new ViewPager(context);
viewPager.setRotationY(180F);
viewPagerMediaViewer.setAdapter(new PagerAdapter() {
#Override
public int getCount() {
return 0;
}
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View childView = inflater.inflate(R.layout.model_view_pager_item, container, false);
container.addView(currentView);
childView.setRotationY(180F);
return currentView;
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view == object;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((LinearLayout)object);
}
});
I have a simple FragmentView in my app and 3 tabs. All 3 tabs have RecyclerView, the problem is first two tabs are not that complex, while third tab uses some complex operations and slows down the app making it lag while it's doing those operations. My question is: How can I prevent FragmentView to call onCreateView until it's focused?
Right now the third tab starts doing those operations when second tab is focused. I want it to start doing those methods when third tab is focused.
This is my code:
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Tab1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
viewPager = (ViewPager) findViewById(R.id.pager);
adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
and this is my adapter:
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
public PagerAdapter(FragmentManager fm, int NumOfTabs) {
super(fm);
this.mNumOfTabs = NumOfTabs;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
RingtonesActivityFragment Ringtones = new RingtonesActivityFragment();
return Ringtones;
case 1:
FavoritesActivityFragment Favorites = new FavoritesActivityFragment();
return Favorites;
case 2:
MySongsActivityFragment Songs = new MySongsActivityFragment();
return Songs;
default:
return null;
}
}
#Override
public int getCount() {
return mNumOfTabs;
}
}
and Tabs:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.main, container, false);
...
...
...
return rootView;
}
ViewPager will load 1 page to either side of the current page by default. Even if you set setOffscreenPageLimit to less than 1, it'll reset itself to 1. There is no getting around this unless you modify the ViewPager class to your liking.
To help with lazily executing code you can use ViewPager.OnPageChangeListener and its method onPageSelected(int position) to find out which tab is currently in focus. You can then postpone the work required once the Fragment is in focus.
I'd also add that if you're doing work which causes lag in your UI, you might want to consider moving the work to a background thread. If the work is layout related and you can't do it on a background thread use Hierarchy Viewer or Systrace to help you optimize.
I have a static menu on the left side of my screen in my android application.Whenever I click an item from the left menu a fragment will appear along side it.
One of my items on the left menu is the course. In the course fragment contains a viewpager to watch read or listen to the course. You can navigate to one of these three options by side swipe or clicking the corresponding tab on the title bar. This all works fine.
However if I click another item on the left menu bar and navigate back to the course section, it messes up. The onCreateView() is invoked again and therefore adds the tabs to the title bar again and the viewpager. I tried removing all tabs in the onPause() method and removing all views in the viewpager. The tabs no longer be added again, but the pages on the screen are now blank.
Any help is much appreciated.
Here's the class which extends FragmentPagerAdapter
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Top Rated fragment activity
return new WatchCourseFrag();
case 1:
// Games fragment activity
return new ReadCourseFrag();
case 2:
// Movies fragment activity
return new ListenCourseFrag();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 3;
}
}
and here is the tab fragment class:
public class TabFrag2 extends Fragment implements ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Watch", "Read", "Listen" };
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.pager, container, false);
// Initilization
viewPager = (ViewPager) view.findViewById(R.id.pager);
actionBar = ((HomeScreenTablet) getActivity()).getSupportActionBar();
mAdapter = new TabsPagerAdapter(getFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
viewPager.setOffscreenPageLimit(3);
return view;
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// on tab selected
// show respected fragment view
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onPause() {
super.onPause();
viewPager.removeAllViews();
viewPager.removeAllViewsInLayout();
actionBar.removeAllTabs();
}
}
Found the answer:
Changed "TabsPagerAdapter extends FragmentPagerAdapter" to "TabsPagerAdapter extends FragmentStatePagerAdapter"