我怎样才能给像Android上的button的imageview点击效果?

我在我的Android应用程序中使用了imageview,就像使用onClick事件的button一样,但是正如您猜测的那样,点击时不会给imageview一个可点击的效果。 我怎样才能做到这一点?

您可以为点击/未点击的状态devise不同的图像,并将其设置在onTouchListener中,如下所示

final ImageView v = (ImageView) findViewById(R.id.button0); v.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) { switch (arg1.getAction()) { case MotionEvent.ACTION_DOWN: { v.setImageBitmap(res.getDrawable(R.drawable.img_down)); break; } case MotionEvent.ACTION_CANCEL:{ v.setImageBitmap(res.getDrawable(R.drawable.img_up)); break; } } return true; } }); 

更好的select是你如下定义一个select器

 <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@drawable/img_down" /> <item android:state_selected="false" android:drawable="@drawable/img_up" /> </selector> 

并在事件中select图像:

 v.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) { v.setSelected(arg1.getAction()==MotionEvent.ACTION_DOWN); return true; } }); 

你可以使用像这样的一个单一的图像做到这一点:

  //get the image view ImageView imageView = (ImageView)findViewById(R.id.ImageView); //set the ontouch listener imageView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { ImageView view = (ImageView) v; //overlay is black with transparency of 0x77 (119) view.getDrawable().setColorFilter(0x77000000,PorterDuff.Mode.SRC_ATOP); view.invalidate(); break; } case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { ImageView view = (ImageView) v; //clear the overlay view.getDrawable().clearColorFilter(); view.invalidate(); break; } } return false; } }); 

我可能会将其作为ImageView(或ImageButton的子类,因为它也是ImageView的子类)的子类,以便于重用,但是这应该允许将“选定”外观应用于imageview。

使用ColorFilter方法只能处理一个图像文件 。 但是,ColorFilter期望与ImageViews而不是button,所以你必须把你的button转换成ImageViews。 如果你使用图片作为你的button,这不是一个问题,但是如果你有文本,这会更麻烦。不pipe怎么说,假设你用文本解决了这个问题,下面是使用的代码:

 ImageView button = (ImageView) findViewById(R.id.button); button.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY); 

这会在button上应用一个红色覆盖(颜色代码是完全不透明的红色的hex代码 – 前两位是透明的,然后是RR GG BB)。

编辑 :虽然原来的答案下面的工作,并且很容易设置,如果你想/需要一个更有效的实现,请参阅谷歌的Android开发者倡导者这篇文章 。 另外请注意, android:foreground属性默认在Android M中传入所有视图 ,包括ImageView。


使用ImageView的select器的问题是,只能将其设置为视图的背景 – 只要图像不透明,就不会看到select器的效果。

诀窍是用一个属性android:foreground将你的ImageView包装在一个FrameLayout中,这允许我们为它的内容定义一个覆盖层 。 如果我们将android:foreground设置为select器(例如?android:attr/selectableItemBackground for API level 11+),并将OnClickListener附加到FrameLayout而不是ImageView,则图像将被我们的select器的drawable覆盖 – 我们希望的点击效果!

看吧:

 <FrameLayout android:id="@+id/imageButton" android:layout_width="match_parent" android:layout_height="match_parent" android:foreground="?android:attr/selectableItemBackground" > <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/yourImageFile" /> </FrameLayout> 

