У меня есть изображение в моем приложении для Android, которое я использую как кнопку с указанным событием onClick, но, как вы могли догадаться, это не дает клиенту эффекта clickview при нажатии. Как я могу это достичь?
Как я могу создать эффект щелчка изображения, как кнопка на Android?
Ответ 1
Вы можете создавать разные изображения для кликов/не нажатых состояний и устанавливать их в 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;
            }
        });
Лучший выбор заключается в том, что вы определяете селектор следующим образом
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true"   
        android:drawable="@drawable/img_down" />
    <item android:state_selected="false"   
        android:drawable="@drawable/img_up" />
</selector>
и выберите изображение в событии:
v.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                v.setSelected(arg1.getAction()==MotionEvent.ACTION_DOWN);
                return true;
            }
        });
		Ответ 2
Вы можете сделать это с помощью одного изображения, используя что-то вроде этого:
     //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;
        }
    });
Я, вероятно, сделаю это в подкласс ImageView (или ImageButton, так как он также является подклассом ImageView) для упрощения повторного использования, но это должно позволить вам применить "выбранный" вид к представлению изображения.
Ответ 3
Возможно использование только одного файла изображения с помощью метода ColorFilter. Тем не менее, ColorFilter ожидает работать с ImageViews, а не с кнопками, поэтому вам нужно преобразовать свои кнопки в ImageViews. Это не проблема, если вы используете изображения в качестве кнопок в любом случае, но это более раздражает, если у вас есть текст... В любом случае, предполагая, что вы найдете способ решения проблемы с текстом, здесь используется код:
ImageView button = (ImageView) findViewById(R.id.button);
button.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
Это красное наложение на кнопку (код цвета - это шестнадцатеричный код для полностью непрозрачного красного цвета - первые две цифры являются прозрачностью, а затем RR GG BB.).
Ответ 4
  РЕДАКТИРОВАТЬ. Хотя исходный ответ ниже работает и его легко настроить, обратитесь к этому сообщению от разработчика Android Developer Advocate в Google если вы хотите/нуждаетесь в более эффективной реализации. Также обратите внимание, что android:foreground атрибут подходит ко всем представлениям, включая ImageView, по умолчанию в Android M.
Проблема с использованием селектора для ImageView заключается в том, что вы можете установить его только в качестве фона представления - пока ваше изображение непрозрачно, вы не увидите эффекта селектора.
Хитрость заключается в том, чтобы обернуть ваш ImageView в FrameLayout с атрибутом android:foreground, который позволяет нам определить наложение для его содержимого. Если мы установим android:foreground в селектор (например, ?android:attr/selectableItemBackground для уровня API 11+) и прикрепим OnClickListener к FrameLayout вместо ImageView, изображение будет наложен с помощью нашего селектора drawable - эффекта щелчка, который мы желаем!
Вот:
<FrameLayout
    android:id="@+id/imageButton"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:foreground="?android:attr/selectableItemBackground" >
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/yourImageFile" />
</FrameLayout>
(Обратите внимание, что это должно быть помещено в родительский макет.)
final View imageButton = findViewById(R.id.imageButton);
imageButton.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View view) {
        // do whatever we wish!
    }
});
		Ответ 5
Использовать style = "? android: borderlessButtonStyle" в файле XML. Он покажет эффект щелчка по умолчанию для Android.
<ImageView
    android:id="@+id/imageView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_launcher" 
    style="?android:borderlessButtonStyle"
/>
		Ответ 6
Просто используйте ImageButton.
Ответ 7
Вот мой простой способ решить эту проблему:
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:
<?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:fillAfter="true" >
<alpha
    android:duration="100"
    android:fromAlpha="0.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toAlpha="1.0" />
 </set>
		Ответ 8
Для определения выбора с возможностью выбора выбора
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true"   
        android:drawable="@drawable/img_down" />
    <item android:state_selected="false"   
        android:drawable="@drawable/img_up" />
</selector>
Мне нужно использовать android: state_pressed вместо android: state_selected
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed ="true"   
        android:drawable="@drawable/img_down" />
    <item android:state_pressed ="false"   
        android:drawable="@drawable/img_up" />
</selector>
		Ответ 9
Установите выбранный фон в ImageView и добавьте некоторое дополнение. Затем присоедините OnClickListener.
<ImageView
    android:id="@+id/your_image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/your_image"
    android:padding="10dp"
    android:background="?android:attr/selectableItemBackground"/>
		Ответ 10
Вы можете попробовать с помощью android:background="@android:drawable/list_selector_background"
чтобы получить тот же эффект, что и "Добавить будильник" по умолчанию "Будильник" (теперь настольные часы).
Ответ 11
Это сработало для меня:
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);
        }
    }
		Ответ 12
Я делаю некоторые подобные вещи См. Подходящие для вас или нет.
View Press Помощник эффекта:
-  
Использование: сделать некоторый простой эффект нажатия, например, iOS
Простое использование:
 -  
ImageView img = (ImageView) findViewById (R.id.img);
 - ViewPressEffectHelper.attach(IMG)
 
Ответ 13
В сочетании со всеми приведенными выше ответами я хотел, чтобы ImageView был нажат и изменил состояние, но если пользователь переместился, то "отменить" и не выполнить onClickListener.
Я закончил создание объекта Point в классе и установил его координаты в соответствии с тем, когда пользователь нажал на 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(f.x - p.x) < 15)
                    && ((Math.abs(f.x - p.x) < 15))) {
                view.performClick();
            }
            // clear the overlay
            view.getDrawable().clearColorFilter();
            view.invalidate();
            break;
        }
        }
        return true;
    }
});
У меня есть набор onClickListener в imageView, но это может быть метод.
Ответ 14
Вы можете переопределить 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();
    }
}
		Ответ 15
