Android 滑动列表
Posted
技术标签:
【中文标题】Android 滑动列表【英文标题】:Android Swipe on List 【发布时间】:2011-05-21 09:13:01 【问题描述】:有没有人有一个 ListActivity 在列中显示 Textviews 的简单示例,当您从左向右滑动时,您会在新视图中看到该行?这就是说编辑该行的数据或在该行上显示更详细的信息。请不要参考代码 shogun 或其他网站,因为我已经用谷歌搜索过并且没有看到这个答案。
【问题讨论】:
我已经在使用上下文菜单来更改字体大小和长按其他活动。我希望用户能够从左向右滑动以打开他们滑动的行的完整数据屏幕。 我猜现在 Fragments 解决了这个问题。 【参考方案1】:这是我用来检测滑动的 sn-p。然后您可以使用viewflipper 更改视图。
@Override
public boolean onTouchEvent(MotionEvent event)
if (gestureDetector.onTouchEvent(event))
return true;
else
return false;
private static final int SWIPE_MIN_DISTANCE = 30;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
class MyGestureDetector extends SimpleOnGestureListener
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY)
try
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// right to left swipe
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
leftFling();
else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
rightFling();
catch (Exception e)
// nothing
return false;
【讨论】:
正在寻找更多的 prorof 示例。我已经尝试过 viewflippers,但是当你这样做时,列表大小总是很奇怪。我喜欢你的代码,虽然它很干净。我将不得不在以后的尝试中使用它,谢谢【参考方案2】:我遇到了同样的问题,但在这里没有找到答案。
我想检测 ListView 项中的滑动操作并将其标记为已滑动,同时继续支持 OnItemClick 和 OnItemLongClick。
这是我的解决方案:
第一个 SwipeDetector 类:
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class SwipeDetector implements View.OnTouchListener
public static enum Action
LR, // Left to Right
RL, // Right to Left
TB, // Top to bottom
BT, // Bottom to Top
None // when no action was detected
private static final String logTag = "SwipeDetector";
private static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;
private Action mSwipeDetected = Action.None;
public boolean swipeDetected()
return mSwipeDetected != Action.None;
public Action getAction()
return mSwipeDetected;
@Override
public boolean onTouch(View v, MotionEvent event)
switch (event.getAction())
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
mSwipeDetected = Action.None;
return false; // allow other events like Click to be processed
case MotionEvent.ACTION_UP:
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// horizontal swipe detection
if (Math.abs(deltaX) > MIN_DISTANCE)
// left or right
if (deltaX < 0)
Log.i(logTag, "Swipe Left to Right");
mSwipeDetected = Action.LR;
return false;
if (deltaX > 0)
Log.i(logTag, "Swipe Right to Left");
mSwipeDetected = Action.RL;
return false;
else if (Math.abs(deltaY) > MIN_DISTANCE) // vertical swipe
// detection
// top or down
if (deltaY < 0)
Log.i(logTag, "Swipe Top to Bottom");
mSwipeDetected = Action.TB;
return false;
if (deltaY > 0)
Log.i(logTag, "Swipe Bottom to Top");
mSwipeDetected = Action.BT;
return false;
return false;
return false;
第二个我在列表视图中使用滑动检测器类:
final ListView lv = getListView();
final SwipeDetector swipeDetector = new SwipeDetector();
lv.setOnTouchListener(swipeDetector);
lv.setOnItemClickListener(new OnItemClickListener()
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
if (swipeDetector.swipeDetected())
// do the onSwipe action
else
// do the onItemClick action
);
lv.setOnItemLongClickListener(new OnItemLongClickListener()
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id)
if (swipeDetector.swipeDetected())
// do the onSwipe action
else
// do the onItemLongClick action
);
这样我可以支持 3 种操作 - 滑动、单击、长按,并且我可以使用 ListView 项目信息。
稍后添加:
由于 ListView 捕捉到滚动动作,因此有时很难滑动。为了解决这个问题,我对 SwipeDetector.onTouch 进行了以下更改:
public boolean onTouch(View v, MotionEvent event)
switch (event.getAction())
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
mSwipeDetected = Action.None;
return false; // allow other events like Click to be processed
case MotionEvent.ACTION_MOVE:
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// horizontal swipe detection
if (Math.abs(deltaX) > HORIZONTAL_MIN_DISTANCE)
// left or right
if (deltaX < 0)
Log.i(logTag, "Swipe Left to Right");
mSwipeDetected = Action.LR;
return true;
if (deltaX > 0)
Log.i(logTag, "Swipe Right to Left");
mSwipeDetected = Action.RL;
return true;
else
// vertical swipe detection
if (Math.abs(deltaY) > VERTICAL_MIN_DISTANCE)
// top or down
if (deltaY < 0)
Log.i(logTag, "Swipe Top to Bottom");
mSwipeDetected = Action.TB;
return false;
if (deltaY > 0)
Log.i(logTag, "Swipe Bottom to Top");
mSwipeDetected = Action.BT;
return false;
return true;
return false;
【讨论】:
为什么如果您返回真实的其他事件(如 Click)不会被处理? @Pinhassi HORIZONTAL_MIN_DISTANCE 和 VERTICAL_MIN_DISTANCE 的值是多少 HORIZONTAL_MIN_DISTANCE 和 VERTICAL_MIN_DISTANCE 是用户手指应该移动的最小距离,以便将操作视为滑动。我将其设置为:HORIZONTAL_MIN_DISTANCE = 40; VERTICAL_MIN_DISTANCE = 80; 如果我错了,请纠正我,但是;您是否应该为 HORIZONTAL_MIN_DISTANCE 和 VERTICAL_MIN_DISTANCE 使用 DP 值。这门课的未来证明。 (适用于超高分辨率手机和桌子) 这是一个非常棒的人。唯一的问题是它没有那么敏感。我需要先用手指在项目上保持足够长的时间,然后才能滑动。此外,大多数时候它甚至没有注册我的滑动。有更好的解决方案吗?【参考方案3】:这是一个非常简化的版本,使用了两个监听器(onTouch 用于滑动检测,onClickIem 用于项目点击检测) 使用 isSwipe 标志停止 onClickItemListener 直到确认不是滑动
检测点击 考虑到它不是先滑动
listView.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
if(!isSwipe)
adapter.increase(arg2);
adapter.notifyDataSetChanged();
);
检测滑动
listView.setOnTouchListener(new OnTouchListener()
private int action_down_x = 0;
private int action_up_x = 0;
private int difference = 0;
@Override
public boolean onTouch(View v, MotionEvent event)
switch (event.getAction())
case MotionEvent.ACTION_DOWN:
action_down_x = (int) event.getX();
isSwipe=false; //until now
break;
case MotionEvent.ACTION_MOVE:
if(!isSwipe)
action_up_x = (int) event.getX();
difference = action_down_x - action_up_x;
if(Math.abs(difference)>50)
Log.d("action","action down x: "+action_down_x);
Log.d("action","action up x: "+action_up_x);
Log.d("action","difference: "+difference);
//swipe left or right
if(difference>0)
//swipe left
Log.d("action","swipe left");
adapter.decrease(selectedItem);
adapter.notifyDataSetChanged();
else
//swipe right
Log.d("action","swipe right");
isSwipe=true;
break;
case MotionEvent.ACTION_UP:
Log.d("action", "ACTION_UP - ");
action_down_x = 0;
action_up_x = 0;
difference = 0;
break;
return false; //to allow the clicklistener to work after
)
【讨论】:
【参考方案4】:如果您想在滑动列表项时显示一些带有操作的按钮,互联网上的很多库都有这种行为。 我实现了我在互联网上找到的库,我非常满意。它使用起来非常简单,而且速度非常快。我改进了原始库,并为项目单击添加了一个新的单击侦听器。我还添加了 font awesome 库 (http://fortawesome.github.io/Font-Awesome/),现在您可以简单地添加一个新项目标题并从 font awesome 指定图标名称。
Here是github链接
【讨论】:
以上是关于Android 滑动列表的主要内容,如果未能解决你的问题,请参考以下文章
滑动手势不支持用手指在 android 的滑动抽屉中的列表视图上