(请注意,这应该放在您的父级布局中。)

 final View imageButton = findViewById(R.id.imageButton); imageButton.setOnClickListener(new OnClickListener(){ @Override public void onClick(View view) { // do whatever we wish! } }); 

只需使用一个ImageButton 。

在XML文件中使用style =“?android:borderlessButtonStyle” 。 它会显示Android的默认点击效果。

 <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" style="?android:borderlessButtonStyle" /> 

这是我解决这个问题的简单方法:

 ImageView iv = (ImageView) findViewById(R.id.imageView); iv.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub //Agrega porcentajes de cada fraccion de grafica pastel Animation animFadein = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_in); iv.startAnimation(animFadein); }); 

在文件res/anim/fade_in.xml

 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" > <alpha android:duration="100" android:fromAlpha="0.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="1.0" /> </set> 

将可选背景设置为ImageView并添加一些填充。 然后附加OnClickListener

 <ImageView android:id="@+id/your_image_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/your_image" android:padding="10dp" android:background="?android:attr/selectableItemBackground"/> 

用于定义select器drawable选项

 <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" android:drawable="@drawable/img_down" /> <item android:state_selected="false" android:drawable="@drawable/img_up" /> </selector> 

我必须使用android:state_pressed而不是android:state_selected

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

结合上面的所有答案,我希望ImageView被按下并改变状态,但如果用户移动然后“取消”,而不是执行onClickListener。

我最终在类中创build了一个Point对象,并根据用户在ImageView上按下的时间来设置它的坐标。 在MotionEvent.ACTION_UP上logging一个新的点并比较这些点。

我只能解释得那么好,但是这是我所做的。

 // set the ontouch listener weatherView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // Determine what action with a switch statement switch (event.getAction()) { // User presses down on the ImageView, record the original point // and set the color filter case MotionEvent.ACTION_DOWN: { ImageView view = (ImageView) v; // overlay is black with transparency of 0x77 (119) view.getDrawable().setColorFilter(0x77000000, PorterDuff.Mode.SRC_ATOP); view.invalidate(); p = new Point((int) event.getX(), (int) event.getY()); break; } // Once the user releases, record new point then compare the // difference, if within a certain range perform onCLick // and or otherwise clear the color filter case MotionEvent.ACTION_UP: { ImageView view = (ImageView) v; Point f = new Point((int) event.getX(), (int) event.getY()); if ((Math.abs(fx - px) < 15) && ((Math.abs(fx - px) < 15))) { view.performClick(); } // clear the overlay view.getDrawable().clearColorFilter(); view.invalidate(); break; } } return true; } }); 

我有一个onClickListener在imageView上设置,但这可以是一个方法。

您可以在ImageView中覆盖setPressed并在那里进行颜色过滤,而不是创buildonTouchEvent侦听器:

 @Override public void setPressed(boolean pressed) { super.setPressed(pressed); if(getDrawable() == null) return; if(pressed) { getDrawable().setColorFilter(0x44000000, PorterDuff.Mode.SRC_ATOP); invalidate(); } else { getDrawable().clearColorFilter(); invalidate(); } } 

基于Zorn先生的回答 ,我在抽象的Utility类中使用了一个静态方法:

 public abstract class Utility { ... public static View.OnTouchListener imgPress(){ return imgPress(0x77eeddff); //DEFAULT color } public static View.OnTouchListener imgPress(final int color){ return new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_DOWN: { ImageView view = (ImageView) v; view.getDrawable().setColorFilter(color, PorterDuff.Mode.SRC_ATOP); view.invalidate(); break; } case MotionEvent.ACTION_UP: v.performClick(); case MotionEvent.ACTION_CANCEL: { ImageView view = (ImageView) v; //Clear the overlay view.getDrawable().clearColorFilter(); view.invalidate(); break; } } return true; } }; } ... } 

然后我用onTouchListener使用它:

 ImageView img=(ImageView) view.findViewById(R.id.image); img.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { /* Your click action */ } }); img_zc.setOnTouchListener(Utility.imgPress()); //Or Utility.imgPress(int_color_with_alpha) 

如果你有很多图像,并且你想要一个简单的onTouch效果,没有任何XML可绘制的,只有一个图像,这是非常简单的。

使用android.widget.Button ,并将其background属性设置为android.graphics.drawable.StateListDrawable 。 这可以全部用XML或编程方式完成。 请参阅Form Stuff教程的自定义button部分 。

这对我工作:

 img.setOnTouchListener(new OnTouchListener(){ @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { ((ImageView)v).setImageAlpha(200); break; } case MotionEvent.ACTION_MOVE: { // if inside bounds if(event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0 && event.getY() < v.getHeight()) { ((ImageView)v).setImageAlpha(200); } else { ((ImageView)v).setImageAlpha(255); } break; } case MotionEvent.ACTION_UP: { ((ImageView)v).setImageAlpha(255); } } return true; } }); 

@编辑:正如Gunhan所说,将会有setImageAlpha方法的向后兼容性问题。 我用这个方法:

 public static void setImageAlpha(ImageView img, int alpha) { if(Build.VERSION.SDK_INT > 15) { img.setImageAlpha(alpha); } else { img.setAlpha(alpha); } } 

我做了一些类似的事情,看看是否适合你

查看新闻效果助手:

  • 用法:像iOS一样做一些简单的按下效果

    简单的用法:

  • ImageView img =(ImageView)findViewById(R.id.img);

  • ViewPressEffectHelper.attach(IMG)

https://gist.github.com/extralam/7489370

您可以尝试使用android:background="@android:drawable/list_selector_background"以获得与默认“闹钟”(现在的桌面时钟)中的“添加闹钟”相同的效果。

我在这里创build示例,只需将您的布局中的ImageView更改为ClickableImageView 。 希望它有帮助。

在这里输入图像说明

如果您使用背景图像,我有一个更美丽的解决scheme:)

 public static void blackButton(View button){ button.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { v.getBackground().setColorFilter(0xf0f47521,PorterDuff.Mode.SRC_ATOP); v.invalidate(); break; } case MotionEvent.ACTION_UP: { v.getBackground().clearColorFilter(); v.invalidate(); break; } } return false; } }); } 

这是我见过的最好的解决scheme。 它更通用

  <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter="true" > <alpha android:duration="100" android:fromAlpha="0.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="1.0" /> </set> 

感谢您对此主题的帮助。 但是,你错过了一件事情,你也需要处理ACTION_CANCEL。 如果你不这样做,那么如果视图层次结构中的父视图拦截了一个触摸事件(想一个ScrollView包裹着你的ImageView),你可能无法正确地恢复ImageView的alpha值。

这是一个基于上面的类的完整的类,但也照顾ACTION_CANCEL。 它使用一个ImageViewCompat帮助程序类来抽象前JellyBean API中的差异。

 public class ChangeAlphaOnPressedTouchListener implements OnTouchListener { private final float pressedAlpha; public ChangeAlphaOnPressedTouchListener(float pressedAlpha) { this.pressedAlpha = pressedAlpha; } @Override public boolean onTouch(View v, MotionEvent event) { ImageView iv = (ImageView) v; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: ImageViewCompat.setAlpha(iv, pressedAlpha); break; case MotionEvent.ACTION_MOVE: if (isInsideViewBounds(v, event)) { ImageViewCompat.setAlpha(iv, pressedAlpha); } else { ImageViewCompat.setAlpha(iv, 1f); } break; case MotionEvent.ACTION_UP: ImageViewCompat.setAlpha(iv, 1f); break; case MotionEvent.ACTION_CANCEL: ImageViewCompat.setAlpha(iv, 1f); } return false; } private static boolean isInsideViewBounds(View v, MotionEvent event) { return event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0 && event.getY() < v.getHeight(); } } 

