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
Just add XML attribute , android:clickable="true" ...
I tried with:
<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" />
and this worked. Please note on the line: style="?android:borderlessButtonStyle"
As for now, we should develop Material Design practice. In this case you could add a ripple effect on an ImageView.
You could try with android:background="@android:drawable/list_selector_background"
to get the same effect as the "Add alarm" in the default "Alarm Clock" (now Desk Clock).
In combination with all the answers above, I wanted the ImageView to be pressed and changed state but if the user moved then "cancel" and not perform an onClickListener.
I ended up making a Point object within the class and setting its coordinates according to when the user pushed down on the ImageView. On the MotionEvent.ACTION_UP I recording a new point and compared the points.
I can only explain it so well, but here is what I did.
// 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;
}
});
I have an onClickListener set on the imageView, but this can be an method.
Here is my code. The idea is that ImageView gets color filter when user touches it, and color filter is removed when user stops touching it.
Martin Booka Weser, András, Ah Lam, altosh, solution doesn't work when ImageView has also onClickEvent. worawee.s and kcoppock (with ImageButton) solution requires background, which has no sense when ImageView is not transparent.
This one is extension of AZ_ idea about color filter.
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;
}
}
usage:
Drawable drawable = new FastBitmapDrawable(bm);
imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5));