How to reverse viewpager swiping - android

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);
}
});

Related

How to update the value of tabs on scrolling

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);
}

Changing tabs of TabLayout programmatically but fragments of ViewPager is not updated

I am developing an Android app. In my app, I am using TabLayout with ViewPager. I need to update the Tabs of TabLayout and its fragments programmatically when an item at the bottom navigation bar is selected. I can update the tabs of TabLayout. But the fragments of pager are not updated.
This is the issue:
As you can see in the above, tabs are changed but its fragments are not changed. List Fragment is always displayed. All the fragments are just the same with the first tab selected. I mean fragments are not changing at all.
This is my XML file for the tabs and view pager:
<android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
android:layout_width="match_parent" android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.TabLayout
android:id="#+id/ma_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabMode="fixed" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:id="#+id/ma_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
This is my whole activity:
public class MainActivity extends AppCompatActivity {
private BottomBar bottomBar;
private TabLayout topTabLayout;
private ViewPager mainViewPager;
private MainPagerAdapter pagerAdapter;
private ArrayList<Fragment> pagerFragments;
private ArrayList<String> pagerTitleList;
protected TfrApplication app;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = (TfrApplication)getApplication();
setContentView(R.layout.activity_main);
initialize();
initViews();
setUpViews();
}
private void initialize()
{
pagerFragments = new ArrayList<Fragment>();
pagerTitleList = new ArrayList<String>();
}
private void initViews()
{
bottomBar = (BottomBar)findViewById(R.id.ma_bottom_action_bar);
mainViewPager = (ViewPager)findViewById(R.id.ma_viewpager);
topTabLayout = (TabLayout)findViewById(R.id.ma_tab_layout);
}
private void setUpViews()
{
pagerAdapter = new MainPagerAdapter(getSupportFragmentManager(),pagerFragments,pagerTitleList);
mainViewPager.setAdapter(pagerAdapter);
topTabLayout.setupWithViewPager(mainViewPager);
setUpBottomBar();
}
private void clearPagerFragments()
{
if(pagerAdapter!=null && pagerFragments!=null && pagerFragments.size()>0)
{
pagerFragments.removeAll(pagerFragments);
pagerTitleList.removeAll(pagerTitleList);
pagerAdapter.notifyDataSetChanged();
}
}
private void setUpNewsPagerFragments()
{
NewsFragment latestNewsFragment = new NewsFragment();
Bundle latestNewsBundle = new Bundle();
latestNewsBundle.putInt(NewsFragment.FIELD_CATEGORY_ID,0);
latestNewsBundle.putInt(NewsFragment.FIELD_LEAGUE_ID,0);
latestNewsBundle.putInt(NewsFragment.FIELD_COUNTRY_ID,0);
latestNewsBundle.putInt(NewsFragment.FIELD_TEAM_ID,0);
latestNewsFragment.setArguments(latestNewsBundle);
pagerTitleList.add("LATEST");
pagerFragments.add(latestNewsFragment);
PrioritizedTeamsFragment teamsFragment = new PrioritizedTeamsFragment();
pagerTitleList.add("TEAMS");
pagerFragments.add(teamsFragment);
NewsFragment articlesFragment = new NewsFragment();
Bundle articlesBundle = new Bundle();
articlesBundle.putInt(NewsFragment.FIELD_CATEGORY_ID, 0);
articlesBundle.putInt(NewsFragment.FIELD_LEAGUE_ID, 0);
articlesBundle.putInt(NewsFragment.FIELD_COUNTRY_ID, 0);
articlesBundle.putInt(NewsFragment.FIELD_TEAM_ID, 0);
articlesFragment.setArguments(articlesBundle);
pagerTitleList.add("ARTICLES");
pagerFragments.add(articlesFragment);
TopFragment topFragment = new TopFragment();
pagerTitleList.add("TOP 10");
pagerFragments.add(topFragment);
}
private void setUpMatchesPagerFragments()
{
MatchesFragment matchesFragment = new MatchesFragment();
pagerTitleList.add("MATCHES");
pagerFragments.add(matchesFragment);
StatisticsFragment statisticsFragment = new StatisticsFragment();
pagerTitleList.add("STATISTICS");
pagerFragments.add(statisticsFragment);
}
private void setUpBottomBar()
{
bottomBar.setOnTabSelectListener(new OnTabSelectListener() {
#Override
public void onTabSelected(int tabId) {
switch (tabId){
case R.id.bottom_tab_news:
clearPagerFragments();
setUpNewsPagerFragments();
pagerAdapter.notifyDataSetChanged();
break;
case R.id.bottom_tab_matches:
clearPagerFragments();
setUpMatchesPagerFragments();
pagerAdapter.notifyDataSetChanged();
topTabLayout.getTabAt(0).select();
break;
case R.id.bottom_tab_meme:
Toast.makeText(getBaseContext(),"MEME",Toast.LENGTH_SHORT).show();
break;
case R.id.bottom_tab_settings:
Toast.makeText(getBaseContext(),"Settings",Toast.LENGTH_SHORT).show();
break;
}
}
});
}
}
I showed the whole activity because code the whole activity dealing with that problem. Besides, the whole activity only contains code for creating tabs, view pager and bottom bar. All are connected.
This is my view pager adapter:
public class MainPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragmentList;
private ArrayList<String> titleList;
public MainPagerAdapter(FragmentManager fragmentManager,ArrayList<Fragment> fragmentsParam,ArrayList<String> titlesParam)
{
super(fragmentManager);
this.fragmentList = fragmentsParam;
this.titleList = titlesParam;
}
#Override
public int getCount() {
return fragmentList.size();
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public CharSequence getPageTitle(int position) {
return titleList.get(position);
}
}
Why is the content or fragments of view pager are not changed when tabs are changed? What is wrong with my code?
As you can see on bottom item selected listener I tried to set the selected fragment like this:
topTabLayout.getTabAt(0).select();
I tried this as well:
mainViewPager.setCurrentItem(0);
Both are not working.
try to add a method to swap the fragment-list and call notifyDataSetChanged() in your adapter like this:
public void notifyDataSetChanged(List<Fragment> list) {
fragmentList.removeAll();
fragmentList.addAll(list);
notifyDataSetChanged();
}
changing data in activity and call adapter.notifyDataSetChanged() may fail to update your view.You can log in getItem() to check if the adapter knows the data set has changed.
Just Check which layout you are inflating in MatchesFragment class.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.matches_fragment, container, false);
}
If your tab is set correctly, under the code where the tab is set, run this again:
mainViewPager.setAdapter(pagerAdapter);
Here is my code:
selectedTab = 0;
tabLayout.getTabAt(selectedTab).select();
viewPager.setAdapter(tabsAdapter);

