TabLayout not filling width when tabMode set to &#

2019-01-10 20:11发布

I have added TabLayout (from support library v22.2.1) to my Fragment as:

<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        style="@style/MyColorAccentTabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable"/>

The issue is that when the Fragment's orientation is landscape (before or after the initial creation of the fragment), the TabLayout doesn't match the width of the Fragment (yes the parent has its width set to match_parent as well).

When screen width is small (i.e not all tabs can be shown at same time): enter image description here

When screen width is big enough to show all tabs (see the blank space at the right): enter image description here

If I change tabMode to fixed, width is filled but tabs are too small. Is there any proper solution out there?

11条回答
爷、活的狠高调
2楼-- · 2019-01-10 21:07

Try this one, it's a workaround which sets tabMaxWidth="0dp", tabGravity="fill" and tabMode="fixed".

 <android.support.v4.view.ViewPager
     android:id="@+id/container"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     app:layout_behavior="@string/appbar_scrolling_view_behavior">
     <android.support.design.widget.TabLayout
         android:id="@+id/tabs"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:tabMaxWidth="0dp"
         app:tabGravity="fill"
         app:tabMode="fixed"/>
</android.support.v4.view.ViewPager>

Screenshot on a 10 inch tablet:

screenshot

查看更多
男人必须洒脱
3楼-- · 2019-01-10 21:07

Please check this i think it works

public class MainActivity extends AppCompatActivity {

private TextView mTxv_Home, mTxv_News, mTxv_Announcement;
private View mView_Home, mView_News, mView_Announcements;
private HorizontalScrollView hsv;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mTxv_Home = (TextView) findViewById(R.id.txv_home);
    mTxv_News = (TextView) findViewById(R.id.txv_news);
    mTxv_Announcement = (TextView) findViewById(R.id.txv_announcements);
    mView_Home = (View) findViewById(R.id.view_home);
    mView_News = (View) findViewById(R.id.view_news);
    mView_Announcements = (View) findViewById(R.id.view_announcements);
    hsv = (HorizontalScrollView) findViewById(R.id.hsv);
    viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);
    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int wt = displaymetrics.widthPixels/3;
    mTxv_Home.setWidth(wt);
    mTxv_News.setWidth(wt);
   // mTxv_Announcement.setWidth(wt);
    mTxv_Home.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            mTxv_Home.setTextColor(Color.parseColor("#3F51B5"));
            mTxv_News.setTextColor(Color.parseColor("#808080"));
            mTxv_Announcement.setTextColor(Color.parseColor("#808080"));
            mView_Home.setBackgroundColor(Color.parseColor("#3F51B5"));
            mView_News.setBackgroundColor(Color.parseColor("#E8E8E8"));
            mView_Announcements.setBackgroundColor(Color.parseColor("#E8E8E8"));
            hsv.post(new Runnable() {
                public void run() {
                    hsv.fullScroll(HorizontalScrollView.FOCUS_LEFT);
                }
            });
            viewPager.setCurrentItem(0);
        }
    });
    mTxv_News.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mTxv_Home.setTextColor(Color.parseColor("#808080"));
            mTxv_News.setTextColor(Color.parseColor("#3F51B5"));
            mTxv_Announcement.setTextColor(Color.parseColor("#808080"));
            mView_Home.setBackgroundColor(Color.parseColor("#E8E8E8"));
            mView_News.setBackgroundColor(Color.parseColor("#3F51B5"));
            mView_Announcements.setBackgroundColor(Color.parseColor("#E8E8E8"));
            hsv.post(new Runnable() {
                public void run() {
                    int centerX = hsv.getChildAt(0).getWidth()/2;
                    hsv.scrollTo(centerX, 0);
                }
            });
            viewPager.setCurrentItem(1);


        }
    });
    mTxv_Announcement.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mTxv_Home.setTextColor(Color.parseColor("#808080"));
            mTxv_News.setTextColor(Color.parseColor("#808080"));
            mTxv_Announcement.setTextColor(Color.parseColor("#3F51B5"));
            mView_Home.setBackgroundColor(Color.parseColor("#E8E8E8"));
            mView_News.setBackgroundColor(Color.parseColor("#E8E8E8"));
            mView_Announcements.setBackgroundColor(Color.parseColor("#3F51B5"));
            hsv.post(new Runnable() {
                public void run() {
                    hsv.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
                }
            });
            viewPager.setCurrentItem(2);
        }
    });

    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {

            if (position == 0) {
                mTxv_Home.setTextColor(Color.parseColor("#3F51B5"));
                mTxv_News.setTextColor(Color.parseColor("#808080"));
                mTxv_Announcement.setTextColor(Color.parseColor("#808080"));
                mView_Home.setBackgroundColor(Color.parseColor("#3F51B5"));
                mView_News.setBackgroundColor(Color.parseColor("#E8E8E8"));
                mView_Announcements.setBackgroundColor(Color.parseColor("#E8E8E8"));
                hsv.post(new Runnable() {
                    public void run() {
                        hsv.fullScroll(HorizontalScrollView.FOCUS_LEFT);
                    }
                });


            } else if (position == 1) {
                mTxv_Home.setTextColor(Color.parseColor("#808080"));
                mTxv_News.setTextColor(Color.parseColor("#3F51B5"));
                mTxv_Announcement.setTextColor(Color.parseColor("#808080"));
                mView_Home.setBackgroundColor(Color.parseColor("#E8E8E8"));
                mView_News.setBackgroundColor(Color.parseColor("#3F51B5"));
                mView_Announcements.setBackgroundColor(Color.parseColor("#E8E8E8"));
                hsv.post(new Runnable() {
                    public void run() {
                        int centerX = hsv.getChildAt(0).getWidth()/2;
                        hsv.scrollTo(centerX, 0);
                    }
                });


            } else if (position == 2) {
                mTxv_Home.setTextColor(Color.parseColor("#808080"));
                mTxv_News.setTextColor(Color.parseColor("#808080"));
                mTxv_Announcement.setTextColor(Color.parseColor("#3F51B5"));
                mView_Home.setBackgroundColor(Color.parseColor("#E8E8E8"));
                mView_News.setBackgroundColor(Color.parseColor("#E8E8E8"));
                mView_Announcements.setBackgroundColor(Color.parseColor("#3F51B5"));
                hsv.post(new Runnable() {
                    public void run() {
                        hsv.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
                    }
                });
            }

        }
        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
}
private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new HomeFragment(), "Home");
    adapter.addFragment(new NewsFragment(), "News");
    adapter.addFragment(new AnnouncementsFragment(), "Announcements");
    viewPager.setAdapter(adapter);
}

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

}

