问题
I am working on an Android App which shows a series of cards. Each card almost takes the whole screen. I want the user to be able to view the previous and next cards by swiping left and right and for that ViewPager is working nicely.
However I also want the user to be able to swipe up and down a card to like/dislike a it. The swipe up/down gesture should move up/down the card according to the user's hand gesture. After a card is swiped up/down, it should be removed from the list of cards.
I searched online for a solution or a costume view. But most of the solutions I found are for 2-directional swipes (either left/right or up/down). Is there a nice solution or a library for a 4-directional Swipe View?
回答1:
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");
}
}
}
回答2:
You could use a ViewPager to change between the cards. Them you could @Override the motionEvents of Up and Down to do whatever you want with your cards. You could store them in an ArrayAdapter to switch between them. When the user swipes DOWN or UP you remove the card from the adapter and use the viewPager.setCurrentItem(viewPager.getCurrentItem() +1) to go to the next card.
http://developer.android.com/reference/android/view/MotionEvent.html http://developer.android.com/reference/android/support/v4/view/ViewPager.html
来源:https://stackoverflow.com/questions/24043697/a-custom-android-view-with-4-direction-swipe-gesture