首页 > 解决方案 > 如何在不导致过度绘制的情况下为 UI 中的特定组件添加背景颜色?

问题描述

背景

我有一个TabLayout里面有一些元素。

在纵向模式下,元素没有足够的空间出现。所以我用:

app:tabMode="scrollable"

另一方面,在横向模式下,元素有多余的空间,我希望它居中。所以我使用了这种方法:

<android.support.design.widget.TabLayout
    android:id="@+id/tabs"
    style="@style/Tab"
    android:layout_width="wrap_content" <!-- Used wrap_content -->
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true" <!-- And CenterHorizontal -->
    app:tabMode="scrollable" />

但由于我的背景颜色为空MainActivity

window.setBackgroundDrawable(null)

横屏模式下TabLayout与 (Black Wings) 一起出现。

我希望它有@color/colorPrimary翅膀。


所以我有两个选择:

1- 制作我的背景MainActivity,不为空(又名@color/colorPrimary

我不想这样做,因为我在同伴中的所有片段ViewPager都会体验到Overdraw,因为它们都有以编程方式设置的不同背景。

或者

2- 添加一个 Container 来孵化 myTabLayout并使用 my 设置其背景@color/colorPrimary,如下所示:

<RelativeLayout
    android:id="@+id/tabs_parent"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimary">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        style="@style/Tab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        app:tabMode="scrollable" />
</RelativeLayout>

我将在下面讨论这种方法的问题。


问题

使用上面的选项 #2:

仍然有一点点,Overdraw两个视图, parentRelativeLayout和 child TabLayout,重叠。

那么我怎样才能删除这个额外的位Overdraw


想法

我正在考虑重写课堂上的OnDraw方法View以满足我的需要,但挑战是如何知道我需要的实际位置ClipRect()

另一个想法是想出一种不同于上述选项#2 的(更简单的)Background方法来解决问题。

提前致谢。

标签: javaandroidperformanceandroid-layoutkotlin

解决方案


我到处寻找这个确切问题的答案。在我的情况下,我是动态添加和删除选项卡,所以我希望它在只有几个选项卡时填满屏幕,但在有太多选项卡时开始滚动,而不是缩小它们或将标题放在两行。使用以下自定义选项卡布局终于让它对我有用。在调用 super.onMeasure()之前设置最小宽度是关键。

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) {

        ViewGroup tabLayout = (ViewGroup)getChildAt(0);
        int childCount = tabLayout.getChildCount();

        DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
        int tabMinWidth = displayMetrics.widthPixels/childCount;

        for(int i = 0; i < childCount; ++i){
            tabLayout.getChildAt(i).setMinimumWidth(tabMinWidth);
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

在 xml 中将选项卡模式设置为可滚动。

    <com.package.name.CustomTabLayout
        android:id="@+id/my_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable">

推荐阅读