Как выделить ImageView при фокусировке или нажатии? - PullRequest
43 голосов
/ 15 ноября 2010

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

В основном мне нужно выделить ImageView, где выделение обводится по контуру изображения внутри ImageView и выглядит так, как будто оно граничит с этим изображением.Я также хотел бы настроить выделение, чтобы оно было определенного цвета и чтобы оно исчезло.

Спасибо,

groomsy

Ответы [ 8 ]

80 голосов
/ 15 ноября 2010

Вам необходимо присвоить атрибут src списка ImageView списка состояний. Другими словами, этот список состояний будет иметь другое изображение для выбранного, нажатого, не выбранного и т. Д. - так делает приложение Twitter.

Так что, если у вас был ImageView:

<ImageView style="@style/TitleBarLogo"
            android:contentDescription="@string/description_logo"
            android:src="@drawable/title_logo" />

src drawable (title_logo.xml) будет выглядеть так:

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

Хорошим примером этого является Приложение Google IO Schedule .

25 голосов
/ 05 декабря 2014

Если у вас нет другого рисунка для нажатого состояния, вы можете использовать setColorFilter для достижения простого эффекта оттенка.

Он ведет себя так же, как нажатой селектор состояния, поэтому при нажатии на изображение он меняет фон на светло-серый.

final ImageView image = (ImageView) findViewById(R.id.my_image);
image.setOnTouchListener(new View.OnTouchListener() {
        private Rect rect;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_DOWN){
                image.setColorFilter(Color.argb(50, 0, 0, 0));
                rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
            }
            if(event.getAction() == MotionEvent.ACTION_UP){
                image.setColorFilter(Color.argb(0, 0, 0, 0));
            }
            if(event.getAction() == MotionEvent.ACTION_MOVE){
                if(!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())){
                    image.setColorFilter(Color.argb(0, 0, 0, 0));
                } 
            }
            return false;
        }
    });

Он обрабатывает движение пальца за пределами границ вида, поэтому, если это происходит, он восстанавливает фон по умолчанию.

Важно возвращать false из onTouch метода, когда вы хотите поддержать onClickListner.

2 голосов
/ 28 марта 2015

Это расширение mklimek.Я не мог заставить его работать должным образом из его фрагмента.Я немного отредактировал

 ImageView testImage = (ImageView)findViewById(R.id.imageView);
 testImage.setOnTouchListener(listener);

 View.OnTouchListener listener = new View.OnTouchListener() {
        private Rect rect;
        @Override
        public boolean onTouch(View v, MotionEvent event) {


            ImageView image = (ImageView) v;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    image.getDrawable().setColorFilter(0x77000000,PorterDuff.Mode.SRC_ATOP);
                    image.invalidate();                        
                    break;

                case MotionEvent.ACTION_UP:                        
                case MotionEvent.ACTION_CANCEL: {
                    //clear the overlay
                    image.getDrawable().clearColorFilter();
                    image.invalidate();
                    break;
                }
            }

            return true;
        }
    };
2 голосов
/ 20 ноября 2014

Мое решение, пользовательский атрибут для ImageView:
https://github.com/henrychuangtw/Android-ImageView-hover

Шаг 1: объявить в стиле

<declare-styleable name="MyImageViewAttr">
    <attr name="hover_res" format="reference" />
</declare-styleable>


Шаг 2: пользовательский ImageView

public class MyImageView extends ImageView {

int resID, resID_hover;

public MyImageView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}
public MyImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub

    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyImageViewAttr);
    resID_hover = array.getResourceId(R.styleable.MyImageViewAttr_hover_res, -1);
    if(resID_hover != -1){
        int[] attrsArray = new int[] {
                android.R.attr.src 
            };

        TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray);
        resID = ta.getResourceId(0 , View.NO_ID);           
        ta.recycle();

        setOnTouchListener(listener_onTouch);
    }

    array.recycle();

}
public MyImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyImageViewAttr);
    resID_hover = array.getResourceId(R.styleable.MyImageViewAttr_hover_res, -1);
    if(resID_hover != -1){
        int[] attrsArray = new int[] {
                android.R.attr.src 
            };

        TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray);
        resID = ta.getResourceId(0 , View.NO_ID);           
        ta.recycle();

        setOnTouchListener(listener_onTouch);
    }

    array.recycle();
}



OnTouchListener listener_onTouch = new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            setImageResource(resID_hover);
            break;

        case MotionEvent.ACTION_MOVE:

            break;

        case MotionEvent.ACTION_UP:
            setImageResource(resID);
            break;

        default:
            break;
        }


        return false;
    }
};

}


Шаг 3: объявите myattr: xmlns: myattr = "http://schemas.android.com/apk/res-auto" в макете xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:myattr="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">


Шаг 4: установите myattr: hover_res для MyImageView

<dev.henrychuang.component.MyImageView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="true"
        myattr:hover_res="@drawable/icon_home_h"
        android:src="@drawable/icon_home"/>


2 голосов
/ 03 сентября 2014

Только для завершения ответа Джоша Клемма.Вы также можете сохранить то же изображение, определенное src, но изменить или выделить только фон.Это будет более или менее так:

logo_box.xml

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

И затем определение фона вашей кнопки как logo_box:

<ImageView
    android:contentDescription="@string/description_logo"
    android:src="@drawable/logo"
    android:background="@drawable/logo_box" />

Где background_normal и background_pressedможет быть настолько сложным, насколько вы хотите, или просто @color:)

2 голосов
/ 18 сентября 2013

Для отображения динамических изображений вы можете использовать LayerDrawable для источника изображения.

LayerDrawable d = new LayerDrawable(new Drawable[]{new BitmapDrawable(myBmp), getResources().getDrawable(R.drawable.my_selector_list)});
imageView.setImageDrawable(d);
1 голос
/ 27 июля 2016

Я заметил, что недостаточно для рисования XML:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_filter_up" android:state_pressed="true"/>
    <item android:drawable="@drawable/ic_filter_up_shadow"/>
</selector>

ImageView не нажимает.Вы также должны назначить OnClickListener для ImageView.Затем он будет нажимать как кнопку.

1 голос
/ 30 июня 2014

Я собрал небольшую библиотеку, которая должна помочь с этим: https://github.com/noveogroup/Highlightify

По сути, он создает селектор во время выполнения, и он должен быть действительно простым в использовании. Хотя сфокусированное состояние еще не поддерживается ...

...