具有4向滑动手势的自定义Android视图
我正在开发一个Android应用程序,它显示一系列卡片。每张卡片几乎占据了整个屏幕。我希望用户能够通过左右滑动查看上一张和下一张卡片,并且ViewPager工作得很好 然而,我也希望用户能够上下滑动一张卡片来喜欢/不喜欢它。向上/向下滑动手势应根据用户的手势向上/向下移动卡。向上/向下刷卡后,应将其从卡列表中删除具有4向滑动手势的自定义Android视图,android,android-viewpager,swipe,Android,Android Viewpager,Swipe,我正在开发一个Android应用程序,它显示一系列卡片。每张卡片几乎占据了整个屏幕。我希望用户能够通过左右滑动查看上一张和下一张卡片,并且ViewPager工作得很好 然而,我也希望用户能够上下滑动一张卡片来喜欢/不喜欢它。向上/向下滑动手势应根据用户的手势向上/向下移动卡。向上/向下刷卡后,应将其从卡列表中删除 我在网上搜索解决方案或服装视图。但我发现的大多数解决方案都是双向滑动(左/右或上/下)。是否有一个很好的解决方案或库用于4向滑动视图?您可以使用ViewPager在卡之间切换。你可以@
我在网上搜索解决方案或服装视图。但我发现的大多数解决方案都是双向滑动(左/右或上/下)。是否有一个很好的解决方案或库用于4向滑动视图?您可以使用ViewPager在卡之间切换。你可以@Override the motionEvents of Up and Down来做你想做的任何事情。您可以将它们存储在ArrayAdapter中,以便在它们之间切换。当用户向下或向上滑动时,从适配器中取出卡,并使用viewPager.setCurrentItem(viewPager.getCurrentItem()+1)转到下一张卡
您可以使用ViewPager在卡之间切换。你可以@Override the motionEvents of Up and Down来做你想做的任何事情。您可以将它们存储在ArrayAdapter中,以便在它们之间切换。当用户向下或向上滑动时,从适配器中取出卡,并使用viewPager.setCurrentItem(viewPager.getCurrentItem()+1)转到下一张卡
在进行了一些在线研究之后,我提出了以下实施方案,效果很好。CardView类扩展了可在类中使用的片段
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");
}
}
}
公共类CardView扩展片段{
私人静态浮动卡刷卡长度=250;
私有浮动原始x=0;
私有浮动初始值=0;
专用浮点startMoveX=0;
专用浮点startMoveY=0;
公共CardView(){
超级();
}
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
视图根视图=充气机。充气(R.layout.card_模板,容器,假);
setOnTouchListener(新视图.OnTouchListener(){
公共布尔onTouch(视图、运动事件){
最终浮点X=event.getRawX();
最终浮点Y=event.getRawY();
浮动deltaX=X-开始移动;
浮动三角洲=Y-开始移动;
开关(event.getAction()&MotionEvent.ACTION\u掩码){
case MotionEvent.ACTION\u DOWN:
startMoveX=X;
startMoveY=Y;
打破
case MotionEvent.ACTION\u UP:
childView.getBackground().setColorFilter(R.color.color_card_background,PorterDuff.Mode.DST);
if(数学abs(deltaY)0){
onCardSwipeDown();
}否则{
onCardSwipeUp();
}
打破
case MotionEvent.ACTION\u指针\u向下:
打破
case MotionEvent.ACTION\u指针\u向上:
打破
case MotionEvent.ACTION\u移动:
int newColor=0;
如果(三角洲<0){
int rb=(int)(255+deltaY/10);
newColor=Color.argb(170,rb,255,rb);
}否则{
int gb=(int)(255 deltaY/10);
newColor=Color.argb(170255,gb,gb);
}
rootView.getBackground().setColorFilter(newColor,PorterDuff.Mode.DARKEN);
rootView.setTranslationY(deltaY);
打破
}
rootView.invalidate();
返回true;
}
});
返回rootView;
}
受保护的void onCardSwipeUp(){
Log.i(AppUtil.APP,“刷卡”);
}
受保护的void onCardSwipeDown(){
Log.i(AppUtil.APP,“刷下”);
}
}
}
在进行了一些在线研究之后,我提出了下面的实现,它运行得很好。CardView类扩展了可在类中使用的片段
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");
}
}
}
公共类CardView扩展片段{
私人静态浮动卡刷卡长度=250;
私有浮动原始x=0;
私有浮动初始值=0;
专用浮点startMoveX=0;
专用浮点startMoveY=0;
公共CardView(){
超级();
}
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
视图根视图=充气机。充气(R.layout.card_模板,容器,假);
setOnTouchListener(新视图.OnTouchListener(){
公共布尔onTouch(视图、运动事件){
最终浮点X=event.getRawX();
最终浮点Y=event.getRawY();
浮动deltaX=X-开始移动;
浮点数deltaY=Y-startMov