How can I give an imageview click effect like a button on Android?

前端 未结 30 2082
情歌与酒
情歌与酒 2020-11-28 01:50

I have imageview in my Android app that I am using like a button with the onClick event given, but as you might guess it is not giving imageview a clickable effect when clic

相关标签:
30条回答
  • 2020-11-28 01:59

    For defining the selector drawable choice

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

    I have to use android:state_pressed instead of 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>
    
    0 讨论(0)
  • 2020-11-28 01:59

    I have a more beauty solution if you use background images :)

    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;
            }
        });
    }
    
    0 讨论(0)
  • 2020-11-28 01:59

    Here's my solution, which, using "nineOldAndroids" library, supports old APIs too:

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

    It assumes the rootView is the cell itself (the layout), and that it has a single imageView that you wish to be affected by the color that you wish to apply to the whole cell.


    EDIT: if you wish, you can also extend ImageView to handle foreground, and set it to "?android:attr/selectableItemBackground". There is a library for this here and a tutorial on how to do it for any view you wish, here.

    0 讨论(0)
  • 2020-11-28 02:00

    You can design different images for clicked/not clicked states and set them in the onTouchListener as follows

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

    The better choice is that you define a selector as follows

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

    and select the image in the event:

    v.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View arg0, MotionEvent arg1) {
                    v.setSelected(arg1.getAction()==MotionEvent.ACTION_DOWN);
                    return true;
                }
            });
    
    0 讨论(0)
  • 2020-11-28 02:03

    This worked for me:

    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: As Gunhan said there will be backward compatibility problem with setImageAlpha method. I used this method:

    public static void setImageAlpha(ImageView img, int alpha)
        {
            if(Build.VERSION.SDK_INT > 15)
            {
                img.setImageAlpha(alpha);
            }
            else
            {
                img.setAlpha(alpha);
            }
        }
    
    0 讨论(0)
  • 2020-11-28 02:03

    Thanks for the help on this thread. However, you missed one thing...you need to handle the ACTION_CANCEL as well. If you don't then you might not properly restore the alpha value of the ImageView in the event that a parent view in the view hierarchy intercepts a touch event (think a ScrollView wrapping you ImageView).

    Here is a complete class that is based off the above class but takes care of the ACTION_CANCEL as well. It uses an ImageViewCompat helper class to abstract the differences in the pre-post 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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题