TabLayout使用遇到的坑及方案

修改下划线宽度的坑效果如下: 代码实现方式: 如果想要实现这种效果,最主要控制的就是下划线部分,现在网上有很多通过反射的方式来修改下划线宽度的文章,但这段代码如果实现我们想要的效果是不可能的,因为如果研究过源码就知道Indicator的宽度跟Tab的宽度一致的,不能让指示器的宽度小于Tab的宽度,所以我们只能另辟蹊径:通过CustomView自己绘制线,通过添加OnTabSelectedListener来展示隐藏下划线,让原生的Indicaqtor高度为0也不会影响我们的展示。 OK! Talk is cheap, show me the code. 先隐藏原来的下划线,让其不显示: <android.support.design.widget.TabLayout android:id="@+id/radio_playlist_tab_layout" android:layout_width="match_parent" android:layout_height="@dimen/dp_36.7" android:background="@color/color_e8e8e8" app:tabBackground="@null" app:tabIndicatorHeight="0dp" app:tabMode="scrollable" />其次设置CustomView效果: 再手动控制切换时Tab的下划线:mTabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { override fun onTabReselected(tab: TabLayout.Tab?) { val view = tab?.customView?.findViewById<View>(R.id.tab_indicator) val textView = tab?.customView?.findViewById<TextView>(R.id.tab_tv_date) textView?.setTextColor(mTabSelectedColor) view?.visibility = View.VISIBLE } override fun onTabUnselected(tab: TabLayout.Tab?) { val view = tab?.customView?.findViewById<View>(R.id.tab_indicator) val textView = tab?.customView?.findViewById<TextView>(R.id.tab_tv_date) textView?.setTextColor(mTabUnSelectedColor) view?.visibility = View.INVISIBLE } override fun onTabSelected(tab: TabLayout.Tab?) { val view = tab?.customView?.findViewById<View>(R.id.tab_indicator) val textView = tab?.customView?.findViewById<TextView>(R.id.tab_tv_date) textView?.setTextColor(mTabSelectedColor) view?.visibility = View.VISIBLE } }) 间距部分只是这样的话,下划线的问题解决了。但对于我们的UI对于界面还原度要求较高,对于Tab之间的间距也有一些要求,所以也要处理,对于间距部分的处理可以按照之前的方式通过反射来完成。注意,这种方式因为需要计算TextView的文字宽度,所以要放到设置完所有的customView后调用。 ...

May 9, 2019 · 3 min · jiezi

TabLayout与ViewPager结合时不显示Tab标题

当我们将TabLayout与ViewPager结合时,会出现Tab标题不显示的问题. mTabLayout.setupWithViewPager(viewPager);从源码里找答案.先看下方法调用流程大致流程如图,这里只给出populateFromPagerAdapter()方法源码.void populateFromPagerAdapter() { removeAllTabs(); if (mPagerAdapter != null) { //返回ViewPager设置的PagerAdapter.getCount() final int adapterCount = mPagerAdapter.getCount(); for (int i = 0; i < adapterCount; i++) { //重新添加,并通过PagerAdapter.getPageTitle()为tab设置标题 addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false); } // Make sure we reflect the currently set ViewPager item if (mViewPager != null && adapterCount > 0) { final int curItem = mViewPager.getCurrentItem(); if (curItem != getSelectedTabPosition() && curItem < getTabCount()) { selectTab(getTabAt(curItem)); } } } }这个方法的第一步 removeAllTabs();./** * Remove all tabs from the action bar and deselect the current tab. */ public void removeAllTabs() { // Remove all the views for (int i = mTabStrip.getChildCount() - 1; i >= 0; i–) { removeTabViewAt(i); } for (final Iterator<Tab> i = mTabs.iterator(); i.hasNext();) { final Tab tab = i.next(); i.remove(); tab.reset(); sTabPool.release(tab); } mSelectedTab = null; }移除了TabLayout添加的tab.下一步final int adapterCount = mPagerAdapter.getCount();则是返回你设置给ViewPager的PagerAdapter的getCount()返回值.然后在for循环中 addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), 添加新的tab,并将PagerAdapter.getPageTitle()返回值设置为tab的标题.因此,当ViewPager与TabLayout结合使用时,不必给TabLayout添加tab,也就是不用调用TabLayout.addTab(). ...

March 29, 2019 · 1 min · jiezi

Android-快速实现ViewPager+Tablayout的联动效果

Android-快速实现ViewPager+Tablayout的联动效果在项目开发中很多场景都会碰到tab栏切换的效果,实现的思路也有很多种,tabhost+fragment,radionbtton+viewpager等方式都可以实现,这里就说下tablayout+viewpager的实现方式;tablayout是android5.0推出来的一个MaterialDesign风格的控件,是专门用来实现tab栏效果的;功能强大,使用方便灵活;引入依赖库:implementation ‘com.android.support:support-v4:26.1.0’ implementation ‘com.android.support:design:26.1.0’布局文件:<?xml version=“1.0” encoding=“utf-8”?><LinearLayoutxmlns: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"android:background="@color/bg"android:orientation="vertical"><android.support.design.widget.TabLayout android:id=”@+id/tablayout" android:layout_width=“match_parent” android:layout_height=“50dp” android:layout_gravity=“top|center” app:tabMode=“fixed” app:tabGravity=“fill” app:tabTextColor="@color/black999" app:tabSelectedTextColor="@color/orange" app:tabIndicatorColor="@color/orange" app:tabIndicatorHeight=“4dp”/><android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width=“match_parent” android:layout_height=“match_parent” android:background="@android:color/white"></android.support.v4.view.ViewPager></LinearLayout>tablayout提供了很多的属性可以设置:app:tabIndicatorColor 指示器颜色app:tabTextColor tab栏字体颜色app:tabSelectedTextColor tab栏字体被选颜色app:tabIndicatorHeight 指示器高度app:tabBackground tab背景颜色app:tabMaxWidth tab栏最大宽度app:tabTextAppearance tab栏字体样式app:tabMinWidth tab栏最小宽度这些属性可以下xml中设置,也可以使用代码进行设置;需要注意这两个属性:app:tabMode="";有scrollable和fixed两个属性值scrollable:可滑动;fixed:不能滑动,平分tabLayout宽度;app:tabGravity="";有center和fill两个属性值fill:tabs平均填充整个宽度;center:tab居中显示;页面实现方式:public static final String[] tabTitles = new String[]{“全部”, “代付款”, “代发货”, “配送中”};private TabLayout mTabLayout;private ViewPager mViewPager;private List<MyOrderFragment> mFragments = new ArrayList<MyOrderFragment>();mTabLayout = (TabLayout) findViewById(R.id.tablayout); mViewPager = (ViewPager) findViewById(R.id.viewpager); tv_title.setText(“所有订单”); for (int i = 0; i < tabTitles.length; i++) { mFragments.add(MyOrderFragment.createFragment(tabTitles[i],activity)); } //为ViewPager设置FragmentPagerAdapter mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { return mFragments.get(position); } @Override public int getCount() { return mFragments.size(); } /** * 为TabLayout中每一个tab设置标题 */ @Override public CharSequence getPageTitle(int position) { return tabTitles[position]; } }); //TabLaout和ViewPager进行关联 mTabLayout.setupWithViewPager(mViewPager);其中MyOrderFragment就是我们装载的页面 ,这样就可以快速的实现tablayout和viewpager相互关联。做个简单的记录~ ...

March 13, 2019 · 1 min · jiezi