Как я могу создать эффект щелчка изображения, как кнопка на Android?

У меня есть изображение в моем приложении для Android, которое я использую как кнопку с указанным событием onClick, но, как вы могли догадаться, это не дает клиенту эффекта clickview при нажатии. Как я могу это достичь?

Вы можете создавать разные изображения для кликов / не нажатых состояний и устанавливать их в onTouchListener следующим образом

final ImageView v = (ImageView) findViewById(R.id.button0); v.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) { switch (arg1.getAction()) { case MotionEvent.ACTION_DOWN: { v.setImageBitmap(res.getDrawable(R.drawable.img_down)); break; } case MotionEvent.ACTION_CANCEL:{ v.setImageBitmap(res.getDrawable(R.drawable.img_up)); break; } } return true; } }); 

Лучший выбор заключается в том, что вы определяете селектор следующим образом

     

и выберите изображение в названии:

 v.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) { v.setSelected(arg1.getAction()==MotionEvent.ACTION_DOWN); return true; } }); 

Вы можете сделать это с помощью одного изображения, используя что-то вроде этого:

  //get the image view ImageView imageView = (ImageView)findViewById(R.id.ImageView); //set the ontouch listener imageView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { ImageView view = (ImageView) v; //overlay is black with transparency of 0x77 (119) view.getDrawable().setColorFilter(0x77000000,PorterDuff.Mode.SRC_ATOP); view.invalidate(); break; } case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { ImageView view = (ImageView) v; //clear the overlay view.getDrawable().clearColorFilter(); view.invalidate(); break; } } return false; } }); 

Вероятно, я сделаю это подclassом ImageView (или ImageButton, так как это также подclass ImageView) для упрощения повторного использования, но это должно позволить вам применить «выбранный» вид к представлению изображения.

Это можно сделать только с одним файлом изображения, используя метод ColorFilter. Тем не менее, ColorFilter ожидает работать с ImageViews, а не с кнопками, поэтому вам нужно преобразовать свои кнопки в ImageViews. Это не проблема, если вы используете изображения в качестве кнопок в любом случае, но это более раздражает, если у вас есть текст … В любом случае, предполагая, что вы нашли способ решить проблему с текстом, вот код для использования:

 ImageView button = (ImageView) findViewById(R.id.button); button.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY); 

Это накладывает красную надпись на кнопку (цветовой код является шестнадцатеричным кодом для полностью непрозрачного красного цвета – первые две цифры являются прозрачностью, то это RR GG BB.).

EDIT : Несмотря на то, что оригинальный ответ ниже работает и его легко настроить, обратитесь к этому сообщению разработчиком Android Developer Advocate в Google, если вы хотите / нуждаетесь в более эффективной реализации. Также обратите внимание, что атрибут android:foreground подходит ко всем представлениям , включая ImageView, по умолчанию в Android M.


Проблема с использованием селектора для ImageView заключается в том, что вы можете установить его только в качестве фона представления – если ваше изображение непрозрачно, вы не увидите эффекта селектора за ним.

Хитрость заключается в том, чтобы обернуть ваш ImageView в FrameLayout атрибутом android:foreground который позволяет нам определять оверлей для его содержимого. Если мы установим android:foreground в селектор (например, ?android:attr/selectableItemBackground для уровня API 11+) и прикрепите OnClickListener к FrameLayout вместо ImageView, изображение будет наложено с помощью нашего селектора – эффект щелчка, который мы желаем !

Вот:

    

