After some online research, I came up with the following implementation which works nicely. The CardView class extends Fragment which can be used in a class.
public class CardView extends Fragment {
private static float CARDS_SWIPE_LENGTH = 250;
private float originalX = 0;
private float originalY = 0;
private float startMoveX = 0;
private float startMoveY = 0;
public CardView() {
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.card_template, container, false);
rootView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
final float X = event.getRawX();
final float Y = event.getRawY();
float deltaX = X - startMoveX;
float deltaY = Y - startMoveY;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
startMoveX = X;
startMoveY = Y;
break;
case MotionEvent.ACTION_UP:
childView.getBackground().setColorFilter(R.color.color_card_background, PorterDuff.Mode.DST);
if ( Math.abs(deltaY) < CARDS_SWIPE_LENGTH ) {
rootView.setX(originalX);
rootView.setY(originalY);
} else if ( deltaY > 0 ) {
onCardSwipeDown();
} else {
onCardSwipeUp();
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
int newColor = 0;
if ( deltaY < 0 ) {
int rb = (int)(255+deltaY/10);
newColor = Color.argb(170, rb, 255, rb);
} else {
int gb = (int)(255-deltaY/10);
newColor = Color.argb(170, 255, gb, gb);
}
rootView.getBackground().setColorFilter(newColor, PorterDuff.Mode.DARKEN);
rootView.setTranslationY(deltaY);
break;
}
rootView.invalidate();
return true;
}
});
return rootView;
}
protected void onCardSwipeUp() {
Log.i(AppUtil.APP, "Swiped Up");
}
protected void onCardSwipeDown() {
Log.i(AppUtil.APP, "Swiped Down");
}
}
}