时间:2011-01-06 17:41:30

标签: java android button imageview

31 个答案:

答案 0 :(得分:73)

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

     //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。

答案 1 :(得分:51)

答案 2 :(得分:43)

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

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

这会在按钮上应用红色叠加层(颜色代码为完全不透明红色的十六进制代码 - 前两位数字是透明度,然后是RR GG BB。)。

答案 3 :(得分:38)

编辑:虽然以下原始答案有效且易于设置,但如果您需要/需要更高效的实施,请参阅Google的Android Developer Advocate this post。另请注意,{M}默认情况下,android:foreground属性为coming to all Views,包括ImageView。


为ImageView使用选择器的问题在于,您只能将其设置为视图的背景 - 只要您的图像不透明,就不会看到选择器背后的效果。

诀窍是将ImageView包含在具有属性android:foreground的FrameLayout中,这允许我们为其内容定义 overlay 。如果我们将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>

(请注意,这应放在您的父版面中。)

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

答案 4 :(得分:25)

在XML文件中使用 style =&#34;?android:borderlessButtonStyle&#34; 。 它将显示Android默认点击效果。

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

答案 5 :(得分:21)

答案 6 :(得分:14)

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

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>

答案 7 :(得分: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"/>

答案 8 :(得分:7)

用于定义选择器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>

答案 9 :(得分:4)

基于Mr Zorn's answer,我在抽象的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可绘制且只有一个图像,这非常简单。

答案 10 :(得分:4)

这对我有用:

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

        });

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

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

答案 11 :(得分:4)

我做了类似的事情 适合您或不适合

查看按效果助手:

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

    简单用法:

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

  • ViewPressEffectHelper.attach(IMG)

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

答案 12 :(得分:4)

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

@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();
    }
}

答案 13 :(得分:4)

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

我最终在类中创建了一个Point对象,并根据用户按下ImageView时设置其坐标。在MotionEvent.ACTION_UP上,我记录了一个新点并比较了这些点。

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

// 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(f.x - p.x) < 15)
                    && ((Math.abs(f.x - p.x) < 15))) {
                view.performClick();
            }
            // clear the overlay
            view.getDrawable().clearColorFilter();
            view.invalidate();
            break;
        }
        }
        return true;
    }
});

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

答案 14 :(得分:4)

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

答案 15 :(得分:3)

答案 16 :(得分:3)

我创建示例here,只需从您的布局中将ImageView更改为ClickableImageView。希望它有所帮助。

enter image description here

答案 17 :(得分:2)

如果你使用背景图片,我有一个更美容的解决方案:)

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

答案 18 :(得分:1)

如果您在点击时需要纹波,可以通过以下代码给出:

-

同样,您可以实现TextView的单击效果

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

答案 19 :(得分:1)

我认为ImageButton是更好的解决方案

<ImageButton
    android:layout_width="96dp"
    android:layout_height="56dp"
    android:src="@mipmap/ic_launcher"
    android:adjustViewBounds="true"
    android:background="@android:color/transparent"
    android:foreground="@drawable/selector" />

答案 20 :(得分:1)

你可以通过添加这个属性来做到这一点

 android:background="?android:attr/selectableItemBackground"/

进入你的

答案 21 :(得分:1)

这是我的解决方案,使用“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”。这个here有一个库,以及如何为您想要的任何视图here进行操作的教程。

答案 22 :(得分:1)

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

    <?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>

答案 23 :(得分:1)

我尝试过:

<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"

答案 24 :(得分:1)

我认为最简单的方法是创建一个新的XML文件。在这种情况下,让我们在drawable文件夹中将其命名为“example.xml”,并输入以下代码:

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

</selector>

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

<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" />

提供您想要的反馈......

答案 25 :(得分:1)

这是我的代码。我们的想法是ImageView在用户触摸时获取滤色器,并在用户停止触摸时删除滤色器。

当ImageView还有onClickEvent时,Martin Booka Weser,András,Ah Lam,altosh,解决方案不起作用。 worawee.s和kcoppock(使用ImageButton)解决方案需要背景,当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));

答案 26 :(得分:1)

感谢您对此主题的帮助。但是,你错过了一件事......你也需要处理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();
    }
}

答案 27 :(得分:0)

我在XML中做了如下操作 - 在图像周围使用 0 padding 并在图像上纹理 ontop

<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@drawable/my_image"
    android:clickable="true"
    android:focusable="true"
    android:src="?android:attr/selectableItemBackground" />

答案 28 :(得分:0)

只需添加XML属性android:clickable =“ true” ...

答案 29 :(得分:0)

您可以为 ImageView 制作一个简单的涟漪效果。这非常适合图标。

res/drawable 中创建 circular_shape.xml

<?xml version="1.0" encoding="utf-8"?>
 <selector xmlns:android="http://schemas.android.com/apk/res/android">

  <item>
    <shape android:shape="oval">
        <solid android:color="@android:color/white"/>
    </shape>
  </item>

res/drawable中创建一个可绘制的资源文件ripple_effect_iv.xml

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight">

 <item
    android:id="@android:id/mask"
    android:drawable="@drawable/circular_shape" />

</ripple>

background设置为ImageView,您也可以考虑使用padding来显示自然波纹:

     <ImageView
        android:background="@drawable/ripple_effect_iv"
        android:padding="10dp"/>

是的,您的 ImageView 变小了,但您可以简单地增加 android:layout_widthandroid:layout_height

答案 30 :(得分:-1)

至于现在,我们应该发展Material Design练习。在这种情况下,您可以在ImageView上添加涟漪效果。