当聚焦或点击时如何突出显示图像?

时间:2022-11-21 20:43: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.

一个很好的例子是在Twitter启动屏幕上(当应用程序第一次启动时可以看到大图标的屏幕),或者甚至在聚焦应用程序图标时查看应用程序托盘。

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.

基本上,我需要高亮一个ImageView其中高亮显示的是ImageView中图像的轮廓看起来是图像的边框。我还想定制突出显示,使它有一定的颜色,并使它淡出。

Thanks,

谢谢,

groomsy

groomsy

8 个解决方案

#1


78  

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.

您需要将ImageView的src属性分配给一个状态列表。换句话说,这个状态列表将会有一个不同的图像,用于选择、按下、而不是选择等等——这就是Twitter应用的做法。

So if you had an ImageView:

如果你有一个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:

src可绘图(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>

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

谷歌IO调度应用程序就是一个很好的例子。

#2


24  

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

如果您没有另一个可绘制的压缩状态,您可以使用setColorFilterto实现简单的着色效果。

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.

在需要支持onClickListner时,从onTouch方法返回false是很重要的。

#3


2  

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

为了显示动态图像,您可以对图像源使用一个LayerDrawable。

LayerDrawable d = new LayerDrawable(new Drawable[]{new BitmapDrawable(myBmp), getResources().getDrawable(R.drawable.my_selector_list)});
imageView.setImageDrawable(d);

#4


2  

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:

只是为了完成Josh Clemm的回答。您还可以维护由src定义的相同图像,但只更改或突出背景。这或多或少是这样的:

logo_box.xml

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:

然后将按钮的背景定义为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 :)

background_normal和background_pressed可以像您希望的那样复杂,或者简单到@color:)

#5


2  

My solution, custom attribute for ImageView :
https://github.com/henrychuangtw/Android-ImageView-hover

Step 1 : declare-styleable

我的解决方案,ImageView的自定义属性:https://github.com/henrychuangtw/Android-ImageView-hover步骤1:declare-styleable

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


Step 2 : custom ImageView

步骤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;
    }
};

}

}


Step 3 : declare myattr : xmlns:myattr="http://schemas.android.com/apk/res-auto" in layout xml

步骤3:在布局xml中声明myattr: xmlns:myattr=“http://schemas.android.com/apk/res-auto”

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


Step 4 : set myattr:hover_res for MyImageView

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


#6


2  

This is an extension of mklimek. I couldn't make it work properly from his snippet. I edited a bit

这是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;
        }
    };

#7


1  

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

我建立了一个小的库,它应该可以帮助我们做到这一点:https://github.com/小说家group/highlightify

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

基本上,它在运行时中创建选择器,它应该非常容易使用。虽然,重点国家还没有得到支持……

#8


1  

I noticed that a drawable xml is not enough:

我注意到,仅使用可绘制的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>

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

一个ImageView不新闻。您还应该为ImageView分配一个OnClickListener。然后按下按钮。

#1


78  

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.

您需要将ImageView的src属性分配给一个状态列表。换句话说,这个状态列表将会有一个不同的图像,用于选择、按下、而不是选择等等——这就是Twitter应用的做法。

So if you had an ImageView:

如果你有一个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:

src可绘图(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>

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

谷歌IO调度应用程序就是一个很好的例子。

#2


24  

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

如果您没有另一个可绘制的压缩状态,您可以使用setColorFilterto实现简单的着色效果。

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.

在需要支持onClickListner时,从onTouch方法返回false是很重要的。

#3


2  

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

为了显示动态图像,您可以对图像源使用一个LayerDrawable。

LayerDrawable d = new LayerDrawable(new Drawable[]{new BitmapDrawable(myBmp), getResources().getDrawable(R.drawable.my_selector_list)});
imageView.setImageDrawable(d);

#4


2  

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:

只是为了完成Josh Clemm的回答。您还可以维护由src定义的相同图像,但只更改或突出背景。这或多或少是这样的:

logo_box.xml

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:

然后将按钮的背景定义为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 :)

background_normal和background_pressed可以像您希望的那样复杂,或者简单到@color:)

#5


2  

My solution, custom attribute for ImageView :
https://github.com/henrychuangtw/Android-ImageView-hover

Step 1 : declare-styleable

我的解决方案,ImageView的自定义属性:https://github.com/henrychuangtw/Android-ImageView-hover步骤1:declare-styleable

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


Step 2 : custom ImageView

步骤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;
    }
};

}

}


Step 3 : declare myattr : xmlns:myattr="http://schemas.android.com/apk/res-auto" in layout xml

步骤3:在布局xml中声明myattr: xmlns:myattr=“http://schemas.android.com/apk/res-auto”

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


Step 4 : set myattr:hover_res for MyImageView

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


#6


2  

This is an extension of mklimek. I couldn't make it work properly from his snippet. I edited a bit

这是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;
        }
    };

#7


1  

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

我建立了一个小的库,它应该可以帮助我们做到这一点:https://github.com/小说家group/highlightify

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

基本上,它在运行时中创建选择器,它应该非常容易使用。虽然,重点国家还没有得到支持……

#8


1  

I noticed that a drawable xml is not enough:

我注意到,仅使用可绘制的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>

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

一个ImageView不新闻。您还应该为ImageView分配一个OnClickListener。然后按下按钮。