Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/214.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android TabLayout在tabMode设置为';可滚动';_Android_Android Support Library_Android Tablayout - Fatal编程技术网

Android TabLayout在tabMode设置为';可滚动';

Android TabLayout在tabMode设置为';可滚动';,android,android-support-library,android-tablayout,Android,Android Support Library,Android Tablayout,我已将TabLayout(来自支持库v22.2.1)添加到我的片段中,如下所示: <android.support.design.widget.TabLayout android:id="@+id/tabs" style="@style/MyColorAccentTabLayout" android:layout_width="match_parent" android:layout_height="wrap_content"

我已将
TabLayout
(来自支持库v22.2.1)添加到我的片段中,如下所示:

<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"/>

当屏幕宽度足够大以显示所有标签时(请参阅右边空白区域):


如果我将
tabMode
更改为fixed,则会填充宽度,但选项卡太小。有什么合适的解决办法吗?

我想这是实现你想要的最简单的方法

public class CustomTabLayout extends TabLayout {
    public CustomTabLayout(Context context) {
        super(context);
    }

    public CustomTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        try {
            if (getTabCount() == 0)
                return;
            Field field = TabLayout.class.getDeclaredField("mTabMinWidth");
            field.setAccessible(true);
            field.set(this, (int) (getMeasuredWidth() / (float) getTabCount()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我想这是实现你想要的最简单的方法

public class CustomTabLayout extends TabLayout {
    public CustomTabLayout(Context context) {
        super(context);
    }

    public CustomTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        try {
            if (getTabCount() == 0)
                return;
            Field field = TabLayout.class.getDeclaredField("mTabMinWidth");
            field.setAccessible(true);
            field.set(this, (int) (getMeasuredWidth() / (float) getTabCount()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

试试这个变化

 <android.support.design.widget.TabLayout
        android:id="@+id/sliding_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill" />

尝试此更改

 <android.support.design.widget.TabLayout
        android:id="@+id/sliding_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill" />

我不在乎标签的宽度,但我在乎的是背景色没有扩展到全宽。所以我想到了这个解决方案,在它后面放了一个框架布局,背景颜色与标签相同

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

我不在乎标签的宽度,但我在乎的是背景色没有扩展到全宽。所以我想到了这个解决方案,在它后面放了一个框架布局,背景颜色与标签相同

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

而不是创建自定义的表格布局,或者创建更多的布局,这些布局仅作为后台表格布局的包装。试试这个

<android.support.design.widget.TabLayout
    android:id="@+id/tabs"
    style="@style/MyColorAccentTabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    <!-- Instead of setting app:tabBackground -->
    android:background="@color/colorAccent"
    app:tabGravity="fill"
    app:tabMode="scrollable"/>

android:background=“@color/colorAccent”
app:tabGravity=“填充”
app:tabMode=“可滚动”/

这会将背景设置为“在表格布局后面”,而不是在每个选项卡后面设置背景。

而不是创建自定义表格布局,并对其进行修改或创建更多布局,这些布局仅作为背景的包装。试试这个

<android.support.design.widget.TabLayout
    android:id="@+id/tabs"
    style="@style/MyColorAccentTabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    <!-- Instead of setting app:tabBackground -->
    android:background="@color/colorAccent"
    app:tabGravity="fill"
    app:tabMode="scrollable"/>

android:background=“@color/colorAccent”
app:tabGravity=“填充”
app:tabMode=“可滚动”/

这会将背景设置为TableLayout后面,而不是在每个选项卡后面设置背景。

@dtx12如果任何选项卡标题大于(measuredWidth/tabCount),则回答无效

对于这种情况,有我的
TabLayout
子类(在Kotlin中)。我希望这能帮助别人

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()
                }
            }
        }
    }
}
类FullWidthTabLayout:TabLayout{
构造函数(上下文:上下文?):超级(上下文)
构造函数(context:context?,attrs:AttributeSet?):super(context,attrs)
构造函数(context:context?,attrs:AttributeSet?,defStyleAttr:Int):super(context,attrs,defStyleAttr)
覆盖仅限乐趣的布局(更改为:布尔、l:Int、t:Int、r:Int、b:Int){
超级。在线布局(更改、l、t、r、b)
如果(更改){
val widths=mutableListOf()
对于(0..this.tabCount-1中的i){
添加(this.getTabAt(i)!!.customView!!.width)
}
if(widths.sum()equalPart}
var smallerWidths=widths.filter{it=equalPart}
smallerWidths=smallerWidths.filter{it
@dtx12如果任何选项卡标题大于(测量宽度/tabCount),则答案不起作用

对于这种情况,有我的
TabLayout
子类(在Kotlin中)。我希望这能帮助别人

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()
                }
            }
        }
    }
}
类FullWidthTabLayout:TabLayout{
构造函数(上下文:上下文?):超级(上下文)
构造函数(context:context?,attrs:AttributeSet?):super(context,attrs)
构造函数(context:context?,attrs:AttributeSet?,defStyleAttr:Int):super(context,attrs,defStyleAttr)
覆盖仅限乐趣的布局(更改为:布尔、l:Int、t:Int、r:Int、b:Int){
超级。在线布局(更改、l、t、r、b)
如果(更改){
val widths=mutableListOf()
对于(0..this.tabCount-1中的i){
添加(this.getTabAt(i)!!.customView!!.width)
}
if(widths.sum()equalPart}
var smallerWidths=widths.filter{it=equalPart}
smallerWidths=smallerWidths.filter{it
请使用这个,它肯定会解决这个问题

<android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="fixed" />

请使用这个,它肯定会解决这个问题

<android.support.design.widget.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="fixed" />

请检查此项,我认为它有效

公共类MainActivity扩展了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);
    }
}
private text查看mTxv\u主页、mTxv\u新闻、mTxv\u公告;
私人查看mView_主页、mView_新闻、mView_公告;
私人水平滚动视图hsv;
私人视页机视页机;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxv\U Home=(文本视图)findViewById(R.id.txv\U Home);
mTxv_新闻=(文本视图)findViewById(R.id.txv_新闻);
mTxv_公告=(文本视图)findViewById(R.id.txv_公告);
mView\u Home=(视图)findviewbyd(R.id.View\u Home);
mView_News=(View)findviewbyd(R.id.View_News);
mView\u公告=(查看)findviewbyd(R.id.View\u公告);
hsv=(水平滚动视图)findViewById(R.id.hsv);
看法
var totalWidth = 0
var maxWidth = 0
for (i in 0 until tabLayout.tabCount) {
    val tabWidth = (tabLayout.getChildAt(0) as ViewGroup).getChildAt(i)!!.width
    totalWidth += tabWidth
    maxWidth = max(maxWidth, tabWidth)
}
val screenWidth = Resources.getSystem().displayMetrics.widthPixels

if (totalWidth <  screenWidth&& screenWidth/ tabLayout.tabCount >= maxWidth) {

    tabLayout.tabMode = TabLayout.MODE_FIXED
}
tabLayout.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
    var totalWidth = 0
    var maxWidth = 0
    for (i in 0 until tabLayout.tabCount) {
        val tabWidth = (tabLayout.getChildAt(0) as ViewGroup).getChildAt(i)!!.width
        totalWidth += tabWidth
        maxWidth = max(maxWidth, tabWidth)
    }

     val screenWidth = Resources.getSystem().displayMetrics.widthPixels

    if (totalWidth < screenWidth && screenWidth / tabLayout.tabCount >= maxWidth) {

        tabLayout.tabMode = TabLayout.MODE_FIXED
    }
}
<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        app:tabMode="scrollable"/>
<androidx.viewpager.widget.ViewPager
    android:id="@+id/vpTabs"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMaxWidth="0dp"
        app:tabMode="scrollable"/>

</androidx.viewpager.widget.ViewPager>
app:tabMaxWidth="0dp"
app:tabMode="scrollable"
class MyTabLayout(
  context: Context,
  attrs: AttributeSet?
) : TabLayout(context, attrs) {

  override fun onMeasure(
    widthMeasureSpec: Int,
    heightMeasureSpec: Int
  ) {

    val equalTabWidth= (MeasureSpec.getSize(widthMeasureSpec) / tabCount.toFloat()).toInt()

    for (index in 0..tabCount) {
      val tab = getTabAt(index)
      val tabMeasuredWidth = tab?.view?.measuredWidth ?: equalTabWidth

      if (tabMeasuredWidth < equalTabWidth) {
        tab?.view?.minimumWidth = equalTabWidth
      }
    }

    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
  }
}
public void dynamicSetTabLayoutMode(TabLayout tabLayout) {
            int tabWidth = calculateTabWidth(tabLayout);
            int screenWidth =  getApplicationContext().getResources().getDisplayMetrics().widthPixels;
            if (tabWidth <= screenWidth) {
                tabLayout.setTabMode(TabLayout.MODE_FIXED);
            } else {
                tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
            }
        }
    
      private int calculateTabWidth(TabLayout tabLayout) {
            int tabWidth = 0;
            for (int i = 0; i < tabLayout.getChildCount(); i++) {
                final View view = tabLayout.getChildAt(i);
                view.measure(0, 0); 
                tabWidth += view.getMeasuredWidth();
            }
            return tabWidth;
        }
class ScalableTabLayout : 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 onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val tabLayout = getChildAt(0) as ViewGroup
        val childCount = tabLayout.childCount
        if (childCount > 0) {
            val widthPixels = MeasureSpec.getSize(widthMeasureSpec)
            val tabMinWidth = widthPixels / childCount
            var remainderPixels = widthPixels % childCount
            tabLayout.forEachChild {
                if (remainderPixels > 0) {
                    it.minimumWidth = tabMinWidth + 1
                    remainderPixels--
                } else {
                    it.minimumWidth = tabMinWidth
                }
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    }
}