如何在Android上提供像按钮一样的imageview点击效果?

Bur*_*ede 80 java android button imageview

我在我的Android应用程序中有一个imageview,我正在使用像给出onClick事件的按钮,但正如你可能猜到的那样,点击后它不会给imageview一个可点击的效果.我怎样才能做到这一点?

Mr *_*orn 74

您可以使用以下内容使用单个图像执行此操作:

     //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;
        }
    });
Run Code Online (Sandbox Code Playgroud)

我可能会将它变成ImageView的子类(或ImageButton,因为它也是ImageView的子类),以便更容易重复使用,但这应该允许您将"选定"外观应用于imageview.

  • 你可能想要返回`false`,否则不会触发视图的实际`onClick()`事件 (3认同)
  • 我还为ACTION_CANCEL添加了一个案例,它很棒,谢谢! (2认同)

Mar*_*ser 52

您可以为单击/未单击状态设计不同的图像,并在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;
            }
        });
Run Code Online (Sandbox Code Playgroud)

更好的选择是您按如下方式定义选择器

<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>
Run Code Online (Sandbox Code Playgroud)

并在事件中选择图像:

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


AZ_*_*AZ_ 43

使用ColorFilter方法可以使用一个图像文件.但是,ColorFilter希望使用ImageViews而不是Buttons,因此您必须将按钮转换为ImageViews.如果你正在使用图像作为你的按钮,这不是问题,但是如果你有文字就更烦人......无论如何,假设你找到解决文本问题的方法,这里是使用的代码:

ImageView button = (ImageView) findViewById(R.id.button);
button.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
Run Code Online (Sandbox Code Playgroud)

这对按钮应用了红色覆盖(颜色代码是完全不透明红色的十六进制代码 - 前两个数字是透明度,然后是RR GG BB.).

  • 你能解释一下代码运行后会发生什么,以及它打算被调用的地方吗?我试图在imageView初始化上调用这两行 - 它用红色绘制我的图像,然后没有任何反应,无论是点击还是触摸.打电话时也一样. (3认同)

jus*_*asm 40

编辑:虽然下面的原始答案有效且易于设置,但如果您需要/需要更高效的实施,请参阅Google的Android Developer Advocate撰写的这篇文章.另请注意,默认情况下,Android M 中的android:foreground属性将出现在所有视图中,包括ImageView.


使用ImageView选择器的问题是你只能将它设置为视图的背景 - 只要你的图像是不透明的,你就不会看到选择器背后的效果.

诀窍是将ImageView包装在FrameLayout中,该属性android:foreground允许我们为其内容定义叠加层.如果我们设置android:foreground为选择器(例如,?android:attr/selectableItemBackground对于API级别11+)并将其附加OnClickListener到FrameLayout而不是ImageView,则图像将覆盖我们的选择器的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>
Run Code Online (Sandbox Code Playgroud)

(请注意,这应该放在父布局中.)

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

  • 太好了!这是一个很好的解决方案。联系人应用程序中用于SMS或Call操作的相同解决方案。 (2认同)

Anj*_*ula 27

在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"
/>
Run Code Online (Sandbox Code Playgroud)

  • @androiddeveloper 使用 `android:adjustViewBounds="true"` 来取消填充。 (2认同)

kco*_*ock 21

只需使用ImageButton即可.

  • 我个人不能让它看起来像ImageView.没有边框,将图像拉伸到ImageButton等大小.如果你可以给这个边框和拉伸问题,并更新你的帖子.我的一些声誉作为赏金=) (3认同)

Osc*_*rez 15

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

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);
    });
Run Code Online (Sandbox Code Playgroud)

在档案中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>
Run Code Online (Sandbox Code Playgroud)


npk*_*npk 9

如果您想要点击时出现涟漪,可以通过以下代码给出:

<ImageView
    ...
    android:background="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    ...
</ImageView>
Run Code Online (Sandbox Code Playgroud)

同样可以为TextView实现点击效果

<TextView
    ...
    android:background="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    ...
</TextView>
Run Code Online (Sandbox Code Playgroud)


小智 8

用于定义选择器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>
Run Code Online (Sandbox Code Playgroud)

我必须使用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>
Run Code Online (Sandbox Code Playgroud)


Oli*_*anz 7

将可选背景设置为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"/>
Run Code Online (Sandbox Code Playgroud)


Mar*_*iol 5

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


alt*_*osh 5

这对我有用:

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

        });
Run Code Online (Sandbox Code Playgroud)

@Edit:正如 Gunhan 所说,setImageAlpha 方法会存在向后兼容性问题。我用了这个方法:

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