Як встановити ефект натискання кнопки в Android?


105

В Android, коли я встановлюю фонове зображення на кнопку, я не бачу жодного впливу на кнопку.

Мені потрібен певний ефект на кнопку, щоб користувач міг розпізнати, що натиснула кнопку.

Кнопка повинна бути темною протягом декількох секунд, коли вона клацнула, і що мені робити для цього?

Дякую.



Наступний метод дозволяє використовувати один styleclass шкіру всі ваші кнопки, незалежно від їх тексту: stackoverflow.com/questions/5327553 / ...
— Zack Marrapese

ні, я не використовую кнопку зображення, я використовую звичайну кнопку будь-яким простим способом для цього?
— Jignesh Ansodariya

3
Дуже приємний підручник: dibbus.com/2011/02/gradient-buttons-for-android
— Pratik Butani

Відповіді:


154

Цього можна досягти, створивши файл, що виписує xml, що містить список станів для кнопки. Наприклад, якщо ви створюєте новий XML-файл під назвою "button.xml" із таким кодом:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/YOURIMAGE" />
    <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/gradient" />
    <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/gradient" />
    <item android:drawable="@drawable/YOURIMAGE" />
</selector>

Щоб зберегти фонове зображення із затемненим виглядом при натисканні, створіть другий файл XML і назвіть його gradient.xml із наступним кодом:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <bitmap android:src="@drawable/YOURIMAGE"/>
    </item>
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android">
            <gradient android:angle="90" android:startColor="#880f0f10" android:centerColor="#880d0d0f" android:endColor="#885d5d5e"/>
        </shape>
    </item>
</layer-list>

У xml вашої кнопки встановіть фон як кнопку xml, наприклад

android:background="@drawable/button"

Сподіваюся, це допомагає!

Редагувати: Змінено вищевказаний код для відображення зображення (YOURIMAGE) у кнопці на відміну від кольору блоку.


Тоді, де я можу встановити Зображення для фону кнопки, щоб встановити Зображення потрібно
— Jignesh Ansodariya

1
Відредаговано, щоб показати, як використовувати фонове зображення зі станом XML. Замініть ВАШУ ІНСТРУМЕНТУ ресурсом зображення у вашому малювальному каталозі.
— Ljdawson

Це працює лише в тому випадку, якщо src кнопки прямокутний. Якщо графічний малюнок src має будь-яку форму, відмінну від цієї, градієнт буде застосований і до фону, і це сумно.
— Ренато Лочетті

Насправді, завжди можна використовувати іншу форму у списку шарів
— Ljdawson

2
поки я використовую зображення, воно працює для мене .. але коли я використовую фон Xml це не працює ...
— DKV

88

Це простіше, коли у вас багато кнопок зображення, і ви не хочете писати xml-s для кожної кнопки.

Версія Котліна:

fun buttonEffect(button: View) {
    button.setOnTouchListener { v, event ->
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                v.background.setColorFilter(-0x1f0b8adf, PorterDuff.Mode.SRC_ATOP)
                v.invalidate()
            }
            MotionEvent.ACTION_UP -> {
                v.background.clearColorFilter()
                v.invalidate()
            }
        }
        false
    }
}

Версія Java:

public static void buttonEffect(View button){
    button.setOnTouchListener(new OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    v.getBackground().setColorFilter(0xe0f47521,PorterDuff.Mode.SRC_ATOP);
                    v.invalidate();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    v.getBackground().clearColorFilter();
                    v.invalidate();
                    break;
                }
            }
            return false;
        }
    });
}

2
Я використовую це у своєму коді, і єдина проблема, яку я помітив до цього часу, - це те, що кнопка поводиться дивно, коли розміщується в ScrollView.
— Finnboy11

Це дійсно чудове рішення, і це має бути правильна відповідь
— Бірай Залавадія

Як це краще? Дизайн слід зберігати поза кодом, чи не так?
— Помилки трапляються

Це просто просте рішення цієї проблеми. Якщо у вас багато кнопок і ви не хочете створювати xmls для кожного окремого, це може бути корисним.
— Андрас

О Боже мій! Уявіть, що у фрагменті є 5 кнопок ... У вас буде цілий букет цього кодового коду ... Як потім його переробляти? Змінити кольоровий фільтр для всіх кнопок у всіх видах діяльності? Імхо, це ваш наступний розробник не буде таким щасливим ..
— Лев Droidcoder

84