<HorizontalScrollView
    android:id="@+id/hsv"
    android:layout_width="fill_parent"
    android:layout_height="56dp"
    android:layout_weight="0"
    android:fillViewport="true"
    android:measureAllChildren="false"
    android:scrollbars="none" >
    <LinearLayout
        android:id="@+id/innerLay"
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:orientation="horizontal" >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:id="@+id/txv_home"
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:text="Home"
                android:singleLine="true"
                android:paddingLeft="35dp"
                android:paddingRight="35dp"
                android:gravity="center"
                android:textSize="15sp"/>
            <View
                android:id="@+id/view_home"
                android:layout_width="match_parent"
                android:layout_height="3dp"
                android:background="@color/colorPrimary"
               />
        </LinearLayout>
        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:visibility="gone"
            android:background="#e8e8e8"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:id="@+id/txv_news"
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:text="News"
                android:singleLine="true"
                android:paddingLeft="35dp"
                android:paddingRight="35dp"
                android:gravity="center"
                android:textSize="15sp"/>
            <View
                android:id="@+id/view_news"
                android:layout_width="match_parent"
                android:layout_height="3dp"
                android:background="#e8e8e8"/>
        </LinearLayout>
        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:visibility="gone"
            android:background="#e8e8e8"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:id="@+id/txv_announcements"
                android:layout_width="wrap_content"
                android:layout_height="0dp"
                android:layout_weight="1"
                android:singleLine="true"
                android:text="Announcements"
                android:paddingLeft="35dp"
                android:paddingRight="35dp"
                android:gravity="center"
                android:textSize="15sp"/>
            <View
                android:id="@+id/view_announcements"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#e8e8e8"/>
        </LinearLayout>

    </LinearLayout>
</HorizontalScrollView>
<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/hsv" />
查看更多
地球回转人心会变
4楼-- · 2019-01-10 21:08

please use this it will solve this problem definitely

<android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="fixed" />
查看更多
小情绪 Triste *
5楼-- · 2019-01-10 21:08

You should set app:tabMode="fixed" when you want to show tabs 'fill'.

**<android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/toolbar"
            android:background="#353535"
            app:tabMode="fixed"
            android:minHeight="?attr/actionBarSize"
            app:tabIndicatorColor="@color/red"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />**
查看更多
【Aperson】
6楼-- · 2019-01-10 21:09

@dtx12 answer doesn't work if any tab title is bigger than (measuredWidth/ tabCount).

There is my TabLayout subclass for this situation (in Kotlin). I hope this will help someone.

class FullWidthTabLayout : TabLayout {

    constructor(context: Context?) : super(context)

    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)
        if (changed) {
            val widths = mutableListOf<Int>()
            for (i in 0..this.tabCount - 1) {
                widths.add(this.getTabAt(i)!!.customView!!.width)
            }

            if (widths.sum() < this.measuredWidth) {
                var equalPart: Long = this.measuredWidth.toLong() / this.tabCount.toLong()
                var biggerWidths = widths.filter { it > equalPart }
                var smallerWidths = widths.filter { it <= equalPart }
                var rest: Long = this.measuredWidth.toLong() - biggerWidths.sum()
                while (biggerWidths.size != 0) {
                    equalPart = rest / smallerWidths.size
                    biggerWidths = smallerWidths.filter { it >= equalPart }
                    smallerWidths = smallerWidths.filter { it < equalPart }
                    rest -= biggerWidths.sum()
                }
                val minWidth = (rest / smallerWidths.size) + 10 //dont know why there is small gap on the end, thats why +10
                for (i in 0..this.tabCount - 1) {
                    this.getTabAt(i)!!.customView!!.minimumWidth = minWidth.toInt()
                }
            }
        }
    }
}
查看更多
登录 后发表回答