我怎样才能给像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)
您可以尝试使用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上添加涟漪效应。