access to xml of fragments in Tablayout

I created an app on AS and I use Tab Layout with View Pager, Fragment in it from this site!
and I want to access each fragment layout (I have 3 fragment) to apply some changes on them. I searched about it in the Internet but I could not find anything about it.
Without seeing any code or errors.. I'll try to give the best answer I can.. In the class you set up the tab layout you can create the page fragments like so:
public class TabLayoutActivity extends MainActivity{
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_layout);
ViewPager vp = (ViewPager) findViewById(R.id.view_pager);
this.addPages(vp);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(vp);
tabLayout.setOnTabSelectedListener(listener(vp));
}
//ADD ALL PAGES
private void addPages(ViewPager pager) {
MyFragPagerAdapter adapter = new MyFragPagerAdapter(getSupportFragmentManager());
Tab1Fragment tab1Fragment = new Tab1Fragment();
adapter.addPage(mondayFragment);
Tab2Fragment tab2Fragment = new Tab2Fragment();
adapter.addPage(tab2Fragment);
Tab3Fragment tab3Fragment = new Tab3Fragment();
adapter.addPage(tab3Fragment);
pager.setAdapter(adapter);
}
private TabLayout.OnTabSelectedListener listener(final ViewPager pager) {
return new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
};
}
}
You then create 3 classes, Tab1Fragment, Tab2Fragment, and Tab3Fragment, aswell as the xml layouts for each. Here is an example of one of the tab fragment classes:
public class Tab1Fragment extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tab1_fragment, null);
}
#Override
public String toString() {
return "Tab 1";
}
}
This is a very simple example to give you an idea. You can then change the xml layout in the corresponding fragment class. Let me know if you have any questions