Створіть свій AlphaAnimationОб’єкт, який вирішить, наскільки буде ефект згасання кнопки, і нехай він запускатиметься onClickListenerз ваших кнопок

Наприклад :

private AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);

// some code

public void onClick(View v) {
    v.startAnimation(buttonClick);
}

звичайно, це лише спосіб, а не самий кращий, це просто простіше


5
Що мені подобається в цьому рішенні, це те, що воно не потребує створення багатьох селекторів, коли у вас є багато кнопок, кожен з яких має власні власні зображення.
— Піт

2
Це не згасає кнопки при натисканні вниз, вона лише згасає на частку секунди після виявлення клацання і пальця користувача вже піднято.
— Даг Восс

1
Приємно і просто

@Doug Voss, ви можете встановити тривалість анімації, щоб зробити її довшою
— Ахмед Адель Ісмаїл

як щодо OnLongClick та "circularReveal"?
— Acauã Pitta

44

Ви можете просто використовувати передній план для Viewдосягнення ефекту, що можна натискати:

android:foreground="?android:attr/selectableItemBackground"


Для використання з темною темою додайте також тему до свого layout(щоб ефект, який можна натиснути, був зрозумілим):

android:theme="@android:style/ThemeOverlay.Material.Dark"

5
Найпростіший спосіб реалізації. FYI, Attribute android: передній план не впливає на рівні API нижче 23
— dolgom

1
Найпростіше рішення.
— Джеррі Чонг

2
Це має бути прийнятою відповіддю, набагато простішим, і це додає приємний ефект анімації пульсацій.
— Тайлер

1
@dolgom Для рівня API <23 використовуйте його на атрибут "background". Отже: android: background = "? android: attr / selectableItemBackground"
— Z3R0

24

Щоб ваш предмет відповідав вигляду і вигляду системи, спробуйте посилатись на системний атрибут android:attr/selectableItemBackgroundу фоновому режимі або тезі переднього плану потрібного перегляду:

<ImageView
    ...
    android:background="?android:attr/selectableItemBackground"      
    android:foreground="?android:attr/selectableItemBackground"
    ...
/>

Використовуйте обидва атрибути, щоб отримати бажаний ефект до / після рівня 23 API відповідно.

https://stackoverflow.com/a/11513474/4683601


2
На сьогодні найпростіше рішення. Дякую!
— tykom

9

Або використовуючи лише одне фонове зображення, ви можете досягти ефекту клацання, використовуючи setOnTouchListener

Два способи

((Button)findViewById(R.id.testBth)).setOnTouchListener(new OnTouchListener() {

      @Override
        public boolean onTouch(View v, MotionEvent event) {
          switch (event.getAction()) {
              case MotionEvent.ACTION_DOWN: {
                  Button view = (Button) v;
                  view.getBackground().setColorFilter(0x77000000, PorterDuff.Mode.SRC_ATOP);
                  v.invalidate();
                  break;
              }
              case MotionEvent.ACTION_UP:
                  // Your action here on button click
              case MotionEvent.ACTION_CANCEL: {
                  Button view = (Button) v;
                  view.getBackground().clearColorFilter();
                  view.invalidate();
                  break;
              }
          }
          return true;
        }
});

введіть тут опис зображення

