Android: 使用线性渐变作为背景看起来带状

我试图应用一个线性渐变到我的 ListView。 这是我的可绘制 xml 的内容:

 <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#3A3C39"
android:endColor="#181818"
android:angle="270"
/>
<corners android:radius="0dp" />
</shape>

所以我将它应用到我的 ListView:

android:background="@drawable/shape_background_grey"

它工作,但它看起来非常“带”在模拟器和一个真正的设备也。

有没有办法减少这种“行为”?

78279 次浏览

You can simply enable dithering on your Drawable object.

As Romain Guy suggests:

listView.getBackground().setDither(true);

solves my problem

If this is not enough especially for AMOLED and/or hdpi devices try this:

@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Window window = getWindow();
window.setFormat(PixelFormat.RGBA_8888);
}

Put this in your Activity:

@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Window window = getWindow();
window.setFormat(PixelFormat.RGBA_8888);
}

For me on HTC Desire works like this

window.getDecorView().getBackground().setDither(true);

For me the banding disappeared when I set the android:useLevel="true" on the gradient: gradient_dark.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient android:startColor="#464646"
android:endColor="#323232"
android:angle="270"
android:type="linear"
android:useLevel="true"
/>
</shape>

But first I tried using a Layer-List with a "noise" drawable to remove the banding, it helps but there is still some banding.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/gradient_dark"/>
<item>
<bitmap
android:gravity="center"
android:src="@drawable/noise_repeater"
android:tileMode="repeat" />
</item>


</layer-list>

The "noise_repeater" drawable i created and used

enter image description here

The only thing that worked for me was to set a slightly-transparent alpha channel on both the startColor and endColor.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#FE3A3C39"
android:endColor="#FE181818"
android:angle="270"
/>
</shape>

I got the idea to try this from this other SO question: android:dither=“true” does not dither, what's wrong?

If the dither and RGBA_888 setting don't help on some phones, the solution can be to set the element layerType to software, to disable the hardware acceleration

android:layerType="software"

This fixed my problem on a Samsung S5 phone.