Fragment Tabs not using all space

I'm trying to convert my activity app into a fragment following this tutorial :
http://www.exoguru.com/android/material-design/navigation/material-design-tabs-with-fragments
As I will use only two tabs, I have made this change to BlankFragment
public class BlankFragment extends Fragment {
private PagerSlidingTabStrip tabs;
private static ViewPager viewPager;
private final int int_items = 2;
public BlankFragment() { // Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View x = inflater.inflate(R.layout.fragment_blank, container, false);
tabs = (PagerSlidingTabStrip) x.findViewById(R.id.tab_strip);
viewPager = (ViewPager) x.findViewById(R.id.viewpager);
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
tabs.post(new Runnable() {
#Override
public void run() {
tabs.setViewPager(viewPager);
}
});
int[][] tabStates = new int[][] {
new int[] { android.R.attr.state_pressed}, // enabled
new int[] { android.R.attr.state_selected}, // unchecked
new int[] { -android.R.attr.state_selected}
};
int[] tabColors = new int[] {R.color.colorAccent,R.color.colorAccent,R.color.colorAccent};
ColorStateList tabList = new ColorStateList(tabStates, tabColors);
tabs.setTextColor(tabList); // Setting the Tab Text Color
return x;
}
public class MyAdapter extends FragmentPagerAdapter { // Tab Adapter
public MyAdapter(FragmentManager fm) { super(fm); }
#Override
public Fragment getItem(int position)
{
switch (position){
case 0 : return new Tab1();
case 1 : return new Tab2();
}
return null;
}
#Override
public int getCount() { return int_items; }
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "Temps ";
case 1 :
return "Vetement ";
}
return null;
}
}
}
The thing is that I get this result :
As you can see the tabs text is not using all the space like this :
https://raw.githubusercontent.com/joseedwin84/Android-Sliding-Tabs-With-Material-Design/master/tabpic.png
So what does I need to change ?
I tried to check layout and they are all set to match_parent width.
So now I don't know where to look.
If someone can help me, It would be great.
You have to set the tabGravity to fill and tabMode to fixed of your TabLayout.
Either in xml
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tabLayout"
app:tabGravity="fill"
app:tabMode="fixed" />
Or you can do it in java
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
Thanks I'm not using TabLayout but a PagerSlidingTabStrip, and with your answer I found in the documentation that it was a layout problem I should use app:shouldExpand="true"

Tablayout with icons only

