Jak wyszarzać przycisk?

103

Mam przycisk zdefiniowany, jak pokazano poniżej. Kiedy chcę go wyłączyć, używam my_btn.setEnabled(false), ale chciałbym też to wyszarzać. Jak mogę to zrobić?

Dzięki

<Button android:id="@+id/buy_btn" style="@style/srp_button" />

style / srp_button

<style name="srp_button" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/btn_default</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textColor">#ffffff</item>
    <item name="android:textSize">14sp</item>
    <item name="android:typeface">serif</item>
    <item name="android:paddingLeft">30dp</item>
    <item name="android:paddingRight">30dp</item>
    <item name="android:paddingTop">5dp</item>
    <item name="android:paddingBottom">5dp</item>
</style>

do rysowania / btn_default.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/pink" />
    <corners android:radius="6dp" />
</shape>
lip
źródło

Odpowiedzi:

57

btn_defaut.xmlJako selektor musisz podać 3 lub 4 stany .

  1. Stan sprasowany
  2. Stan domyślny
  3. Stan skupienia
  4. Stan włączony (stan wyłączenia z fałszywym wskazaniem; patrz komentarze)

Zapewnisz odpowiednio efekt i tło dla stanów.

Oto szczegółowe omówienie: Standardowy przycisk Androida w innym kolorze

Adil Soomro
źródło
Żeby więc to wyszarzać, muszę zmienić kolor tła ORAZ kolor tekstu w stanie wyłączonym? Nie ma sposobu, aby po prostu dodać przezroczysty pierwszy plan?
lipiec
3
Tak! to, co podasz android:state_disable="true", pokaże stan, gdy przycisk jest wyłączony, w łatwy i zalecany sposób.
Adil Soomro,
i gdzie mogę określić kolor tekstu dla stanu wyłączonego? Wygląda na to, że można określić tylko tło ... Zadałem w tym celu nowe pytanie: stackoverflow.com/questions/8743584/…
lipiec
17
Nie ma android:state_disable="true", prawda? Czy masz na myśli android:state_enabled="false"?
caw
@MarcoW .: tak, masz całkowitą rację. Przepraszamy za niewłaściwy atrybut.
Adil Soomro,
173

Możesz również sprawić, że będzie wyglądał jako wyłączony, ustawiając alfa (dzięki czemu będzie półprzezroczysty). Jest to szczególnie przydatne, jeśli tłem przycisku jest obraz i nie chcesz tworzyć dla niego stanów.

button.setAlpha(.5f);
button.setClickable(false);

aktualizacja: powyższe rozwiązanie napisałem przed Kotlinem i jako debiutant. Jest to bardziej „szybkie i brudne” rozwiązanie, ale nie polecam go w środowisku zawodowym.

Dzisiaj, gdybym chciał mieć ogólne rozwiązanie działające na dowolnym przycisku / widoku bez konieczności tworzenia listy stanów, stworzyłbym rozszerzenie Kotlin.

fun View.disable() {
    getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY)
    setClickable(false)
}

W Javie możesz zrobić coś podobnego za pomocą statycznej funkcji util i po prostu musisz przekazać widok jako zmienną. Nie jest tak czysty, ale działa.

Siavash
źródło
4
Czytałem, że wywołania setAlpha są drogie dla procesora. Czy ktoś może potwierdzić?
Ali Kazi
@AliKazi to zależy od typu twojego View. Od tego postu G + : „Jeśli Państwa zdaniem nie zawierają nakładających polecenia rysowania, setAlpha()jest zoptymalizowany z dala, a my po prostu zmodyfikować malowania obiektów w celu zastosowania odpowiedniej alfa Dzieje się tak kiedy. View.hasOverlappingRendering()Zwraca true. ImageViewS i TextViews bez tła rozciągliwej są wspólne kandydatami do tego optymalizacji. Jeśli jesteś w takiej sytuacji, użyj setAlpha()tyle, ile chcesz. ”.
Sufian,
1
@Sufian Thanks. Ale żeby być bezpieczniejszym, oparłem się na prostym StateListDrawable dla każdego przycisku. Jak to zrobiłem, opublikowałem jako nową odpowiedź. Dołączyłem linki do miejsc, w których dowiedziałem się, że alfa źle wpływa na wydajność.
Ali Kazi
Wizualnie nieprzyjazny dla użytkownika
Farid
które faktycznie wizualnie wyłączają widok. dzięki @Siavash
Akash Bisariya
54

