Как изменить оттенок кнопки Image на фокусе / нажатии - PullRequest
56 голосов
/ 11 июня 2010

У меня в приложении ImageButton, и мне нужно изменить оттенок изображения, когда кнопка pressed/focused. У меня есть ImageButton для получения src из XML-файла, который выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- pressed -->
    <item 
        android:state_pressed="true"
        android:tint="@color/black"
        android:drawable="@drawable/search"
        />

    <!-- focused -->
    <item 
        android:state_focused="true"
        android:tint="@color/black"
        android:drawable="@drawable/search"
        />

    <!-- default -->
    <item
        android:tint="@null"
        android:drawable="@drawable/search"
        />

</selector>

Однако оттенок не применяется при нажатии или фокусировке ImageButton - изображение отображается как обычно. Цвет черный определяется как #000000 как всегда. Есть идеи?

Ответы [ 9 ]

86 голосов
/ 09 августа 2010

Вы можете легко изменить оттенок в коде с помощью:

ImageButton button = (ImageButton) this.findViewById(R.id.button_i_want_to_modify);
button.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint

Надеюсь, это поможет.

JS

17 голосов
/ 21 декабря 2016

Вот как это сделать, используя только XML.В вашей папке drawable создайте селектор.Например: touch_selector.xml

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

    <!-- State when a row is being pressed, but hasn't yet been activated (finger down) -->
    <item android:state_pressed="true" android:color="@color/semi_slate" />

    <!-- When the view is "activated".  In SINGLE_CHOICE_MODE, it flags the active row
     of a ListView -->
    <item android:state_activated="true" android:color="@color/semi_slate" />

    <!-- Default, "just hangin' out" state. -->
    <item android:color="@android:color/transparent" />
</selector>

В моем представлении «Изображение» в формате xml я установил атрибут android: tint для рисования, созданного выше.

android:tint = "@drawable/touch_selector"

Весь код выглядел следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/poster"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:tint="@drawable/touch_selector" />

Это полностью XML-решение для нанесения оттенка на ImageView при нажатии или при активном.Аналогичное можно сделать для ImageButton

Обратите внимание, что это работает только для уровня API> = 21.

7 голосов
/ 07 июля 2016

Я нашел способ сделать это в XML (в API 21 и выше, по крайней мере).

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <bitmap
            android:src="@drawable/search"
            android:tint="@color/black"
            />
    </item>
    <item android:drawable="@drawable/search"/>
</selector>

Установив оттенок на растровом изображении, можно использовать один и тот же чертеж в xml без необходимостиперехватывать касания или создавать подкласс ImageView или ImageButton.

После создания селектора просто примените его в качестве источника ImageView или ImageButton.

6 голосов
/ 20 ноября 2015

Наконец-то я нашел решение для API <21: </p>

Button more = (Button) findViewById(R.id.more);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    more.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN);
} else {
    Drawable wrapDrawable = DrawableCompat.wrap(more.getBackground());
    DrawableCompat.setTint(wrapDrawable, color));
    more.setBackgroundDrawable(DrawableCompat.unwrap(wrapDrawable));
}

Пусть это поможет кому-то не потерять 2 часа!

2 голосов
/ 15 апреля 2015
bt.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        bt.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        bt.clearColorFilter(); // White Tint
                        return true; // if you want to handle the touch event
                }
                return false;
            }
        });
1 голос
/ 23 июня 2014

Я заметил, что есть некоторые запросы для людей, которые хотят знать, как сделать это в XML. Это на самом деле довольно просто. Это можно сделать с помощью layer-list

Drawable вашей кнопки (drawable / some_button.xml):

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/some_button_highlighted" />
    <item android:drawable="@drawable/some_button_image" />
</selector>

И это выделенный чертеж (drawable / some_button_highlighted.xml)

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/some_button_image"/>
    <item>
        <shape>
            <solid android:color="@color/highlighted_button_color" />
        </shape>
    </item>
</layer-list>

Теперь вы можете использовать это в любом другом xml:

...
android:drawable="@drawable/some_button"
...

Я надеюсь, что это поможет кому-то в будущем.

1 голос
/ 24 декабря 2013

Что я делаю, так это добавляю пользовательскую кнопку с функцией setColorFilter.

Таким образом, я могу использовать новую кнопку в XML.

public class CustomImageButton extends ImageButton {

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

public CustomImageButton(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    int maskedAction = event.getActionMasked();
    if (maskedAction == MotionEvent.ACTION_DOWN)
        setColorFilter(Color.argb(150, 155, 155, 155), PorterDuff.Mode.DST_IN);
    else if (maskedAction == MotionEvent.ACTION_UP)
        setColorFilter(null);
    return super.onTouchEvent(event);
}}
0 голосов
/ 29 августа 2016

Вы можете установить цвет (оттенок) из XML.

Установите transparent (android:background="@null") для background, затем используйте tint:

<ImageButton
     android:layout_width="wrap_content"
     android:layout_height="fill_parent"
     android:tint="@color/Amber_200"
     android:background="@null"
     android:src="@drawable/back_selector" />
0 голосов
/ 25 августа 2010

Поскольку вы определили селектор как src для ImageButton, Android будет AFAIK просто возьмет рисование, потому что это то, что соответствует типу src. Таким образом, оттенок не будет использоваться.

Тем не менее, у меня была похожая проблема: я также пытался использовать селектор, подобный вашему, но для значения android: tint ImageButton вместо android: src. Конечно, я опустил значения оттенков, которые есть в вашем селекторе. Это также решит вашу проблему, потому что вы хотите использовать один и тот же объект рисования для всех состояний. Любопытно, что каждый раз я получаю NumberFormatException, заявляя, что система не смогла проанализировать 'res / color / tint_selector.xml' (который действительно является моим селектором) как целое число. Если быть точным, мой код выглядит так:

Это мой селектор, сохраненный в /res/color/tint_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_pressed="true"
         android:color="#D3D3D3"/> <!-- pressed -->
   <item android:color="#ff000000"/> <!-- default -->
</selector>

И это соответствующий ImageButton:

<ImageButton android:id="@+id/program_help"
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content"
     android:src="@drawable/symbol"
     android:tint="@color/tint_selector">
</ImageButton>

Может быть, это вам немного поможет, хотя в настоящее время это не работает.

...