如何旋转背景颜色不锯齿的 Android 文本视图(需要抗锯齿)

jt-*_*son 0 android antialiasing textview

我有一个带有背景颜色的静态 xml 布局(看起来像打印的标签),我想以某个角度显示。我遇到的问题是背景边缘看起来像是在 1980 年代渲染的(锯齿状 - 没有抗锯齿)。

如何获得一个在某个角度看起来像标签的文本视图并让它看起来不错(即抗锯齿)?

布局:

    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:paddingRight="5dp"
    android:paddingTop="5dp"
    android:paddingBottom="5dp"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:includeFontPadding="false"
        android:maxLines="1"
        android:singleLine="true"
        android:text="Sample Text"
        android:textAllCaps="true"
        android:textColor="#ffffff"
        android:textSize="12sp"
        android:background="#3db8eb"
        android:rotation="-3"
        android:paddingTop="1dp"
        android:paddingBottom="1dp"
        android:paddingLeft="3dp"
        android:paddingRight="3dp"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

它的外观:

例子

gMa*_*ale 5

根据我的相关答案setFilterBitmap对我来说不太适用。部分原因是我使用的是 9patch 背景而不是颜色。

方法#1:在视图上禁用硬件加速

有效的是禁用相关视图及其父视图的硬件加速(单独一个不起作用):

private void fixAntiAlias(View viewFromThe80s) {
    if (Build.VERSION.SDK_INT > 10) {
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
        viewFromThe80s.setLayerType(View.LAYER_TYPE_SOFTWARE, p);
        ((View) viewFromThe80s.getParent()).setLayerType(View.LAYER_TYPE_SOFTWARE, p);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:[2/2/17]:我再次遇到这个问题,但这次只需要通过资源文件差异来修复它,而不是代码/逻辑差异

方法 2:基于 XML 的修复

有时,您无法编辑视图逻辑。例如,在我的例子中,两个视图共享同一个 RecyclerView.Adapter,一个有旋转视图,另一个没有。我需要视图/适配器逻辑保持不变,但 XML 布局和资源可能会有所不同。所以我采取了这种方法:

1.制作一个带有透明边框的形状 src/main/res/drawable/background_rotatable_color.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- transparent 1px border -->
    <item>
        <shape>
            <solid android:color="@android:color/transparent"/>
            <size android:width="16dp" android:height="16dp"/>
        </shape>
    </item>
    <!-- main color : inset by 1px so the transparent layer below shows so that when antialiasing is done, it blends better -->
    <item android:top="1px" android:right="1px" android:left="1px" android:bottom="1px">
        <shape>
            <solid android:color="@color/red"/>
        </shape>
    </item>
</layer-list>
Run Code Online (Sandbox Code Playgroud)

2. 应用形状和(可选):使用着色将其设置为所需的颜色
src/main/res/layout-land/item_product_details.xml

<TextView
    android:id="@+id/text_savings_banner"
    . . .
    android:background="@drawable/background_rotatable_color"
    android:backgroundTint="@color/blue_accent" /> <!-- optional but handy if you need to do this in a lot of places with different colors -->
Run Code Online (Sandbox Code Playgroud)