I have a custom adapter set for my ListView. I have also set the default item selection ripple animation to appear when an item is selected (android:background="?android:selectableItemBackground"
).
However, the animation won't appear when I tap the TextViews. Here's a video.
What I've tried, to no avail:
Here's my list_item.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:background="?android:selectableItemBackground"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1" />
</LinearLayout>
(Edit) And in getView()
method in Adapter class I have these before return convertView
:
holder.title.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ListView) parent).performItemClick(v, position, 0); // Let the event be handled in onItemClick()
}
});
holder.text.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ListView) parent).performItemClick(v, position, 0); // Let the event be handled in onItemClick()
}
});
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
((ListView) parent).performItemClick(v, position, 0);
}
});
...to allow onItemClick
in MainActivity
(if I press the text or the linear layout, it opens up the same thing).
I have a solution to your problem: Try this in your getView():
final RippleDrawable rippleDrawable = (RippleDrawable) convertView.getBackground();
final View finalParent = parent;
final int finalPosition = position;
View.OnTouchListener listener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
rippleDrawable.setHotspot(motionEvent.getX(), motionEvent.getY());
rippleDrawable.setState(new int[] {android.R.attr.state_pressed, android.R.attr.state_enabled});
return true;
case MotionEvent.ACTION_UP:
rippleDrawable.setState(new int[0]);
((ListView)finalParent).performItemClick(view, finalPosition, 0);
return true;
}
return false;
}
};
The first line gets the RippleDrawable of the ListView item which holds the touched TextView.
When the TextView gets touched, you get the coordinates of the touch and set them to the RippleDrawable with setHotSpot, to specify the starting point of the ripple effect.
After that you trigger the ripple effect by setting an int array holding the states android.R.attr.state_pressed and android.R.attr.state_enabled to the RippleDrawable using setState().
When the touch ends, you set the state to an empty int array, the stop the ripple.
It should work!