Як встановити ефект натискання кнопки в 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.