返回

如何使用原生TabLayout实现指示符固定宽度+圆角,兼容Android 5.0 & 5.1

Android

原生TabLayout实现指示符固定宽度+圆角,兼容Android 5.0 & 5.1系统

在开发中,我们经常会用到 TabLayout 来实现 Tab 页签切换。对于 TabLayout 中的指示符,通常我们会希望对其进行定制,比如设置固定的宽度和圆角等。然而,在 Android 5.0 及 5.1 系统中,使用原生 TabLayout 实现这些定制可能会遇到一些问题。本文将介绍一种原生实现 TabLayout 指示符固定宽度和圆角的方法,并且兼容 Android 5.0 & 5.1 系统。

背景

在 Android 系统中,TabLayout 是一个用于在屏幕上显示一组选项卡的控件。每个选项卡代表一个页面或片段。TabLayout 通常包含一个指示符,用于突出显示当前选中的选项卡。

默认情况下,TabLayout 的指示符是一个横线,它的宽度和高度都是根据选项卡的宽度和高度自动计算的。然而,在某些情况下,我们可能希望定制指示符的外观,比如设置固定的宽度和圆角。

问题

在 Android 5.0 及 5.1 系统中,使用原生 TabLayout 实现指示符的固定宽度和圆角会遇到一些问题。这是因为在这些系统中,TabLayout 使用了一个称为 SlidingTabStrip 的类来绘制指示符。SlidingTabStrip 并没有提供直接设置指示符宽度和圆角的方法。

解决方法

为了解决这个问题,我们可以使用一种变通的方法来实现指示符的固定宽度和圆角。该方法涉及创建自定义的指示符类,并使用它来替换 TabLayout 的默认指示符。

自定义指示符类

首先,我们需要创建一个自定义的指示符类。该类将继承 SlidingTabStrip 类,并重写其 onDraw() 方法来绘制指示符。在 onDraw() 方法中,我们可以使用 Canvas 来绘制一个具有固定宽度和圆角的矩形。

public class CustomIndicator extends SlidingTabStrip {

    private int indicatorWidth;
    private int indicatorHeight;
    private int indicatorCornerRadius;

    public CustomIndicator(Context context) {
        super(context);
        init(context, null);
    }

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

    private void init(Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomIndicator);
        indicatorWidth = a.getDimensionPixelSize(R.styleable.CustomIndicator_indicatorWidth, 10);
        indicatorHeight = a.getDimensionPixelSize(R.styleable.CustomIndicator_indicatorHeight, 4);
        indicatorCornerRadius = a.getDimensionPixelSize(R.styleable.CustomIndicator_indicatorCornerRadius, 2);
        a.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 计算指示符的边界
        int left = (getWidth() - indicatorWidth) / 2;
        int top = getHeight() - indicatorHeight;
        int right = left + indicatorWidth;
        int bottom = top + indicatorHeight;

        // 绘制指示符
        Paint paint = new Paint();
        paint.setColor(getCurrentColor());
        paint.setAntiAlias(true);
        RectF rectF = new RectF(left, top, right, bottom);
        canvas.drawRoundRect(rectF, indicatorCornerRadius, indicatorCornerRadius, paint);
    }
}

替换默认指示符

接下来,我们需要替换 TabLayout 的默认指示符。这可以通过覆盖 TabLayout 的 onDraw() 方法并手动绘制指示符来实现。

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // 绘制自定义指示符
    CustomIndicator indicator = new CustomIndicator(getContext());
    indicator.setBounds(getSelectedTabIndicatorBounds());
    indicator.draw(canvas);
}

完整代码

以下是一个完整的代码示例,演示了如何在原生 TabLayout 中实现指示符的固定宽度和圆角:

public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tabLayout = (TabLayout) findViewById(R.id.tab_layout);
        tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));

        // 替换默认指示符
        tabLayout.setOnDrawListener(new TabLayout.OnDrawListener() {
            @Override
            public void onDraw(Canvas canvas) {
                CustomIndicator indicator = new CustomIndicator(MainActivity.this);
                indicator.setBounds(tabLayout.getSelectedTabIndicatorBounds());
                indicator.draw(canvas);
            }
        });
    }
}

效果

使用上述方法,我们可以在原生 TabLayout 中实现指示符的固定宽度和圆角,并且兼容 Android 5.0 & 5.1 系统。

总结

本文介绍了一种原生实现 TabLayout 指示符固定宽度和圆角的方法,并且兼容 Android 5.0 & 5.1 系统。该方法涉及创建自定义的指示符类,并使用它来替换 TabLayout 的默认指示符。通过这种方法,我们可以实现更灵活的指示符定制,从而满足不同的设计需求。