这是我的代码。 这个想法是,当用户触摸它时,ImageView会获取颜色filter,当用户停止触摸时,将会移除颜色filter。

Martin Booka Weser,András,Ah Lam,altosh,当ImageView也有onClickEvent时,解决scheme不起作用。 worawee.s和kcoppock(与ImageButton)解决scheme需要背景,当ImageView不透明时,这是没有意义的。

这是关于彩色滤光片的AZ_思想的延伸。

 class PressedEffectStateListDrawable extends StateListDrawable { private int selectionColor; public PressedEffectStateListDrawable(Drawable drawable, int selectionColor) { super(); this.selectionColor = selectionColor; addState(new int[] { android.R.attr.state_pressed }, drawable); addState(new int[] {}, drawable); } @Override protected boolean onStateChange(int[] states) { boolean isStatePressedInArray = false; for (int state : states) { if (state == android.R.attr.state_pressed) { isStatePressedInArray = true; } } if (isStatePressedInArray) { super.setColorFilter(selectionColor, PorterDuff.Mode.MULTIPLY); } else { super.clearColorFilter(); } return super.onStateChange(states); } @Override public boolean isStateful() { return true; } } 

用法:

 Drawable drawable = new FastBitmapDrawable(bm); imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5)); 

我试着用:

 <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/get_started" android:src="@drawable/home_started" style="?android:borderlessButtonStyle" android:adjustViewBounds="true" android:clickable="true" android:elevation="5dp" android:longClickable="true" /> 

