Niestandardowy obraz pola wyboru android


182

Czy istnieje prosty sposób na użycie niestandardowego obrazu dla pola wyboru? Chcę powielić zachowanie Gmaila oznaczone gwiazdką. Chcę mieć pole wyboru, które po zaznaczeniu jest wypełnioną gwiazdą. A kiedy odznaczona, jest pusta gwiazda. Czy muszę korzystać z podglądu obrazu i samodzielnie tworzyć własną logikę?

Odpowiedzi:


128

Pola wyboru będące dziećmi przycisku, możesz po prostu nadać swojemu polu wyboru obraz tła z kilkoma stanami, jak opisano tutaj , pod „Stylem przycisku”:

... i przykład tutaj :


26
Dzięki, faktycznie znalazłem dokładnie to, czego potrzebowałem tutaj it-ride.blogspot.com/2010/04/... ale musiałbym to zrobić po swojemu, gdybym chciał uzyskać prawdziwy obraz niestandardowy = P
Falmarri

2
Dziękuję Ci. Dokładnie to, czego szukałem - wymyśliłem cały stan, ale ustawiłem android: tło zamiast androida: przycisk i zamiast tego otrzymałem 2 przyciski. Teraz wszystko działa dobrze.
Artem Russakovskii,

1
-1. Poniższe android:buttonrozwiązanie jest znacznie lepsze niż użycie atrybutu tła!
Orabîg

8
@ Orabîg: To zdanie jest złe. Odpowiedź na pytanie jest doskonale („Niestandardowy obraz pola wyboru”). Fakt, że istnieje skrót do tego konkretnego przycisku oznaczonego gwiazdką, nie unieważnia tej odpowiedzi.
ereOn

Chociaż jest to może stary post, chciałbym dodać, że studio Android również używa metody android: button = "@ android: drawable / btn_star"
Angry 84

288

Utwórz rysunkowy selektor pola wyboru:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/checkbox" 
          android:state_checked="false"/>
    <item android:drawable="@drawable/checkboxselected" 
          android:state_checked="true"/>
    <item android:drawable="@drawable/checkbox"/>    
</selector>

Upewnij się, że pole wyboru jest takie android:button="@drawable/checkbox_selector"

<CheckBox
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:button="@drawable/checkbox_selector"
    android:text="CheckBox"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="@color/Black" />

W jakim rekordzie określasz ten selektor? W samym pliku XML, w którym określasz również CheckBox?
Tom Hammond

Tom: utwórz selektor w folderze do rysowania i pole wyboru w folderze układu
Mohamed Hisham Ibn Hanifa

Musiałem zmienić „przycisk” na „tło” w CheckBox
Francisco Corrales Morales


2
Uaktualniłem swój projekt do Androida x, po czym nie mogłem dostosować mojego pola wyboru, jak powiedziałeś przed 21 poziomem interfejsu API i Androida: przycisk nie działa.
Misagh Aghakhani

44

Skopiuj plik btn_check.xml z android-sdk / platform / android - # / data / res / drawable do folderu graficznego projektu i zmień stany obrazu „włączony” i „wyłączony” na obrazy niestandardowe.

Wtedy twój xml będzie po prostu potrzebował android:button="@drawable/btn_check"

<CheckBox
    android:button="@drawable/btn_check"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="true" />

Jeśli chcesz użyć różnych domyślnych ikon Androida, możesz użyć android:button="@android:drawable/..."


2
Zła rada. Ikony mogą być zmieniane z wersji na wersję i mogą w ogóle znikać. Jeśli naprawdę podoba Ci się domyślna ikona, możesz pobrać ją ze źródeł.
Korniltsev Anatoly

Czy mówienie, że odwoływanie się do domyślnych ikon bezpośrednio za pomocą „@android: drawable / ...” jest złym pomysłem, czy ten proces całkowicie?
WOUNDEDStevenJones

2
Przykład: odniesienie do ikon holo spowoduje awarię aplikacji na urządzeniach o strukturze plastra miodu. Naprawdę trudno jest utrzymywać i debugować takie problemy. Więc zwykle kopiuję nie tylko xml, ale także obrazy, aby być pewnym, że zasoby zostaną znalezione. Jest to również bardzo ważne, aby interfejs użytkownika wyglądał tak samo na każdym urządzeniu.
Korniltsev Anatoly

15

res / drawable / day_selector.xml

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android" >
        <item android:drawable="@drawable/dayselectionunselected"
              android:state_checked="false"/>
        <item android:drawable="@drawable/daysselectionselected"
              android:state_checked="true"/>
        <item android:drawable="@drawable/dayselectionunselected"/>
    </selector>

res / layout / my_layout.xml

<CheckBox
    android:id="@+id/check"
    android:layout_width="39dp"
    android:layout_height="39dp"
    android:background="@drawable/day_selector"
    android:button="@null"
    android:gravity="center"
    android:text="S"
    android:textColor="@color/black"
    android:textSize="12sp" />

