如何将tablayout的指示器从底部更改为顶部?

Posted

技术标签:

【中文标题】如何将tablayout的指示器从底部更改为顶部?【英文标题】:How to change indicator of tablayout to top from bottom? 【发布时间】:2016-02-21 23:10:03 【问题描述】:

我想从下到上更改标签布局的指示器。

我的代码

activity_tab.xml

<android.support.design.widget.AppBarLayout
    android:layout_
    android:layout_

    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_
        android:layout_
        android:background="?attr/colorPrimary"

        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_
        android:layout_

        app:tabIndicatorColor="#000000"

        app:tabMode="scrollable"
        />
</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_
    android:layout_
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

我想要这个结果。

怎么做

谢谢你问我,抱歉英语不好。

【问题讨论】:

请将您的图片嵌入为图片,无需 html 标记。还请提高您的文字质量! 好的,对不起,我会编辑它。 你找到解决办法了吗? 我使用智能标签布局库 【参考方案1】:

不要使用 scale = -1 之类的东西。

从 XML 你可以使用app:tabIndicatorGravity="top"

您可以从代码中使用setSelectedTabIndicatorGravity(INDICATOR_GRAVITY_TOP)

【讨论】:

被低估了,可能是因为它最近被添加到标准库中,但这绝对是要走的路,谢谢分享!【参考方案2】:

可以通过xml属性来完成,在xml代码中使用android:scaleY="-1"。视图将垂直翻转。使用相同的方法更正标签标题中使用的文本和图像。

在xml文件中:

<android.support.design.widget.TabLayout
    android:id="@+id/tabLayout"
    android:layout_
    android:layout_
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:scaleY="-1"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

在 Java 代码中

tabLayout = (TabLayout) findViewById(R.id.tabLayout);

// Adding the tabs using addTab() method
tabLayout.addTab(tabLayout.newTab().setText("Section 1"));
tabLayout.addTab(tabLayout.newTab().setText("Section 2"));
tabLayout.addTab(tabLayout.newTab().setText("Section 3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

TextView tv1 = (TextView)(((LinearLayout)((LinearLayout)tabLayout.getChildAt(0)).getChildAt(0)).getChildAt(1));
tv1.setScaleY(-1);
TextView tv2 = (TextView)(((LinearLayout)((LinearLayout)tabLayout.getChildAt(0)).getChildAt(1)).getChildAt(1));
tv2.setScaleY(-1);
TextView tv3 = (TextView)(((LinearLayout)((LinearLayout)tabLayout.getChildAt(0)).getChildAt(2)).getChildAt(1));
tv3.setScaleY(-1);

【讨论】:

@Wilhelm 谢谢 :) 正如@Michael 在下面的答案中所说,app:tabIndicatorGravity="top" 工作顺利【参考方案3】:

您可以通过像这样旋转 TabLayout 来实现这一点:

tabLayout.setRotationX(180);

然后你必须将它的所有 TextView 子级旋转回来,或者你可以将 TabLayout 设置为自定义视图,而不是递归搜索 TextView:

TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(R.layout.layout_tab_view);

layout_tab_view.xml

    <TextView
        android:layout_
        android:layout_
        android:rotationX="180"
        android:text="HOME"/>

如果您设置自定义视图,我猜您会丢失一些默认功能,例如从 PagerAdapter 和 TextView 禁用外观命名的片段标题,但您可以通过其他方式将它们绑定在一起。

【讨论】:

【参考方案4】:

不幸的是,您不能通过设置属性或在代码中设置它来做到这一点。 TabLayout有一个SlidingTabStrip(内部类)的属性mTabStrip,设置为private final

private final SlidingTabStrip mTabStrip;

,所以你不能通过扩展 TabLayout 来访问它。

所以SlidingTabStrip(它扩展了LinearLayoyut)是一个覆盖draw方法的视图

@Override
    public void draw(Canvas canvas) 
        super.draw(canvas);
        // Thick colored underline below the current selection
        if (mIndicatorLeft >= 0 && mIndicatorRight > mIndicatorLeft) 
            canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight,
                    mIndicatorRight, getHeight(), mSelectedIndicatorPaint);
        
    

