Przycisk Android z ikoną i tekstem

92

W mojej aplikacji mam kilka takich przycisków:

    <Button
        android:id="@+id/bSearch"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="Search"
        android:textSize="24sp" />

Próbuję utworzyć ten sam przycisk z tekstem i ikoną. android: drawableLeft nie działa dla mnie (może tak, ale nie wiem, jak ustawić maksymalną wysokość ikony).

Utworzyłem więc LinearLayout z ImageView i TextView i sprawiłem, że zachowuje się jak przycisk:

    <LinearLayout
        android:id="@+id/bSearch2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/btn_default"
        android:clickable="true"
        android:padding="16dp"
        android:orientation="horizontal" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="5dp"
            android:adjustViewBounds="true"
            android:maxHeight="30dp"
            android:maxWidth="30dp"
            android:scaleType="fitCenter"
            android:src="@drawable/search_icon" />

        <TextView
            android:id="@+id/tvSearchCaption"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:textSize="24sp"
            android:paddingRight="30dp"
            android:gravity="center"
            android:text="Search" />
    </LinearLayout>

Mój nowy przycisk jest dokładnie tym, czego chcę (rozmiar czcionki, ikona i rozmieszczenie tekstu). Ale nie wygląda jak moje domyślne przyciski:

wprowadź opis obrazu tutaj

Próbowałem więc zmienić tło i kolor tekstu mojego nowego przycisku:

Button Search = (Button) findViewById(R.id.bSearch);
LinearLayout bSearch2 = (LinearLayout) findViewById(R.id.bSearch2);
bSearch2.setBackground(bSearch.getBackground());
TextView tvSearchCaption = (TextView)findViewById(R.id.tvSearchCaption);
tvSearchCaption.setTextColor(bSearch.getTextColors().getDefaultColor());

Daje to dziwny wynik, mój stary przycisk jest pomieszany:

wprowadź opis obrazu tutaj

Kiedy zmieniam kolejność tych dwóch przycisków w kodzie XML, więc „nowy przycisk” pojawia się jako pierwszy, pojawia się kolejny dziwny wynik:

wprowadź opis obrazu tutaj

Teraz zauważyłem, że kiedy próbuję wcisnąć stary przycisk, naciskany jest nowy.

Jakieś pomysły?

Dusan
źródło

Odpowiedzi:

283

Spróbuj tego.

<Button
    android:id="@+id/bSearch"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:text="Search"
    android:drawableLeft="@android:drawable/ic_menu_search"
    android:textSize="24sp"/>
Liem Vo
źródło
3
Wygląda dokładnie tak, jak chcę, ale chcę używać własnych ikon, a nie domyślnych ikon Androida. Moje ikony są większe. Czy to oznacza, że ​​muszę tworzyć mniejsze mapy bitowe dla każdej rozdzielczości? Czy jest jakiś parametr, który pozwala mi kontrolować rozmiar ikony?
Dusan,
To jest poprawne. Musisz utworzyć inny rozmiar obrazu dla każdej rozdzielczości
Liem Vo
Ok, dziękuję za pomoc, ale teraz mam kolejne pytanie ... Moje ikony są jasne, ponieważ tekst jest biały na ciemnym przycisku, jak widać na obrazkach w moim pytaniu. Aplikacja jest ustawiona do korzystania z motywu, który jest dostępny w wersji na Androida. Moje przykłady pochodzą z Androida 4.3. Gdy aplikacja działa na Androidzie 2.3.3, domyślne przyciski są jasne i mają ciemny tekst. Coś w rodzaju przycisku na moim pierwszym zdjęciu. Czy istnieje sposób na zapewnienie alternatywnej mapy bitowej dla ikony działającej na starszych urządzeniach? Mam nadzieję, że rozumiesz moje pytanie :)
Dusan
To jest dobre pytanie. Możesz zdefiniować inny styl dla swojej ikony, chłodniejszy styl tekstu dla każdego poziomu API (oznacza to wersję systemu operacyjnego Android). Możesz zobaczyć foldery values-v11, values-v14.
Liem Vo
2
Możesz także dodać dopełnienie do ikony android: drawablePadding = ""
Asad Mirza
15

Aby dodać obraz z lewej, prawej, góry lub dołu, możesz użyć następujących atrybutów:

android:drawableLeft
android:drawableRight
android:drawableTop
android:drawableBottom

Przykładowy kod podano powyżej. Możesz to również osiągnąć za pomocą układu względnego.

user3515854
źródło
Jak to zrobić programowo
Sujay ONZ
1
Możesz powiedzieć android:drawableStartzamiast Left i android:drawableEndzamiast Right.
Simão Garcia
@ SimãoGarcia * powinien. Początek powinien zastąpić prawy, a koniec lewy we wszystkich miejscach. Ma to zapewnić możliwość czytania zarówno od prawej do lewej, jak i od lewej do prawej, ponieważ niektóre inne kraje czytają inaczej.
Carson J.
11

Dla każdego, kto chce robić to dynamicznie setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) pomocny będzie obiekt przycisków.

Próba

Button search = (Button) findViewById(R.id.yoursearchbutton);
search.setCompoundDrawables('your_drawable',null,null,null);
Kennedy Nyaga
źródło
5
Użycie setCompoundDrawables nie miało wpływu na interfejs użytkownika. Zamiast tego użyto setCompoundDrawablesWithIntrinsicBounds i to zadziałało.
Aldo
5

To jest to, czego naprawdę chcesz.

<Button
       android:id="@+id/settings"
       android:layout_width="190dp"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
       android:background="@color/colorAccent"
       android:drawableStart="@drawable/ic_settings_black_24dp"
       android:paddingStart="40dp"
       android:paddingEnd="40dp"
       android:text="settings"
       android:textColor="#FFF" />
Stackoverflower
źródło
4

Możesz użyć Biblioteki komponentów materiałów i MaterialButtonkomponentu.
Użyj atrybutów app:iconi app:iconGravity="start".

Coś jak:

  <com.google.android.material.button.MaterialButton
        style="@style/Widget.MaterialComponents.Button.Icon"
        app:icon="@drawable/..."
        app:iconGravity="start"
        ../>

wprowadź opis obrazu tutaj

Gabriele Mariotti
źródło
Zwróć uwagę, że jeśli masz motyw Material Design dla swojej aplikacji, standardowy widżet Button jest automatycznie zawyżany jako MaterialButton. Per here - material.io/develop/android/components/buttons
dodgy_coder
2

Odpowiedź @Liem Vo jest prawidłowa, jeśli używasz android.widget.Button bez nadpisywania. Jeśli nadpisujesz motyw za pomocą MaterialComponents, nie rozwiąże to problemu.

Więc jeśli tak

  1. Za pomocą com.google.android.material.button.MaterialButton lub
  2. Zastępowanie AppTheme przy użyciu MaterialComponents

Użyj parametru app: icon .

<Button
    android:id="@+id/bSearch"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:text="Search"
    android:textSize="24sp"
    app:icon="@android:drawable/ic_menu_search" />
Chamin Wickramarathna
źródło