Najłatwiejszym rozwiązaniem jest ustawienie filtru kolorów na obrazie tła przycisku, jak widziałem tutaj

Możesz wykonać następujące czynności:

if ('need to set button disable')
    button.getBackground().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY);
else
    button.getBackground().setColorFilter(null);

Mam nadzieję, że komuś pomogłem ...

Drzewiasty
źródło
Najbardziej podoba mi się to podejście. Dzięki!
złap
2
Takie podejście ma potencjał, ale wynikowy kolor nie zawsze jest tym, czym myślisz, że będzie. Na przykład pomarańczowy przycisk z pomnożonym kolorem Szary daje ciemnoczerwony kolor, a nie wyblakły pomarańczowy.
Someone Somewhere
4
może Mode.SRC_INnależy użyć zamiast funkcji Mnożenie. Zobacz stackoverflow.com/a/17112876/550471
Someone Somewhere
To działa, ale po zmieszaniu dwa kolory zamieniają się w inny kolor
Shamsul Arefin Sajib
Niesamowite! tak czysty.
Milind Chaudhary
22

Wszystkie podane odpowiedzi działają dobrze, ale pamiętam, że nauczyłem się, że użycie setAlpha może być złym pomysłem pod względem wydajności (więcej informacji tutaj ). Dlatego utworzenie StateListDrawable jest lepszym pomysłem do zarządzania wyłączonymi stanami przycisków. Oto jak:

Utwórz plik XML btn_blue.xml w folderze res / drawable:

<!-- Disable background -->
<item android:state_enabled="false"
      android:color="@color/md_blue_200"/>

<!-- Enabled background -->
<item android:color="@color/md_blue_500"/>

Utwórz styl przycisku w res / values ​​/ styles.xml

<style name="BlueButton" parent="ThemeOverlay.AppCompat">
      <item name="colorButtonNormal">@drawable/btn_blue</item>
      <item name="android:textColor">@color/md_white_1000</item>
</style>

Następnie zastosuj ten styl do swojego przycisku:

<Button
     android:id="@+id/my_disabled_button"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:theme="@style/BlueButton"/>

Teraz, gdy zadzwonisz do btnBlue.setEnabled(true)LUB, btnBlue.setEnabled(false)kolory stanu zostaną automatycznie przełączone.

Ali Kazi
źródło
13

Powinieneś utworzyć plik XML dla wyłączonego przycisku ( drawable / btn_disable.xml )

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/grey" />
    <corners android:radius="6dp" />
</shape>

I utwórz selektor dla przycisku ( drawable / btn_selector.xml )

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/btn_disable" android:state_enabled="false"/>
    <item android:drawable="@drawable/btn_default" android:state_enabled="true"/>
    <item android:drawable="@drawable/btn_default" android:state_pressed="false" />

</selector>

Dodaj selektor do swojego przycisku

<style name="srp_button" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/btn_selector</item>
</style>
Willy Chen
źródło
12

Ustaw klikalne jako fałsz i zmień kolor tła na:

callButton.setClickable(false);
callButton.setBackgroundColor(Color.parseColor("#808080"));
Saty
źródło
2
Button button = (Button)findViewById(R.id.buy_btn);
button.setEnabled(false);
Leon van Noord
źródło
14
To nie odpowiada na pytanie.
Quality Catalyst
1

Użyłem do tego tego kodu:

ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
profilePicture.setColorFilter(filter);
Dominik
źródło
0

Wypróbowałem powyższe rozwiązania, ale żadne z nich nie wydawało mi się skuteczne. Poszedłem z następującą opcją:

<!-- button_color_selector.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorAccent" android:state_enabled="true"/>
    <item android:color="@color/colorAccentLight" android:state_enabled="false"/>
</selector>
<com.google.android.material.button.MaterialButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:backgroundTint="@color/button_color_selector"
                .../>
André Ramon
źródło