所以你可以看到它绘制了具有顶部和底部属性的矩形。

将来他们可能会有一个标志来改变它。

【讨论】:

【参考方案5】:

我有不同的方法来做到这一点..

    将选项卡指示器的颜色设置为与选项卡布局的背景颜色相同(这样您就不会看到底部的选项卡指示器)

    在包含视图的选项卡布局上方添加一个线性布局(水平)(与选项卡数量相同)。

<LinearLayout android:layout_ android:layout_ android:orientation="horizontal" android:background="@color/tab_bg" android:weightSum="3">

<View
    android:id="@+id/view1"
    android:layout_
    android:layout_
    android:layout_weight="1"
    android:elevation="10dp"
    android:background="@drawable/selector_tab_indicator_white"/>

<View
    android:id="@+id/view2"
    android:layout_
    android:layout_
    android:layout_weight="1"
    android:elevation="10dp"
    android:background="@drawable/selector_tab_indicator_blue"/>

<View
    android:id="@+id/view3"
    android:layout_
    android:layout_
    android:layout_weight="1"
    android:elevation="10dp"
    android:background="@drawable/selector_tab_indicator_blue"/>

&lt;/LinearLayout&gt;

    现在只需以编程方式调整视图背景。

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

    
    
    @Override
    public void onPageSelected(int position) 
        setTitle(getPageTitle(position));
    
        switch(position)
    
            case 0:
                view1.setBackgroundResource( R.drawable.selector_tab_indicator_white );
                view2.setBackgroundResource( R.drawable.selector_tab_indicator_blue );
                view3.setBackgroundResource( R.drawable.selector_tab_indicator_blue );
                break;
    
            case 1:
                view1.setBackgroundResource( R.drawable.selector_tab_indicator_blue );
                view2.setBackgroundResource( R.drawable.selector_tab_indicator_white );
                view3.setBackgroundResource( R.drawable.selector_tab_indicator_blue );
                break;
    
            case 2:
                view1.setBackgroundResource( R.drawable.selector_tab_indicator_blue );
                view2.setBackgroundResource( R.drawable.selector_tab_indicator_blue );
                view3.setBackgroundResource( R.drawable.selector_tab_indicator_white );
                break;
    
            default:
                view1.setBackgroundResource( R.drawable.selector_tab_indicator_white );
                view2.setBackgroundResource( R.drawable.selector_tab_indicator_blue );
                view3.setBackgroundResource( R.drawable.selector_tab_indicator_blue );
                break;
        
    
    
    @Override
    public void onPageScrollStateChanged(int state) 
    
    
    

    );

使用这些选择器自定义视图

selector_tab_indicator_white.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">
<corners
    android:radius="50dp"/>
<stroke
    android:
    android:color="#c4c0c0" />
<solid
    android:color="#fafafa" />

selector_tab_indicator_blue.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">
<corners
    android:radius="0dp"/>
<stroke
    android:
    android:color="@color/tab_bg" />
<solid
    android:color="@color/tab_bg" />

结果:

【讨论】:

如果我有五个不同大小的标签怎么办? @ShabbirDhangot - 改用线性布局。但是切换标签时不会有任何动画。 kartik 琼脂溶液对我有用。您的解决方案不适用于标签空间不均匀。【参考方案6】:

你只需要那些行

tabLayout.setRotationX(180);

    tabListed = ((LinearLayout)tabLayout.getChildAt(0));
    for(int position = 0;position<tabListed.getChildCount();position++) 
        LinearLayout item=((LinearLayout) tabListed.getChildAt(position));
        item.setBackground(getDrawable(R.drawable.square_tab));
        item.setRotationX(180);
    