这工作。 请注意: style="?android:borderlessButtonStyle"

我认为最简单的方法是创build一个新的XML文件。 在这种情况下,让我们在可绘制文件夹中将其称为“example.xml”,并放入以下代码:

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

但在此之前,您必须在values.xml文件中设置颜色,如下所示:

 <resources> <color name="blue">#0000FF</color> </resources> 

这样做,你只需设置Button / ImageButton使用新的布局,如下所示:

 <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/example" /> 

然后当你点击那个图像时,它将会变成设置的颜色

 <item android:drawable="@color/blue" android:state_pressed="true" /> 

给你想要的反馈…

要么:

你可以使用这个forms,与图像button。

创build文件res/drawable/btn_video.xml

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

res/layout/activity_main.xml

 <ImageButton android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/imageButton" android:layout_gravity="center_horizontal" android:onClick="eventImageBtn" android:background="@drawable/btn_video" android:adjustViewBounds="true" android:scaleType="fitXY" /> 

您的图片只需点击一下,您就可以使用线性布局进行调整:

 <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@color/menu_item_background"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingLeft="@dimen/main_screen_side_padding" android:paddingRight="@dimen/main_screen_side_padding" android:paddingTop="@dimen/main_screen_side_padding" android:paddingBottom="@dimen/main_screen_side_padding" android:background="#ffb3ff13" android:weightSum="10.00"> <LinearLayout android:layout_weight="2.50" android:background="#ff56cfcd" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" > <ImageButton android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/imageButton" android:layout_gravity="center_horizontal" android:onClick="eventImageBtn" android:background="@drawable/btn_video" android:adjustViewBounds="true" android:scaleType="fitXY" /> </LinearLayout> <LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" > </LinearLayout> <LinearLayout android:layout_weight="4.50" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ff8aa5ff"> </LinearLayout> <LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" > </LinearLayout> <LinearLayout android:layout_weight="2.00" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ffff7d1a" > </LinearLayout> </LinearLayout> </LinearLayout> </ScrollView> 

这是我的解决scheme,使用“ nineOldAndroids ”库,也支持旧的API:

 rootView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(final View v, final MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: v.setBackgroundResource(R.drawable.listview_normal); ViewHelper.setAlpha(imageView, 1); break; case MotionEvent.ACTION_DOWN: v.setBackgroundResource(0); v.setBackgroundColor(getResources().getColor(R.color.listview_pressed)); ViewHelper.setAlpha(imageView, 0.75f); break; } return false; } }); 

它假设rootView是单元格本身(布局),并且它有一个单一的imageView,你希望受到你想要应用到整个单元格的颜色的影响。


编辑:如果你愿意,你也可以扩展ImageView来处理前景,并将其设置为“?android:attr / selectableItemBackground”。 有一个这里的图书馆和一个教程,如何做到这一点,你希望任何看法, 在这里

如果你想要点击时涟漪,它可以由这个代码给出:

 <ImageView ... android:background="?attr/selectableItemBackgroundBorderless" android:clickable="true" ... </ImageView> 

同样,你可以实现对TextView的点击效果

 <TextView ... android:background="?attr/selectableItemBackgroundBorderless" android:clickable="true" ... </TextView> 

到现在为止,我们应该开发材料devise实践。 在这种情况下,您可以在ImageView上添加涟漪效应。