(Обратите внимание, что это должно быть помещено в родительский макет.)

 final View imageButton = findViewById(R.id.imageButton); imageButton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View view) { // do whatever we wish! } }); 

Используйте стиль = “? Android: borderlessButtonStyle” в файле XML. Он покажет эффект щелчка по умолчанию для Android.

  

Просто используйте ImageButton .

Вот мой простой способ решить эту проблему:

 ImageView iv = (ImageView) findViewById(R.id.imageView); iv.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub //Agrega porcentajes de cada fraccion de grafica pastel Animation animFadein = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_in); iv.startAnimation(animFadein); }); 

В файле res/anim/fade_in.xml :

     

Установите выбранный фон в ImageView и добавьте некоторое дополнение. Затем присоедините OnClickListener .

  

Для определения выбора для выбора селектора

     

Мне нужно использовать android: state_pressed вместо android: state_selected

     

Я делаю некоторые подобные вещи См. Подходящие для вас или нет

View Press Помощник эффекта:

  • использование: сделать некоторый простой эффект нажатия, например, iOS

    Простое использование:

  • ImageView img = (ImageView) findViewById (R.id.img);

  • ViewPressEffectHelper.attach (IMG)

https://gist.github.com/extralam/7489370

В сочетании со всеми приведенными выше ответами я хотел, чтобы ImageView был нажат и изменил состояние, но если пользователь переместился, то «отменить» и не выполнить onClickListener.

Я закончил создание объекта Point в classе и установил его координаты в соответствии с тем, когда пользователь нажал на ImageView. На MotionEvent.ACTION_UP я записываю новую точку и сравниваю точки.

Я могу только объяснить это так хорошо, но вот что я сделал.

 // set the ontouch listener weatherView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // Determine what action with a switch statement switch (event.getAction()) { // User presses down on the ImageView, record the original point // and set the color filter case MotionEvent.ACTION_DOWN: { ImageView view = (ImageView) v; // overlay is black with transparency of 0x77 (119) view.getDrawable().setColorFilter(0x77000000, PorterDuff.Mode.SRC_ATOP); view.invalidate(); p = new Point((int) event.getX(), (int) event.getY()); break; } // Once the user releases, record new point then compare the // difference, if within a certain range perform onCLick // and or otherwise clear the color filter case MotionEvent.ACTION_UP: { ImageView view = (ImageView) v; Point f = new Point((int) event.getX(), (int) event.getY()); if ((Math.abs(fx - px) < 15) && ((Math.abs(fx - px) < 15))) { view.performClick(); } // clear the overlay view.getDrawable().clearColorFilter(); view.invalidate(); break; } } return true; } }); 

У меня есть onClickListener, установленный в imageView, но это может быть метод.

Вы можете переопределить setPressed в ImageView и сделать там фильтрацию цветов вместо создания onTouchEvent-слушателей:

 @Override public void setPressed(boolean pressed) { super.setPressed(pressed); if(getDrawable() == null) return; if(pressed) { getDrawable().setColorFilter(0x44000000, PorterDuff.Mode.SRC_ATOP); invalidate(); } else { getDrawable().clearColorFilter(); invalidate(); } } 

Вы можете попробовать с android:background="@android:drawable/list_selector_background" чтобы получить тот же эффект, что и «Добавить будильник» по умолчанию «Будильник» (теперь «Настольные часы»).

Основываясь на ответе г-на Цорна , я использую статический метод в своем абстрактном classе Utility:

 public abstract class Utility { ... public static View.OnTouchListener imgPress(){ return imgPress(0x77eeddff); //DEFAULT color } public static View.OnTouchListener imgPress(final int color){ return new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_DOWN: { ImageView view = (ImageView) v; view.getDrawable().setColorFilter(color, PorterDuff.Mode.SRC_ATOP); view.invalidate(); break; } case MotionEvent.ACTION_UP: v.performClick(); case MotionEvent.ACTION_CANCEL: { ImageView view = (ImageView) v; //Clear the overlay view.getDrawable().clearColorFilter(); view.invalidate(); break; } } return true; } }; } ... } 

Затем я использую его с onTouchListener:

 ImageView img=(ImageView) view.findViewById(R.id.image); img.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { /* Your click action */ } }); img_zc.setOnTouchListener(Utility.imgPress()); //Or Utility.imgPress(int_color_with_alpha) 

Это очень просто, если у вас много изображений, и вы хотите простой эффект onTouch, без какого-либо XML-чертежа и только одного изображения.

Используйте android.widget.Button и установите его свойство background для android.graphics.drawable.StateListDrawable . Все это можно сделать в XML или программно. См. Раздел « Пользовательская кнопка» в учебнике Form Stuff .

Это сработало для меня:

 img.setOnTouchListener(new OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { ((ImageView)v).setImageAlpha(200); break; } case MotionEvent.ACTION_MOVE: { // if inside bounds if(event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0 && event.getY() < v.getHeight()) { ((ImageView)v).setImageAlpha(200); } else { ((ImageView)v).setImageAlpha(255); } break; } case MotionEvent.ACTION_UP: { ((ImageView)v).setImageAlpha(255); } } return true; } }); 

@Edit: Как сказал Ганхан, проблема обратной совместимости с методом setImageAlpha. Я использовал этот метод:

 public static void setImageAlpha(ImageView img, int alpha) { if(Build.VERSION.SDK_INT > 15) { img.setImageAlpha(alpha); } else { img.setAlpha(alpha); } } 

Я создаю образец здесь , просто измените ImageView на ClickableImageView из вашего макета. Надеюсь, это поможет.

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

У меня есть более красочное решение, если вы используете фоновые изображения 🙂

 public static void blackButton(View button){ button.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { v.getBackground().setColorFilter(0xf0f47521,PorterDuff.Mode.SRC_ATOP); v.invalidate(); break; } case MotionEvent.ACTION_UP: { v.getBackground().clearColorFilter(); v.invalidate(); break; } } return false; } }); } 

ИЛИ:

Вы можете использовать эту форму с помощью кнопки «Изображение».

Создать файл res/drawable/btn_video.xml :

       

И res/layout/activity_main.xml :

  

Изменение изображения с помощью щелчка, и вы можете настроить его с помощью линейного макета:

                   

Спасибо за помощь в этой теме. Однако вы пропустили одну вещь … вам также нужно обработать ACTION_CANCEL. Если вы этого не сделаете, вы можете неправильно восстановить альфа-значение ImageView в том случае, если родительский вид в иерархии представлений перехватит событие касания (подумайте, что ScrollView обертывает вами ImageView).