I am using design support to create tabs. I am also using ViewPager for swipable tabs.
Now, I don't know how to use only icons instead of texts in tabs. I tried finding out but didn't get any success.
My code:
Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
setupViewPager(viewPager);
setupTablayout();
}
private void setupTablayout() {
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setupWithViewPager(viewPager);
}
class MyPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public MyPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
mFragmentTitleList.get(position)
}
}
private void setupViewPager(ViewPager viewPager) {
MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new frag(), "CAT");
adapter.addFrag(new frag(), "DOG");
adapter.addFrag(new frag(), "BIRD");
viewPager.setAdapter(adapter);
}
One approach is setting the icons after TabLayout.setupWithViewPager() method.
mTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
mTabLayout.getTabAt(i).setIcon(R.drawable.your_icon);
}
The tutorial shown in the following link should cover what you want. https://github.com/codepath/android_guides/wiki/Google-Play-Style-Tabs-using-TabLayout#add-icons-to-tablayout
I copied the relevant section below.
Add Icons to TabLayout
Currently, the TabLayout class does not provide a clean abstraction model that allows for icons in your tab. There are many posted workarounds, one of which is to return a SpannableString, containing your icon in an ImageSpan, from your PagerAdapter's getPageTitle(position) method as shown in the code snippet below:
private int[] imageResId = {
R.drawable.ic_one,
R.drawable.ic_two,
R.drawable.ic_three
};
// ...
#Override
public CharSequence getPageTitle(int position) {
// Generate title based on item position
// return tabTitles[position];
Drawable image = context.getResources().getDrawable(imageResId[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
SpannableString sb = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
By default, the tab created by TabLayout sets the textAllCaps property to be true, which prevents ImageSpans from being rendered. You can override this behavior by changing the tabTextAppearance property.
<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
<item name="tabTextAppearance">#style/MyCustomTextAppearance</item>
</style>
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
<item name="textAllCaps">false</item>
</style>
In new version of TabLayout, google added TabItem which easily can add Icon through your XML with following code:
<android.support.design.widget.TabLayout
app:tabTextColor="#color/gray"
app:tabMode="fixed"
app:tabBackground="#color/red"
app:tabIndicatorHeight="4dp"
app:tabIndicatorColor="#color/purple"
app:tabPadding="2dp"
app:tabSelectedTextColor="#color/white"
app:tabMinWidth="64dp"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<!--add height and width to TabItem -->
<android.support.design.widget.TabItem
android:text="#string/tab_text"/>
<android.support.design.widget.TabItem
android:icon="#drawable/ic_android"/>
</android.support.design.widget.TabLayout>
See more here.
try this
public class GlobalActivity extends AppCompatActivity {
Toolbar toolbar;
ViewPager viewPager;
TabLayout tabLayout;
ViewPagerAdapter adapter;
private int[] tabIcons = {
R.drawable.home_ic,
R.drawable.biz_ic,
R.drawable.network_ic,
R.drawable.offers_ic,
R.drawable.message_ic_b
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_global_hub);
tab();
}
public void tab(){
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tablayout);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
tabLayout.getTabAt(3).setIcon(tabIcons[3]);
tabLayout.getTabAt(4).setIcon(tabIcons[4]);
}
public void setupViewPager(ViewPager viewPager){
adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new GlHubFragment(),"HOME");
adapter.addFrag(new BizForumFragment(), "BIZ FORUM");
adapter.addFrag(new NetworkFragment(), "NETWORK");
adapter.addFrag(new MessagesFragment(), "MESSAGEs");
adapter.addFrag(new OfferFragmentActivity(), "OFFER");
viewPager.setAdapter(adapter);
}
public class ViewPagerAdapter extends FragmentPagerAdapter{
private final List<Fragment> mfragmentlist =new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return mfragmentlist.get(position);
}
#Override
public int getCount() {
return mfragmentlist.size();
}
public void addFrag(Fragment fragment,String title){
mfragmentlist.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position){
return mFragmentTitleList.get(position);
}
}
}
In TabLayout, setting icon is easy:
getPageTitle(position) should return null (if you don't want title to show).
Next :
tabLayout.getTabAt(0).setIcon(resId);
tabLayout.getTabAt(1).setIcon(resId);
......
None of these methods are elegant when using TabLayout as the ViewPager "decor" scenario. TabLayout Documentation Here is a simple extension of TabLayout and PagerAdapter that provides a simple drop in replacement for TabLayout that should be able to be used in either scenario without manually adding icons outside of the TabLayout class and following the usage of PagerAdapter to get the tab information.
/**
* Created by JDL on 1/18/2017.
*/
public class TabLayoutExt extends TabLayout {
protected ViewPager mViewPager;
public abstract static class TabLayoutViewPagerAdapter extends PagerAdapter {
public TabLayoutViewPagerAdapter() {
}
/**
* This method may be called by the TabLayout to obtain an icon drawable
* to for the specified tab. This method may return null
* indicating no tab icon for this page. The default implementation returns
* null.
*
* #param position The position of the title requested
* #return A drawable icon for the requested page
*/
public Drawable getPageIcon(Context context, int position) {
return null;
}
}
public TabLayoutExt(Context context) {
super(context);
}
public TabLayoutExt(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TabLayoutExt(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onAttachedToWindow() {
//Cover the implicit setup in TabLayout
if (mViewPager == null) {
final ViewParent vp = getParent();
if (vp instanceof ViewPager) {
mViewPager = (ViewPager)vp;
}
}
super.onAttachedToWindow();
}
public void addTab(#NonNull Tab tab, int position, boolean setSelected) {
if (mViewPager != null && mViewPager.getAdapter() instanceof TabLayoutViewPagerAdapter) {
Drawable icon = ((TabLayoutViewPagerAdapter) mViewPager.getAdapter()).getPageIcon(getContext(),position);
tab.setIcon(icon);
}
super.addTab(tab,position,setSelected);
}
#Override
public void setupWithViewPager(#Nullable ViewPager viewPager, boolean autoRefresh) {
mViewPager = viewPager;
super.setupWithViewPager(viewPager, autoRefresh);
}
}
So all that needs be done is extend TabLayoutViewPagerAdapter instead of PageAdapter and implement getPageIcon(Context,int) instead of or in addition to title. The drop in TabLayoutExt in your XML file, instead of the normal TabLayout. This could be extended for further modifying the tab, either with a custom view instead or something else.
With the TabLayout provided by the Material Components Library you can use:
the method setIcon to define the resourceId
the method setTabLabelVisibility to set the TAB_LABEL_VISIBILITY_UNLABELED.
Something like:
for (int i=0;i<tabLayout.getTabCount();i++){
tabLayout.getTabAt(i).setIcon(iconResId);
tabLayout.getTabAt(i).
setTabLabelVisibility(TabLayout.TAB_LABEL_VISIBILITY_UNLABELED);
}
The easiest way I've found to use icons is to use Tablayout.Tab.setIcon(drawable). This also makes it easy to highlight the selected icon. If you want to do this, follow these steps.
Step 1.
Add your images to the res.mipmap folders. (mipmap-mdpi, hdpi etc.) Judging by the other answers here it's also fine to put then in the res.drawable folders.
Step 2.
Call setIcon on all your tabs after setting up your TabLayout and ViewPager. I did this in my AdapterTabs to keep the Activity tidy.
So in your activity do this:
tablayout = (TabLayout) findViewById(R.id.tab_layout);
viewPager = (ViewPager) findViewById(R.id.viewPager);
adapterTabs = new AdapterTabs(this, getSupportFragmentManager(), fragments, tablayout, viewPager);
viewPager.setAdapter(adapterTabs);
tablayout.setupWithViewPager(viewPager);
adapterTabs.setTabIcons();
and in your AdapterTabs, which should extend FragmentPagerAdapter, put your setTabIcons() method.
public void setTabTitlesToIcons() {
Drawable icon1 = context.getResources().getDrawable(R.mipmap.ic_1);
Drawable icon2 = context.getResources().getDrawable(R.mipmap.ic_2);
Drawable icon3 = context.getResources().getDrawable(R.mipmap.ic_3);
Drawable icon1Hilighted = context.getResources().getDrawable(R.mipmap.ic_1_selected);
Drawable icon2Hilighted = context.getResources().getDrawable(R.mipmap.ic_2_selected);
Drawable icon3Hilighted = context.getResources().getDrawable(R.mipmap.ic_3_selected);
icons.add(icon1);
icons.add(icon2);
icons.add(icon3);
iconsHilighted.add(icon1Hilighted);
iconsHilighted.add(icon2Hilighted);
iconsHilighted.add(icon3Hilighted);
for(int i = 0; i < icons.size(); i++) {
if(i == 0) {
//noinspection ConstantConditions
tabLayout.getTabAt(i).setIcon(iconsSelected.get(i));
}
else {
//noinspection ConstantConditions
tabLayout.getTabAt(i).setIcon(icons.get(i));
}
}
}
Make sure to store a reference to the two lists 'icons' and 'iconsHilighted'. You'll need them later. Also store a reference to the TabLayout and the ViewPager which you passed in from the activity.
Step 3.
Make sure AdapterTabs.getPageTitle() returns null.
At this point, if you run it you should see that the first icon is highlighted.
Step 4.
Implement ViewPager.OnPageChangeListener in AdapterTabs and add that listener to your viewPager
public AdapterTabs(Context context, FragmentManager fragmentManager, List<Fragment> fragments, TabLayout tabLayout, ViewPager viewPager) {
super(fragmentManager);
this.context = context;
this.tabLayout = tabLayout;
this.viewPager = viewPager;
this.viewPager.addOnPageChangeListener(this);
tabs.add(fragments.get(0));
tabs.add(fragments.get(1));
tabs.add(fragments.get(2));
}
Step 5.
Update the icons in the tabs in the onPageSelected callback in your AdapterTabs.
#Override
public void onPageSelected(int position) {
for (int i = 0; i < tabs.size(); i++) {
if(i == position) {
//noinspection ConstantConditions
tabLayout.getTabAt(i).setIcon(iconsSelected.get(i));
}
else {
//noinspection ConstantConditions
tabLayout.getTabAt(i).setIcon(icons.get(i));
}
}
}
Now you should see the hilighted icon being updated when you change tabs.
Try this this will definitely work .
private TabLayout tabLayout;
private ViewPager viewPager;
private int[] tabIcons = {
R.drawable.single,
R.drawable.multiple};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact_picker);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Choose contact");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
tab();
}
public void tab(){
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Login());
adapter.addFragment(new Register());
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = 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) {
mFragmentList.add(fragment);
}
}
As mentioned in the comments, defining the icons in the TabLayout does not work when using a PagerAdapter. For those using Kotlin, one workaround is to create an extension function like this:
fun TabLayout.setupWithViewPagerAndKeepIcons(viewPager : ViewPager?) {
val icons = mutableListOf<Drawable?>()
repeat(tabCount) {
icons.add(getTabAt(it)?.icon)
}
setupWithViewPager(viewPager)
repeat(tabCount) {
getTabAt(it)?.setIcon(icons.get(it))
}
}
Then in the layout.xml add your icons to the TabLayout:
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout">
<com.google.android.material.tabs.TabItem
android:icon="#drawable/your_icon"/>
</com.google.android.material.tabs.TabLayout>
Finally, use the extension function to setup the TabLayout with a ViewPager.
tab_layout.setupWithViewPagerAndKeepIcons(view_pager)
the simplest way is create new table by setting Icon on tablayout. below code will create two tab with icon only. use this code on onCreate() method
tablayout = (TabLayout) findViewById(R.id.order_tablayout);
tablayout.addTab( tablayout.newTab().setIcon(getResources().getDrawable(R.mipmap.ic_shopping_cart_white_24dp)) );
tablayout.addTab( tablayout.newTab().setIcon(getResources().getDrawable(R.mipmap.ic_like2_fille_white_24dp)) );
Using a ViewPager. This is how I have a tab with an icon only and no text.
TabLayout tabs...
TabLayout.Tab tab = tabs.getTabAt(0);
tab.setText("");
tab.setIcon(R.drawable.yourIcon);
This may not be the best answer for all cases, but what I found did not solve my problem yet.
After having a look at Androids implementation of tabLayout.setupWithViewPager(ViewPager pager) I came up with a solution using just listeners.
The layout structure:
| LinearLayout (vertical)
|-- TabLayout (width: match_parent)
|---- TabItem (without text, just icons)
|---- TabItem
|---- ...
|-- ViewPager
Code for the both listeners:
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
tabLayout.setScrollPosition(position, positionOffset, false);
}
#Override
public void onPageSelected(int position) {
TabLayout.Tab tab = tabLayout.getTabAt(position);
if (tab != null) {
tab.select();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
Have a look at the tabLayout.setScrollPosition call inside OnPageChangeListener.onPageScrolled for the more or less good moving of the indicator while scrolling.
This may not work if the TabLayout's width is not set to match_parent (or must be scrollable).

Categories

Resources