第一个标签旋转将标签布局旋转 180º,然后您将获得所有标签并将其旋转 180º。所以他们又好了。

【讨论】:

【参考方案7】:

xml属性无法做到,但可以通过在tab的背景中设置图片,顶部填充颜色,底部透明来实现。

 <android.support.design.widget.TabLayout
          ...
            app:tabBackground="@drawable/bg_tab"
            ...
 /> 

bg_tab.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/cap" android:state_selected="true" />
</selector>

cap.png

底部透明

【讨论】:

【参考方案8】:

我知道这个问题是 2 年前提出的,但我没有找到任何简单的解决方案而不使用任何库(smartTabLayout 没有 SelectedTextColour 属性)。

反转你的 tabLayout 以获得顶部的指示器android:rotationX="180" 现在这将导致该选项卡中的文本也被反转,因此可以解决这个问题 我们必须创建自定义选项卡视图。制作一个xml文件,例如:layout_custom_tab

<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/tab.text"
android:layout_
android:layout_
android:gravity="center"
android:maxLines="1"
android:padding="10dp"
android:rotationX="180"
android:textAllCaps="true"
android:textSize="12sp"
android:textColor="@color/white"
/>

注意:当只有一个元素时,你不需要 RelativeLayout 或其他任何东西

创建自己的 TabLayout 并将 customView 设置为它。

public class TabLayoutPlus extends TabLayout 

public TabLayoutPlus(Context context) 
    super(context);


public TabLayoutPlus(Context context, AttributeSet attrs) 
    super(context, attrs);


public TabLayoutPlus(Context context, AttributeSet attrs, int defStyleAttr) 
    super(context, attrs, defStyleAttr);


@Override
public void setupWithViewPager(ViewPager viewPager) 
    super.setupWithViewPager(viewPager);
    this.removeAllTabs();

    PagerAdapter adapter = viewPager.getAdapter();

    for (int i = 0, count = adapter.getCount(); i < count; i++) 
        Tab tab = this.newTab();
        View customView = LayoutInflater.from(getContext()).inflate(R.layout.layout_custom_tab, null);
        TextViewPlus tv = (TextViewPlus) customView.findViewById(R.id.tab_text);
        tv.setText(adapter.getPageTitle(i));
        tab.setCustomView(customView);
        this.addTab(tab.setText(adapter.getPageTitle(i)));
    
     

您的活动中的 TabLayout 将如下所示

<TabLayoutPlus
    android:id="@+id/tablayout"
    android:layout_
    android:layout_
    android:layout_above="@+id/camera.buttons.layout"
    android:layout_centerHorizontal="true"
    android:background="@color/cardscan.background"
    android:rotationX="180"
    app:tabGravity="center"
    app:tabIndicatorColor="@color/colorPrimary"
    app:tabMode="fixed"
    app:tabSelectedTextColor="@color/colorPrimary"
    app:tabTextColor="@color/white"
    />

如果您需要突出显示选定的选项卡文本颜色

private void setSelectedTab(TabLayoutPlus.Tab tab) 
    View view = tab.getCustomView();
    TextViewPlus tabtext = (TextViewPlus) view.findViewById(R.id.tab_text);
    tabtext.setTextColor(ContextCompat.getColor(this, R.color.colorPrimary)); // color you want to highlight your text with


private void setUnselectedTab(TabLayoutPlus.Tab tab)
    View view = tab.getCustomView();
    TextViewPlus tabtext = (TextViewPlus) view.findViewById(R.id.tab_text);
    tabtext.setTextColor(ContextCompat.getColor(this, R.color.white)); // color you want to lowlight your text with

现在只需添加 OnTabSelectedListener

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() 
        @Override
        public void onTabSelected(TabLayout.Tab tab) 
            setSelectedTab(tab);
        

        @Override
        public void onTabUnselected(TabLayout.Tab tab) 
            setUnselectedTab(tab);
        

        @Override
        public void onTabReselected(TabLayout.Tab tab) 
            setSelectedTab(tab);
        
    );