Вот полный class, основанный на вышеуказанном classе, но также заботящийся о ACTION_CANCEL. Он использует вспомогательный class ImageViewCompat для абстрагирования различий в API JellyBean до публикации.

 public class ChangeAlphaOnPressedTouchListener implements OnTouchListener { private final float pressedAlpha; public ChangeAlphaOnPressedTouchListener(float pressedAlpha) { this.pressedAlpha = pressedAlpha; } @Override public boolean onTouch(View v, MotionEvent event) { ImageView iv = (ImageView) v; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: ImageViewCompat.setAlpha(iv, pressedAlpha); break; case MotionEvent.ACTION_MOVE: if (isInsideViewBounds(v, event)) { ImageViewCompat.setAlpha(iv, pressedAlpha); } else { ImageViewCompat.setAlpha(iv, 1f); } break; case MotionEvent.ACTION_UP: ImageViewCompat.setAlpha(iv, 1f); break; case MotionEvent.ACTION_CANCEL: ImageViewCompat.setAlpha(iv, 1f); } return false; } private static boolean isInsideViewBounds(View v, MotionEvent event) { return event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0 && event.getY() < v.getHeight(); } } 

Вот мой код. Идея заключается в том, что ImageView получает цветной фильтр, когда пользователь прикасается к нему, а цветной фильтр удаляется, когда пользователь перестает касаться его.

Martin Booka Weser, András, Ah Lam, altosh, решение не работает, когда ImageView также имеет onClickEvent. Решение worawee.s и kcoppock (с ImageButton) требует фона, который не имеет смысла, когда ImageView не прозрачен.

Это расширение идеи AZ_ о цветовом фильтре.

 class PressedEffectStateListDrawable extends StateListDrawable { private int selectionColor; public PressedEffectStateListDrawable(Drawable drawable, int selectionColor) { super(); this.selectionColor = selectionColor; addState(new int[] { android.R.attr.state_pressed }, drawable); addState(new int[] {}, drawable); } @Override protected boolean onStateChange(int[] states) { boolean isStatePressedInArray = false; for (int state : states) { if (state == android.R.attr.state_pressed) { isStatePressedInArray = true; } } if (isStatePressedInArray) { super.setColorFilter(selectionColor, PorterDuff.Mode.MULTIPLY); } else { super.clearColorFilter(); } return super.onStateChange(states); } @Override public boolean isStateful() { return true; } } 

Применение:

 Drawable drawable = new FastBitmapDrawable(bm); imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5)); 

Я попробовал:

  

и это сработало. Обратите внимание на строку: style="?android:borderlessButtonStyle"

Я думаю, что самый простой способ – создать новый XML-файл. В этом случае назовем его «example.xml» в папке с возможностью переноса и поместим следующий код:

    

Но перед этим вам нужно установить цвета в файле colors.xml в папке значений, например:

  #0000FF  

Это сделано, вы просто установите Button / ImageButton для использования нового макета, например:

  

Затем, когда вы нажмете это изображение, оно изменится на цвет, установленный в

  

давая отзывы, которые вы хотите …

. Это лучшее решение, которое я когда-либо видел. Его более общий

      

Вот мое решение, которое, используя библиотеку « nineOldAndroids », также поддерживает старые API:

 rootView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(final View v, final MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: v.setBackgroundResource(R.drawable.listview_normal); ViewHelper.setAlpha(imageView, 1); break; case MotionEvent.ACTION_DOWN: v.setBackgroundResource(0); v.setBackgroundColor(getResources().getColor(R.color.listview_pressed)); ViewHelper.setAlpha(imageView, 0.75f); break; } return false; } }); 

Предполагается, что rootView – это сама ячейка (макет) и что у нее есть один образный вид, на который вы хотите повлиять цвет, который вы хотите применить ко всей ячейке.


EDIT: если вы хотите, вы также можете расширить ImageView для обработки переднего плана и установить его на «? Android: attr / selectableItemBackground». Для этого здесь есть библиотека и учебник о том, как это сделать для любого вида, которое вы хотите, здесь .

Если вы хотите пульсацию при нажатии, она может быть задана с помощью этого кода:

  

Аналогично, вы можете реализовать эффект щелчка для TextView

  

Просто добавьте атрибут XML, android: clickable = “true” …

На данный момент мы должны разработать практику Material Design . В этом случае вы можете добавить эффект ряби на ImageView.

Я сделал следующее в XML – с 0 дополнением вокруг изображения и рябью на изображении:

  
  • Разбор JSON для Java - приложение для Android
  • Обнаружение изменений состояния, внесенных в BluetoothAdapter?
  • Передача пользовательских объектов между действиями?
  • настраиваемое listview с использованием classа arrayadapter в android
  • Как получить список установленных принтеров?
  • Ошибка конструктора списка Firebase
  • Android - Изменить тему приложения onClick
  • Android Geocoder getFromLocationName всегда возвращает null
  • WebView и Cookies на Android
  • Java: Как установить точность для двойного значения?
  • Как можно обнаружить режим самолета на Android?
  • Давайте будем гением компьютера.