44

I am using Google's SlidingTabLayout. As i only have 3 tabs to be displayed, I am seeing empty space after last tab. Please screenshot below. enter image description here

Can someone explain me how to fit the tabs to entire screen. Thanks for your time.

Raju
  • 1,427
  • 2
  • 18
  • 31

9 Answers9

97

Use this before setViewPager():

slidingTabs.setDistributeEvenly(true);

If you got this error Cannot resolve method 'setDistributeEvenly(boolean)', you should update your SlidingTabLayout.java and SlidingTabStrip.java from Google I/O source code:

SlidingTabLayout.java

SlidingTabStrip.java

iForests
  • 6,757
  • 10
  • 42
  • 75
  • 14
    and call it before setViewPager – Fanglin Jan 18 '15 at 04:44
  • 3
    This is the correct answer, you should download the codes from github instead of google developer page. – Umeumeume Jan 18 '15 at 06:47
  • 1
    Perfect! Thanks! Just one question, in the version of the Developer page the SlidingTabLayout.TabColorizer has the method "getDividerColor", which was removed in the code of the github. As a matter of fact, the divider is entirely gone. Any motive for this change? – DBragion May 15 '15 at 17:20
  • @NonUmemoto I just copied and pasted the code from github to the android example package. There is no need to download anything – iOSAndroidWindowsMobileAppsDev Sep 27 '16 at 06:26
44

In SlidingTabLayout.java, find

protected TextView createDefaultTabView(Context context)

and add these lines to that method:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
textView.setWidth(size.x / 3);

That fixed it for me. Basically, you're getting the width of your screen and dividing by 3 (the number of tabs) and setting that as the width for the TextField that makes up your tab.

UPDATE:

In the current source, google added a setDistributeEvenly(Boolean); method, so you can use slidingTabs.setDistributeEvenly(true); instead. When using the older source code, either use my solution above, or update to the newest source (latter is recommended).

SubliemeSiem
  • 1,129
  • 17
  • 25
  • I have problems using the snippet above as my minSDKVersion is Gingerbread, which dont support getSize(). Anyways my doubt is, what is the use of display.getSize(size), when we are not using it in subsequent lines. – Raju Nov 07 '14 at 17:08
  • It passes the size to the size variable. I believe in older sdks you can use getx, but I'm not sure. – SubliemeSiem Nov 07 '14 at 17:11
  • Thank you @AndroidCoder85. I am accepting this answer, as it worked for me. Thanks again. – Raju Nov 07 '14 at 17:21
  • Thanks, here is the code for gingerbread compat: if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) { display.getSize(size); } else { size.set(display.getWidth(), display.getHeight()); } – Daniel Wilson Dec 29 '14 at 23:37
  • 6
    This solution works, but you'd better to use sliding_tabs.setDistributeEvenly(true). – Umeumeume Jan 18 '15 at 06:48
  • 1
    Please see my answer below. Google officially add this feature. – iForests Feb 10 '15 at 09:55
  • At the time of writing this answer there was no setDistributeEvenly method available. Else I would have suggested that instead. I've edited my answer though. – SubliemeSiem Oct 01 '15 at 12:36
  • for xamarin development what is the solution – Sumit Pathak Jan 07 '16 at 12:46
  • 2
    IMPORTANT: Use this before setViewPager(), else it won't work! – sudoExclaimationExclaimation Apr 25 '16 at 17:22
10

Changing the SlidingTabLayout.java file may help. However, the solution may not seem very much generic. In the SlidingTabLayout.java file, search for the method

protected TextView createDefaultTabView(Context context)

Underneath the TextView 'set' methods, type in the following code.

textView.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f));

Each tab strip is merely a customized LinearLayout.

Achilles Rasquinha
  • 353
  • 1
  • 3
  • 11
8

SubliemeSiem's answer is on the right track. A more flexible, and shorter, answer is to add a weight of 1 to each TextView that makes up a tab.

In SlidingTabLayout.java, find

protected TextView createDefaultTabView(Context context)

It was line 171 at the time of writing. Add this line to the function.

textView.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));

TableLayout.LayoutParams takes three arguments, the final of which is weight. As all views in the horizontal layout will have equal weight they will be equally sized. The wrap content should allow for graceful behaviour as the number of tabs increases and the size overflows the width of the screen, but I haven't tested that..

Derek
  • 1,572
  • 1
  • 14
  • 25
5

You can create a custom tab layout and assign it to your SlidingTabLayout to inflate.

custom_tab.xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="@+id/customTab">
  <TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/customText"/>
</FrameLayout>

In your code:

    viewPager = (ViewPager) rootView.findViewById(R.id.viewPager);
    viewPager.setAdapter(new SampleAdapter(getChildFragmentManager()));
    SlidingTabLayout tabLayout = (SlidingTabLayout)rootView.findViewById(R.id.slidingTab);
    tabLayout.setCustomTabView(R.layout.custom_tab,R.id.customText);
    tabLayout.setViewPager(viewPager);

By keeping the width to 0 dp and the weight as 1 (the number is arbitrary), the layout should take care of giving all your tabs equal screen space. This should also work for any number of tabs. You shouldn't need to modify your SlidingTabLayout.java.

amitavk
  • 1,196
  • 1
  • 12
  • 15
  • Yes, this work. But text on tab set to very small and blue line on bottom of tab still over text on tab. How to fix it, @amitav13 ? – DQuade Dec 03 '14 at 16:22
  • Reply to my question : after see createDefaultTabView I think - is needed to add only these to TextView in custom_tab.xml ( see reply of @amitav13 ) : android:gravity="center" android:textStyle="bold" android:paddingLeft="2dp" android:paddingRight="2dp" android:paddingTop="10dp" android:paddingBottom="10dp" Its worked for me. Worked well if tabs <= 5. – DQuade Dec 03 '14 at 16:34
  • 1
    @DQuade Yes, 5 tabs or more would be tough to see on a screen in portrait mode. If you want to reduce the thickness of the blue line (selected indicator), you need to adjust the value of the SELECTED_INDICATOR_THICKNESS_DIPS in the SlidingTabStrip class. – amitavk Dec 04 '14 at 00:27
4

Google have released Design Support Library. You can now use TabLayout. To make tabs fits the screen you can call setTabMode(TabLayout.MODE_FIXED);

0

more dynamic approach is

Edit SlidingTabLayout.java

locate private void populateTabStrip() method and replace

mTabStrip.addView(tabView);

with

 // get dimension of current layout
 DisplayMetrics display = this.getResources().getDisplayMetrics();
   int width = display.widthPixels;
        //your tab names here
        String[] tabTitles = {"tab1", "tab2", "tab3"}
        // compare max width and number of tabs's length 
        //will not fit to the maxwidth it will distribute the tabs evenly
        if(width%(width/tabTitles.length) == 0){
            mTabStrip.addView(tabView,
                    new LinearLayout.LayoutParams(width/tabTitles.length, ViewGroup.LayoutParams.WRAP_CONTENT));
        } else {
            mTabStrip.addView(tabView);
        }
Emil Reña Enriquez
  • 2,929
  • 1
  • 29
  • 32
0

in SlidingTabLayout.java under the following method, just before the return statement:

protected TextView createDefaultTabView(Context context)

I added these lines to that method:

final PagerAdapter adapter = mViewPager.getAdapter();
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1.0f / adapter.getCount());
textView.setLayoutParams(param);

that is very close to the answer marked as the solution for the question, however I did not have to use the window manager.

0

try this android:layout_weight="1" in your xml layout for each textview.

shumeza
  • 99
  • 1
  • 2
  • 8