【讨论】:

【参考方案9】:

我用这个方法解决了

set scaleY="-1" ,这会将 TabLayout 旋转到 180 度,结果选项卡布局与文本反向旋转并将您的 TextView 旋转到水平到 180 度,这将解决问题,请参见下面的代码

    activity.xml

     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_
        android:layout_>
    
    
        <RelativeLayout
            android:layout_
            android:layout_>
    
    
            <android.support.v4.view.ViewPager
                android:id="@+id/viewpager_exp"
                android:layout_above="@+id/tabs_RL"
                android:layout_
                android:layout_
                app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
    
    
            <RelativeLayout
                android:id="@+id/tabs_RL"
                android:layout_alignParentBottom="true"
                android:layout_
                android:layout_>
    
    
                <android.support.design.widget.TabLayout
                    android:id="@+id/tabs"
                    android:layout_
                    android:layout_
                    android:background="@color/white"
                    android:clipToPadding="false"
                    android:paddingLeft="0dp"
                    android:paddingRight="0dp"
                    android:scaleY="-1"
                    app:layout_scrollFlags="snap|enterAlways"
                    app:tabGravity="fill"
                    app:tabMaxWidth="0dp"
                    app:tabIndicatorHeight="4dp"
                    app:tabIndicatorColor="@color/dark_pink1"
                    app:tabMinWidth="50dp"
                    app:tabPaddingEnd="0dp"
                    app:tabPaddingStart="0dp"
                    app:tabMode="fixed" />
    
            </RelativeLayout>
        </RelativeLayout>
    
    </RelativeLayout>
    

    custom_tab.xml

    <customviews.CusMediumTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tab"
    android:layout_
    android:layout_
    android:gravity="center_horizontal"
    android:textColor="#000000"
    android:textSize="@dimen/dimen_12"
    android:rotationX="180"
    android:textStyle="bold" />
    

    MainActivity.class

        tabLayout.setupWithViewPager(viewPager);
    
        tabOne = (CusMediumTextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
        tabOne.setText("Tab1");
        tabOne.setTextColor(getResources().getColor(R.color.light_black));
        tabOne.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.home_icon, 0, 0);
    
    
        tabTwo = (CusMediumTextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
        tabTwo.setText("Tab2");
        tabTwo.setTextColor(getResources().getColor(R.color.light_black));
        tabTwo.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.settin_icon, 0, 0);
    
    
        tabThree = (CusMediumTextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
        tabThree.setText("Tab3");
        tabThree.setTextColor(getResources().getColor(R.color.light_black));
        tabThree.setCompoundDrawablesWithIntrinsicBounds( 0,R.drawable.delete_icon, 0, 0);
    
    
        tabFour = (CusMediumTextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
        tabFour.setText("Tab4");
        tabFour.setTextColor(getResources().getColor(R.color.light_black));
        tabFour.setCompoundDrawablesWithIntrinsicBounds( 0, R.drawable.msg_icon,0, 0);
    
        tabLayout.getTabAt(0).setCustomView(tabOne);
        tabLayout.getTabAt(1).setCustomView(tabTwo);
        tabLayout.getTabAt(2).setCustomView(tabThree);
        tabLayout.getTabAt(3).setCustomView(tabFour);
    

【讨论】:

以上是关于如何将tablayout的指示器从底部更改为顶部?的主要内容,如果未能解决你的问题,请参考以下文章

IOS:如何将UITabbar的位置更改为视图顶部

底部 TabLayout 位于键盘顶部

如何将 Flutter 标签栏指示器更改为与 google play store 完全相同

简单Fragment+Tablayout+ViewPage实现底部和顶部滑动(菜单栏)

如何以编程方式将视图的底部约束从安全区域更改为超级视图?

如何将默认的小吃店动画更改为“从顶部到按钮”?