How to highlight ImageView when focused or clicked

2019-01-16 06:58发布

A good example of this is either on the Twitter launch screen (the screen with the large icons that is seen when the application is first launch) or even just look at the application tray when you focus an application icon.

Basically I need to highlight an ImageView where the highlight contours to the image within the ImageView and looks like it's a border to that image. I would also like to customize the highlight to have it be a certain color and for it to fade out.

Thanks,

groomsy

8条回答
对你真心纯属浪费
2楼-- · 2019-01-16 07:03

For displaying dynamic images you can use a LayerDrawable for the image source.

LayerDrawable d = new LayerDrawable(new Drawable[]{new BitmapDrawable(myBmp), getResources().getDrawable(R.drawable.my_selector_list)});
imageView.setImageDrawable(d);
查看更多
祖国的老花朵
3楼-- · 2019-01-16 07:07

Only to complete Josh Clemm answer. You can also maintain the same image defined by src, but change or highlight only the background. This would more or less like this:

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>

And then defining the background of your button as logo_box:

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

Where background_normal and background_pressed can be as complex as you want, or as simple as a @color :)

查看更多
姐就是有狂的资本
4楼-- · 2019-01-16 07:09

I put together small library that should help with that: https://github.com/noveogroup/Highlightify

Basically it creates selector in runtime, and it should be really easy to use. Though, focused state not supported yet...

查看更多
Rolldiameter
5楼-- · 2019-01-16 07:15

You need to assign the src attribute of the ImageView a state list drawable. In other words, that state list would have a different image for selected, pressed, not selected, etc. - that's how the Twitter App does it.

So if you had an ImageView:

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

The src drawable (title_logo.xml) would look like this:

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

The Google IO Schedule app has a good example of this.

查看更多
甜甜的少女心
6楼-- · 2019-01-16 07:16

I noticed that a drawable xml is not enough:

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

An ImageView doesn't press. You should also assign an OnClickListener for an ImageView. Then it will press as a button.

查看更多
Root(大扎)
7楼-- · 2019-01-16 07:18

If you don't have another drawable for the pressed state you can use setColorFilterto achieve a simple tint effect.

It behaves just like pressed state selector so when the image is pressed it changes the background to light grey color.

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

It handles moving finger outside the view boundaries, thus if it occurs, it restores a default background.

It's important to return false from onTouch method when you want to support onClickListner too.

查看更多
登录 后发表回答