1
Niektóre wyjaśnienia pomogłyby nowym użytkownikom zrozumieć, w jaki sposób Twój kod rozwiązuje problem.
Brian Tompsett - 汤 莱恩

7

Jeśli masz otwarty kod źródłowy Androida, definicję stylów znajdziesz pod:
src / frameworks / base / core / res / res / values

<style name="Widget.CompoundButton.CheckBox">
    <item name="android:background">
        @android:drawable/btn_check_label_background
    </item>
    <item name="android:button">
        ?android:attr/listChoiceIndicatorMultiple
    </item>
</style>

4

Spróbuj -

package com;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;



public class CheckBoxImageView extends ImageView implements View.OnClickListener {
    boolean checked;
    int defImageRes;
    int checkedImageRes;
    OnCheckedChangeListener onCheckedChangeListener;

    public CheckBoxImageView(Context context, AttributeSet attr, int defStyle) {
        super(context, attr, defStyle);
        init(attr, defStyle);
    }

    public CheckBoxImageView(Context context, AttributeSet attr) {
        super(context, attr);
        init(attr, -1);
    }

    public CheckBoxImageView(Context context) {
        super(context);
    }

    public boolean isChecked() {
        return checked;
    }

    public void setChecked(boolean checked) {
        this.checked = checked;
        setImageResource(checked ? checkedImageRes : defImageRes);
    }

    private void init(AttributeSet attributeSet, int defStyle) {
        TypedArray a = null;
        if (defStyle != -1)
            a = getContext().obtainStyledAttributes(attributeSet, R.styleable.CheckBoxImageView, defStyle, 0);
        else
            a = getContext().obtainStyledAttributes(attributeSet, R.styleable.CheckBoxImageView);
        defImageRes = a.getResourceId(0, 0);
        checkedImageRes = a.getResourceId(1, 0);
        checked = a.getBoolean(2, false);
        a.recycle();
        setImageResource(checked ? checkedImageRes : defImageRes);
        setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        checked = !checked;
        setImageResource(checked ? checkedImageRes : defImageRes);
        onCheckedChangeListener.onCheckedChanged(this, checked);
    }

    public void setOnCheckedChangeListener(OnCheckedChangeListener onCheckedChangeListener) {
        this.onCheckedChangeListener = onCheckedChangeListener;
    }

    public static interface OnCheckedChangeListener {
        void onCheckedChanged(View buttonView, boolean isChecked);
    }
}

Dodaj ten atrybut -

<declare-styleable name="CheckBoxImageView">
        <attr name="default_img" format="integer"/>
        <attr name="checked_img" format="integer"/>
        <attr name="checked" format="boolean"/>
</declare-styleable>

Użyj jak -

 <com.adonta.ziva.consumer.wrapper.CheckBoxImageView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/checkBox"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:clickable="true"
        android:padding="5dp"
        app:checked_img="@drawable/check_box_checked"
        app:default_img="@drawable/check_box" />

Naprawi wszystkie twoje problemy.


Brakuje metod onSaveInstanceState()i onRestoreInstanceState(), myślę, że sprawdzony stan zostałby utracony podczas rotacji
EpicPandaForce

2

Inną opcją jest użycie ToggleButton z zerowym tłem i niestandardowym przyciskiem.

Poniżej przykład z selektorem koloru tekstu.

<ToggleButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:button="@drawable/toggle_selector"
    android:background="@null"
    android:paddingLeft="10dp"
    android:layout_centerHorizontal="true"
    android:gravity="center"
    android:textColor="@drawable/toggle_text"
    android:textOn="My on state"
    android:textOff="My off state" />

toggle_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:state_checked="true"
        android:drawable="@drawable/state_on" />

    <item
        android:drawable="@drawable/state_off" />

</selector>

toggle_text.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:state_checked="true"
        android:color="@color/app_color" />

    <item
        android:color="@android:color/darker_gray" />

</selector>

2

Jeśli używasz niestandardowych adapterów, android:focusable="false"a nie android:focusableInTouchMode="false"jest konieczne, aby elementy listy można było klikać podczas korzystania z pola wyboru.

<CheckBox
        android:id="@+id/checkbox_fav"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:button="@drawable/checkbox_layout"/>

W rysunku> checkbox_layout.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/uncked_checkbox"
        android:state_checked="false"/>
    <item android:drawable="@drawable/selected_checkbox"
        android:state_checked="true"/>
    <item android:drawable="@drawable/uncked_checkbox"/>
</selector>

1

Jeśli używasz androidx.appcompat: appcompat i chcesz niestandardowego rysowalnego (typu selectorz android:state_checked) do pracy na starych wersjach platformy oprócz nowych wersji platformy, musisz użyć

    <CheckBox
        app:buttonCompat="@drawable/..."

zamiast

    <CheckBox
        android:button="@drawable/..."

1

Na podstawie odpowiedzi Enselica i Rahula.

Działa dla mnie (przed i po API 21):

<CheckBox
    android:id="@+id/checkbox"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:text=""
    android:gravity="center"

    android:background="@drawable/checkbox_selector"
    android:button="@null"
    app:buttonCompat="@null" />
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.