На основе Mr Zorn answer, я использую статический метод в своем абстрактном классе 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-чертежа и только одного изображения.
Ответ 16
Используйте android.widget.Button и установите для свойства background значение android.graphics.drawable.StateListDrawable. Все это можно сделать в XML или программно. См. Раздел Пользовательская кнопка в учебном пособии по формату.
Ответ 17
Я создаю образец здесь, просто измените ImageView на ClickableImageView из вашего макета. Надеюсь, это поможет.
Ответ 18
У меня есть более красочное решение, если вы используете фоновые изображения:)
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;
        }
    });
}
		Ответ 19
ИЛИ
Вы можете использовать эту форму с помощью кнопки "Изображение".
Создать файл res/drawable/btn_video.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/image"
        android:state_pressed="true" />
    <item android:drawable="@drawable/ico2"
        android:state_focused="true" />
    <item android:drawable="@drawable/ico2" />
</selector>
И res/layout/activity_main.xml:
<ImageButton
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/imageButton"
    android:layout_gravity="center_horizontal"
    android:onClick="eventImageBtn"
    android:background="@drawable/btn_video"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
/>
Ваше изображение изменяется одним щелчком мыши, и вы можете настроить его с помощью линейного макета:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@color/menu_item_background">
        <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"
                      android:paddingLeft="@dimen/main_screen_side_padding" android:paddingRight="@dimen/main_screen_side_padding" android:paddingTop="@dimen/main_screen_side_padding" android:paddingBottom="@dimen/main_screen_side_padding"
                      android:background="#ffb3ff13" android:weightSum="10.00">
            <LinearLayout android:layout_weight="2.50" android:background="#ff56cfcd" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" >
                <ImageButton
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:id="@+id/imageButton"
                    android:layout_gravity="center_horizontal"
                    android:onClick="eventImageBtn"
                    android:background="@drawable/btn_video"
                    android:adjustViewBounds="true"
                    android:scaleType="fitXY"
                />
            </LinearLayout>
            <LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" >
            </LinearLayout>
            <LinearLayout android:layout_weight="4.50" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ff8aa5ff">
            </LinearLayout>
            <LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" >
            </LinearLayout>
            <LinearLayout android:layout_weight="2.00" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ffff7d1a" >
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</ScrollView>
		Ответ 20
Спасибо за помощь в этой теме. Однако вы пропустили одну вещь... вам также нужно обработать ACTION_CANCEL. Если вы этого не сделаете, вы можете неправильно восстановить альфа-значение ImageView в том случае, если родительский вид в иерархии представлений перехватит событие касания (подумайте, что ScrollView обертывает ImageView).
Вот полный класс, основанный на вышеуказанном классе, но также заботящийся о ACTION_CANCEL. Он использует вспомогательный класс 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();
    }
}
		Ответ 21
Вот мой код. Идея заключается в том, что 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));
		Ответ 22
Я думаю, что самый простой способ - создать новый XML файл. В этом случае позвольте называть его "example.xml" в выпадающей папке и вставить следующий код:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/blue"
          android:state_pressed="true" />
</selector>
Но перед этим вам нужно установить цвета в файле colors.xml в папке значений, например:
<resources>
    <color name="blue">#0000FF</color>
</resources>
Это сделано, вы просто устанавливаете Button/ImageButton для использования нового макета, например:
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/example"
/>
Затем, когда вы нажмете это изображение, оно изменится на цвет, установленный в
<item android:drawable="@color/blue"
      android:state_pressed="true" />
предоставив отзывы, которые вы хотите...
Ответ 23
Здесь мое решение, которое, используя библиотеку 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". Существует библиотека для здесь и учебник о том, как сделать это для любого вида, которое вы пожелаете, здесь.
Ответ 24
Я пробовал:
<ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/get_started"
        android:src="@drawable/home_started"
        style="?android:borderlessButtonStyle"
        android:adjustViewBounds="true"
        android:clickable="true"
        android:elevation="5dp"
        android:longClickable="true" />
и это сработало. Обратите внимание на строку: style="?android:borderlessButtonStyle"
Ответ 25
. Это лучшее решение, которое я когда-либо видел. Его более общий
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:fillAfter="true" >
<alpha
    android:duration="100"
    android:fromAlpha="0.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toAlpha="1.0" />
 </set>
		Ответ 26
Если вы хотите пульсацию при нажатии, она может быть задана с помощью этого кода:
<ImageView
    ...
    android:background="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    ...
</ImageView>
Аналогично, вы можете реализовать эффект щелчка для TextView
<TextView
    ...
    android:background="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    ...
</TextView>
		Ответ 27
Я думаю, что ImageButton - лучшее решение
<ImageButton
    android:layout_width="96dp"
    android:layout_height="56dp"
    android:src="@mipmap/ic_launcher"
    android:adjustViewBounds="true"
    android:background="@android:color/transparent"
    android:foreground="@drawable/selector" />
		Ответ 28
В XML я сделал следующее: с 0 добавлением вокруг изображения и рябью на изображении:
<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@drawable/my_image"
    android:clickable="true"
    android:focusable="true"
    android:src="?android:attr/selectableItemBackground" />
		Ответ 29
Просто добавьте атрибут XML, android: clickable = "true"...
Ответ 30
На данный момент мы должны разработать Практикурование материалов. В этом случае вы можете добавить эффект ряби на ImageView.
