这方面的一个很好的例子是在Twitter启动屏幕(首次启动应用程序时看到的带有大图标的屏幕),或者甚至只是在关注应用程序图标时查看应用程序托盘。
基本上我需要突出显示一个ImageView,其中高光轮廓与ImageView中的图像轮廓相似,看起来它是该图像的边框。我还想自定义高光,使其成为一种特定的颜色,并使其淡出。
谢谢,
groomsy
答案 0 :(得分:80)
您需要为src
分配一个状态列表drawable的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 app就是一个很好的例子。
答案 1 :(得分:25)
如果您没有其他可用状态,您可以使用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 :(得分:2)
为了显示动态图像,您可以使用LayerDrawable作为图像源。
LayerDrawable d = new LayerDrawable(new Drawable[]{new BitmapDrawable(myBmp), getResources().getDrawable(R.drawable.my_selector_list)});
imageView.setImageDrawable(d);
答案 3 :(得分:2)
只有完成Josh Clemm的回答。您还可以维护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一样简单:)
答案 4 :(得分:2)
我的解决方案,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 =&#34; 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步:为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"/>
答案 5 :(得分:2)
这是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;
}
};
答案 6 :(得分:1)
我把小型图书馆放在一起应该有助于: https://github.com/noveogroup/Highlightify
基本上它在运行时创建选择器,它应该非常容易使用。 虽然,焦点状态尚未得到支持......
答案 7 :(得分:1)
我注意到一个可绘制的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
。然后按下按钮。
答案 8 :(得分:0)
我正在将android:state_selected="true"
用于 imageView的状态。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_enable" android:state_selected="true" />
<item android:drawable="@drawable/ic_disable" android:state_selected="false" />
<!--for default-->
<item android:drawable="@drawable/ic_enable" />
</selector>
使用img_view.setSelected(true)
OR img_view.setSelected(false)
以 java / kotlin 代码更改图像状态。
答案 9 :(得分:0)
使用selectableItemBackground作为背景:
android:background="?android:attr/selectableItemBackground"