如何在突出显示或点击时突出显示ImageView?
一个很好的例子是在Twitter的启动屏幕上(当应用程序第一次启动时显示大图标的屏幕),或者当您关注应用程序图标时,甚至只是查看应用程序托盘。
基本上我需要突出显示一个ImageView,ImageView中图像的高亮轮廓,看起来像是该图像的边框。 我也想自定义突出显示,使其成为某种颜色,并淡化。
谢谢,
groomsy
您需要将ImageView
的src
属性分配为可绘制的状态列表。 换句话说,该状态列表将具有不同的select,按下,不select等图像 – 这是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应用程序就是一个很好的例子。
如果在按下状态时没有其他drawable,则可以使用setColorFilter
实现简单的色调效果。
它的行为就像按下状态select器,所以当图像被按下时,它将背景变成浅灰色。
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; } });
它处理视图边界外的移动手指,因此如果发生,它会恢复默认的背景。
当您想要支持onTouch
时,从onTouch
方法返回false
很重要。
为了显示dynamic图像,您可以使用LayerDrawable作为图像源。
LayerDrawable d = new LayerDrawable(new Drawable[]{new BitmapDrawable(myBmp), getResources().getDrawable(R.drawable.my_selector_list)}); imageView.setImageDrawable(d);
只有完成Josh Clemm的答案。 您也可以维护由src定义的相同图像,但只更改或突出显示背景。 这或多或less会像这样:
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>
然后将您的button的背景定义为logo_box:
<ImageView android:contentDescription="@string/description_logo" android:src="@drawable/logo" android:background="@drawable/logo_box" />
其中background_normal和background_pressed可以像你想要的那样复杂,或者像@color一样简单:)
我的解决scheme,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步:在layout 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">
第4步:为MyImageView设置myattr:hover_res
<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"/>
这是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; } };
我把小型图书馆,应该帮助: https : //github.com/noveogroup/Highlightify
基本上它在运行时创buildselect器,它应该很容易使用。 虽然,尚未支持重点国家…
我注意到一个可绘制的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不会按。 您还应该为ImageView分配一个OnClickListener
。 然后它会按下button。