Как я могу дать imageview нажмите эффект, как кнопка на Android?



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

739   29  

29 ответов:

вы можете создавать различные изображения для состояний clicked / not clicked и устанавливать их в 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;
            }
        });

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

     //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) для более легкого повторного использования, но это должно позволить вам применить "выбранный" взгляд к imageview.

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

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

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

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


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

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

вот:

<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!
    }
});

использовать 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"
/>

просто использовать 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:

<?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>

установите выбираемый фон в 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"/>

для определения селектора drawable choice

<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>

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

Просмотр Пресс-Эффект Помощник:

  • использование : сделайте какой-нибудь простой пресс-эффект, как iOS

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

  • книги ИМГ = (графическое представление) команду findViewById(Р. ИД.ИМГ);

  • ViewPressEffectHelper.прикрепить(ИМГ)

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

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

Я закончил тем, что сделал точечный объект в классе и установил его координаты в соответствии с тем, когда пользователь нажал на ImageView. О событии движения.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, но это может быть метод.

Вы можете переопределить 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" чтобы получить тот же эффект, что и "добавить будильник" по умолчанию "будильник" (теперь Настольные часы).

на основе ответ Мистера Зорна, Я использую статический метод в моем абстрактном служебном классе:

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 drawable и только одно изображение.

использовать android.widget.Button и background свойства android.graphics.drawable.StateListDrawable. Все это может быть сделано в XML или программно. Смотрите пользовательский раздел кнопки формы материал учебник.

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

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 из вашего макета. Надеюсь, это поможет.

enter image description here

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

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:

<?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>

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

вот полный класс, который основан на вышеуказанном классе, но также заботится о ACTION_CANCEL. Он использует вспомогательный класс ImageViewCompat для аннотация различия в API-интерфейсе Pre-post 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));

Я старался с:

<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"

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

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

</selector>

но перед этим вы должны установить цвет в цвет.xml-файл, в папке values, например:

<resources>
    <color name="blue">#0000FF</color>
</resources>

что сделано, вы просто установите кнопку / 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" />

давая обратную связь, что вы хотите...

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

    <?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>

вот мое решение, которое, с помощью "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 - это сама ячейка (макет), и что у нее есть один imageView, на который вы хотите повлиять цветом, который вы хотите применить ко всей ячейке.


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

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

<ImageView
    ...
    android:background="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    ...
</ImageView>

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

<TextView
    ...
    android:background="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    ...
</TextView>

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

<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" />

просто добавьте атрибут XML, android: clickable= "true"...

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

Comments

    Ничего не найдено.