І якщо ви не хочете використовувати setOnTouchLister, інший спосіб цього досягти

    myButton.getBackground().setColorFilter(.setColorFilter(0xF00, Mode.MULTIPLY);

    StateListDrawable listDrawable = new StateListDrawable();
    listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
    listDrawable.addState(new int[] {android.R.attr.defaultValue}, myButton);

    myButton.setBackgroundDrawable(listDrawable);

є помилки в коді 2-м способом. Що таке функція getCurrent ()? Також myButton не є Dravable, тому його не можна додати як стан.
— Ехтешам Хасан

Дякуємо, що вказали на помилку. Я виправив це, і myButton - це екземпляр класу Button, який постачає метод setBackgroundDravable, і він бере екземпляри Dravable, отже, це буде працювати.
— Vinayak Bevinakatti

Ознайомтеся з моєю відповіддю, яка ґрунтується на вашому другому підході. stackoverflow.com/a/39430738/5229515
— Етешам Hasan

Це, мабуть, має бути "повернути помилкове" в кінці, так що воно не споживає події, і будь-які додаткові OnClickListeners можуть бути викликані.
— Doug Voss

3

просто хочете додати ще один простий спосіб зробити це: Якщо ваш ImageButton залишається його фоном, а ви не встановите його на нуль, він буде працювати як звичайна кнопка і покаже анімацію натискань, натискаючи точно так само, як інші кнопки. Спосіб приховати фон, поки він все ще є:

<ImageButton
    android:id="@+id/imageButton2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingBottom="1dp"
    android:paddingLeft="1dp"
    android:paddingRight="1dp"
    android:paddingTop="1dp"
    android:src="@drawable/squareicon" />

Прокладки не дозволять фону бути видимим і змушують кнопку діяти як інші кнопки.


1
це дозволить зберегти рамку кнопки в квадраті навколо зображення, якщо вона кругла
— MSaudi

3

Це найкраще рішення, з яким я придумав підказки з відповіді @ Vinayak. Усі інші рішення мають різні недоліки.

Перш за все створіть подібну функцію.

void addClickEffect(View view)
{
    Drawable drawableNormal = view.getBackground();

    Drawable drawablePressed = view.getBackground().getConstantState().newDrawable();
    drawablePressed.mutate();
    drawablePressed.setColorFilter(Color.argb(50, 0, 0, 0), PorterDuff.Mode.SRC_ATOP);

    StateListDrawable listDrawable = new StateListDrawable();
    listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
    listDrawable.addState(new int[] {}, drawableNormal);
    view.setBackground(listDrawable);
}

Пояснення:

getConstantState (). newDravable () використовується для клонування існуючих Dravable, інакше буде використаний той же малюнок. Детальніше читайте звідси: Android: Клоніруйте чернетку, щоб зробити StateListDravable з фільтрами

mutate () використовується для того, щоб клон Dravable не поділяв його стан з іншими екземплярами Dravable. Детальніше про це читайте тут: https://developer.android.com/reference/android/graphics/dravable/Dravable.html#mutate ()

Використання:

Ви можете передати будь-який тип перегляду (Кнопка, ImageButton, Перегляд тощо) як параметр функції, і вони отримають ефект натискання, застосований до них.

addClickEffect(myButton);
addClickEffect(myImageButton);

2
Step: set a button in XML with onClick Action:

 <Button
android:id="@+id/btnEditUserInfo"
style="?android:borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/txt_height"
android:layout_gravity="center"
android:background="@drawable/round_btn"
android:contentDescription="@string/image_view"
android:onClick="edit_user_info"
android:text="Edit"
android:textColor="#000"
android:textSize="@dimen/login_textSize" />

Step: on button clicked show animation point
//pgrm mark ---- ---- ----- ---- ---- ----- ---- ---- -----  ---- ---- -----

    public void edit_user_info(View view) {

        // show click effect on button pressed
        final AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);
        view.startAnimation(buttonClick);

        Intent intent = new Intent(getApplicationContext(),  EditUserInfo.class);
        startActivity(intent);

    }// end edit_user_info

2

Використовуйте ефект RippleDravable для дизайну матеріалів для натискання / натискання клавіш.

Для того, щоб досягти цього, створіть пульсаційний елемент як .xml під папкою / dravable та використовуйте його в android: background для будь-яких переглядів.

  • Ефект для натискання / натискання піктограми, використовуйте ефект кругової пульсації, наприклад:

    <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@android:color/darker_gray" />

  • Ефект для перегляду, натиснутого з межею прямокутника, ми можемо додати пульсацію над існуючою схемою, накресленою нижче:

    <?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#000000"> <item android:drawable="@drawable/your_background_drawable"/> </ripple>


2

Для всіх поглядів

android:background="?android:attr/selectableItemBackground"

Але для перегляду карт, які використовують висоту

android:foreground="?android:attr/selectableItemBackground"

Для ефекту кругового натискання, як на панелі інструментів

android:background="?android:attr/actionBarItemBackground"

Також потрібно встановити

 android:clickable="true"
 android:focusable="true"

0

Внесення незначного доповнення до відповіді Андраса:

Ви можете використовувати postDelayedдля того, щоб кольоровий фільтр прослужив невеликий проміжок часу, щоб зробити його помітнішим:

        @Override
        public boolean onTouch(final View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    v.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
                    v.invalidate();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    v.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            v.getBackground().clearColorFilter();
                            v.invalidate();
                        }
                    }, 100L);
                    break;
                }
            }
            return false;
        }

Ви можете змінити значення затримки 100L відповідно до ваших потреб.


0

Якщо ви використовуєте xml фон замість IMG, просто видаліть це:

<item>
    <bitmap android:src="@drawable/YOURIMAGE"/>
</item>

з 1-ї відповіді, яку нам дав @Ljdawson.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.