Android: użycie gradientu liniowego, gdy tło wygląda na pasiaste

85

Próbuję zastosować gradient liniowy do mojego ListView. Oto zawartość mojego pliku XML do rysowania:

 <?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>

Więc stosuję go do mojego ListView z:

android:background="@drawable/shape_background_grey"

Działa, ale na emulatorze i na prawdziwym urządzeniu wygląda na bardzo „opasany”.

Czy istnieje sposób na ograniczenie tego „zachowania”?

Francesco Laurita
źródło
18
Tylko aktualizacja: dodanie getWindow (). SetFormat (PixelFormat.RGBA_8888); getWindow (). addFlags (WindowManager.LayoutParams.FLAG_DITHER); w metodzie onCreate wydaje się działać również w przypadku hdpi z ekranem amoled (N1 / Desire)
Francesco Laurita
2
@FrancescoŚwietny! Pomogło na moim Galaxy S z Androidem 2.2 . Przekształć swój przydatny komentarz w odpowiedź, aby inni mogli na nią głosować.
java.is.for.desktop

Odpowiedzi:

84

Jak sugeruje Romain Guy:

listView.getBackground().setDither(true);

rozwiązuje mój problem

Jeśli to nie wystarczy, szczególnie w przypadku urządzeń AMOLED i / lub HDpi, spróbuj tego:

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
    Window window = getWindow();
    window.setFormat(PixelFormat.RGBA_8888);
}
Francesco Laurita
źródło
To nie działa na Androidzie 1.6 i nowszych. Zobacz mój drugi komentarz
Francesco Laurita
8
Czy możesz to zrobić w xml?
Thomas Ahle,
@Artem W moim przypadku na Androidzie> = 1.6 listView.getBackground().setDither(true);nie zadziała, musiałem nadpisać onAttachedToWindowmetodę.
Francesco Laurita
3
setDither () jest teraz przestarzały
GuillermoMP
39

Możesz po prostu włączyć dithering na swoim obiekcie do rysowania.

Romain Guy
źródło
1
Tak to działa! Dziękuję Ci bardzo. Swoją drogą, próbowałem użyć tej właściwości w definicji XML, którą można rysować, ale ponieważ lepiej czytam dokumentację, ta właściwość jest obsługiwana tylko dla elementu selektora.
Francesco Laurita
Niestety nie działa to na Androidzie w wersji> 1.5. Testowałem na prawdziwym urządzeniu z Androidem 1.6 i Androidem 1.5. Dodanie ditheringu do mojego gradientu do rysowania nie działa. Oba urządzenia mają rozdzielczość 320 x 480 (180 ppi). Jakieś sugestie? Tnx
Francesco Laurita
3
setDither()została wycofana na poziomie API 23. Ta właściwość jest teraz ignorowana.
Tot Zam
9

Umieść to w swojej aktywności:

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
    Window window = getWindow();
    window.setFormat(PixelFormat.RGBA_8888);
}
Miša Peić
źródło
3

U mnie na HTC Desire działa tak

window.getDecorView().getBackground().setDither(true);
Sebastian
źródło
1
setDither()została wycofana na poziomie API 23. Ta właściwość jest teraz ignorowana.
Tot Zam
2

U mnie pasmowanie zniknęło po ustawieniu androida: useLevel = "true" na gradiencie: 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>

Ale najpierw spróbowałem użyć listy warstw z „szumem”, który można narysować, aby usunąć pasmowanie, pomaga, ale nadal jest pewne pasmo.

<?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>

Utworzony i użyty przeze mnie plik „noise_repeater”

wprowadź opis obrazu tutaj

TouchBoarder
źródło
2

Jeśli dithering i ustawienie RGBA_888 nie pomagają w niektórych telefonach, rozwiązaniem może być ustawienie elementu layerTypena software, aby wyłączyć akcelerację sprzętową

android:layerType="software"

To rozwiązało mój problem z telefonem Samsung S5.

peter.bartos
źródło
0

Jedyną rzeczą, która działała dla mnie, było ustawienie lekko przezroczystego kanału alfa zarówno na startColor, jak i 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>

Wpadłem na pomysł, aby to wypróbować z tego drugiego pytania SO: android: dither = „true” nie waha się, co jest nie tak?

Greg
źródło