要实现的效果:三星手机上左右滑动任一项联系人(ListView的Item),即可进行打电话或发短信的操作;备忘软件Any.Do中,滑动ListView中任一项即可标记为已完成。
作为一个初学者,为了实现这一效果,花了很长时间终于才成功,希望大家支持下{:soso_e113:}。
思路:使用了OnItemClickListener, OnGestureListener,前者用于判断当前选中的项,后者用于判断是左右滑动还是直接点击选项。当在一项上滑动时, 会执行onFling,直到手指放开时才会执行onItemClick方法,所以先在onFling 中判断是否为滑动动作,保存到一个全局变量中,然后在onItemClick 中根据这个变量的值就能判断动作。这样做也避免了滑动时先响应了onItemClick方法造成的干扰。
Layout中只有一个ListView
[mw_shl_code=xhtml,false]
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
[/mw_shl_code]
Java代码如下:
[mw_shl_code=java,true]
public class MainActivity extends Activity implements OnItemClickListener, OnGestureListener {
private GestureDetector gd;
// 事件状态
private final char FLING_CLICK = 0;
private final char FLING_LEFT = 1;
private final char FLING_RIGHT = 2;
private char flingState = FLING_CLICK;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gd = new GestureDetector(this);
ListView lv = (ListView) findViewById(R.id.listView1);
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_expandable_list_item_1,getData()));
lv.setOnItemClickListener(this);
}
private List<String> getData(){
List<String> data = new ArrayList<String>();
data.add("测试数据0");
data.add("测试数据1");
data.add("测试数据2");
data.add("测试数据3");
data.add("测试数据4");
data.add("测试数据5");
data.add("测试数据6");
data.add("测试数据7");
data.add("测试数据8");
data.add("测试数据9");
data.add("测试数据10");
data.add("测试数据11");
data.add("测试数据12");
return data;
}
/**
* 事件处理
* 其中flingState的值为事件
* 参数pos为ListView的每一项
*/
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
// TODO Auto-generated method stub
Log.v("MY_TAG", "onItemClick: state="+flingState+", pos="+pos);
switch(flingState) {
// 处理左滑事件
case FLING_LEFT:
Toast.makeText( this, "Fling Left:"+pos, Toast.LENGTH_SHORT).show();
flingState = FLING_CLICK;
break;
// 处理右滑事件
case FLING_RIGHT:
Toast.makeText( this, "Fling Right:"+pos, Toast.LENGTH_SHORT).show();
flingState = FLING_CLICK;
break;
// 处理点击事件
case FLING_CLICK:
switch(pos) {
case 0:break;
case 1:break;
}
Toast.makeText( this, "Click Item:"+pos, Toast.LENGTH_SHORT).show();
break;
}
}
/**
* 覆写此方法,以解决ListView滑动被屏蔽问题
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
this.gd.onTouchEvent(event);
return super.dispatchTouchEvent(event);
}
/**
* 覆写此方法,以使用手势识别
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v("MY_TAG", "onTouchEvent");
return this.gd.onTouchEvent(event);
}
/**
* 参数解释:
* e1:第1个ACTION_DOWN MotionEvent
* e2:最后一个ACTION_MOVE MotionEvent
* vX:X轴上的移动速度,像素/秒
* vY:Y轴上的移动速度,像素/秒
* 触发条件 :
* X坐标位移大于minX,Y坐标位移小于maxY,移动速度大于minV像素/秒
*
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float vX, float vY)
{
final int minX = 120 ,maxY = 20, minV = 150;
int x1 = (int) e1.getX(), x2 = (int) e2.getX();
int y1 = (int) e1.getY(), y2 = (int) e2.getY();
if( Math.abs(x1-x2)>minX && Math.abs(y1-y2)<maxY && Math.abs(vX)>minV) {
if(x1>x2) {
Log.v("MY_TAG", "Fling Left");
flingState = FLING_LEFT;
}
else {
Log.v("MY_TAG", "Fling Right");
flingState = FLING_RIGHT;
}
}
return false;
}
@Override
public void onLongPress(MotionEvent e) {}
@Override
public void onShowPress(MotionEvent e) {}
@Override
public boolean onDown(MotionEvent e) {return false;}
@Override
public boolean onSingleTapUp(MotionEvent e) {return false;}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float dX,float dY) {
return false;
}
}
[/mw_shl_code]
源码见附件,测试运行正常。
GestureListView.zip
作为一个初学者,为了实现这一效果,花了很长时间终于才成功,希望大家支持下{:soso_e113:}。
思路:使用了OnItemClickListener, OnGestureListener,前者用于判断当前选中的项,后者用于判断是左右滑动还是直接点击选项。当在一项上滑动时, 会执行onFling,直到手指放开时才会执行onItemClick方法,所以先在onFling 中判断是否为滑动动作,保存到一个全局变量中,然后在onItemClick 中根据这个变量的值就能判断动作。这样做也避免了滑动时先响应了onItemClick方法造成的干扰。
Layout中只有一个ListView
[mw_shl_code=xhtml,false]
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
[/mw_shl_code]
Java代码如下:
[mw_shl_code=java,true]
public class MainActivity extends Activity implements OnItemClickListener, OnGestureListener {
private GestureDetector gd;
// 事件状态
private final char FLING_CLICK = 0;
private final char FLING_LEFT = 1;
private final char FLING_RIGHT = 2;
private char flingState = FLING_CLICK;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gd = new GestureDetector(this);
ListView lv = (ListView) findViewById(R.id.listView1);
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_expandable_list_item_1,getData()));
lv.setOnItemClickListener(this);
}
private List<String> getData(){
List<String> data = new ArrayList<String>();
data.add("测试数据0");
data.add("测试数据1");
data.add("测试数据2");
data.add("测试数据3");
data.add("测试数据4");
data.add("测试数据5");
data.add("测试数据6");
data.add("测试数据7");
data.add("测试数据8");
data.add("测试数据9");
data.add("测试数据10");
data.add("测试数据11");
data.add("测试数据12");
return data;
}
/**
* 事件处理
* 其中flingState的值为事件
* 参数pos为ListView的每一项
*/
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
// TODO Auto-generated method stub
Log.v("MY_TAG", "onItemClick: state="+flingState+", pos="+pos);
switch(flingState) {
// 处理左滑事件
case FLING_LEFT:
Toast.makeText( this, "Fling Left:"+pos, Toast.LENGTH_SHORT).show();
flingState = FLING_CLICK;
break;
// 处理右滑事件
case FLING_RIGHT:
Toast.makeText( this, "Fling Right:"+pos, Toast.LENGTH_SHORT).show();
flingState = FLING_CLICK;
break;
// 处理点击事件
case FLING_CLICK:
switch(pos) {
case 0:break;
case 1:break;
}
Toast.makeText( this, "Click Item:"+pos, Toast.LENGTH_SHORT).show();
break;
}
}
/**
* 覆写此方法,以解决ListView滑动被屏蔽问题
*/
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
this.gd.onTouchEvent(event);
return super.dispatchTouchEvent(event);
}
/**
* 覆写此方法,以使用手势识别
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.v("MY_TAG", "onTouchEvent");
return this.gd.onTouchEvent(event);
}
/**
* 参数解释:
* e1:第1个ACTION_DOWN MotionEvent
* e2:最后一个ACTION_MOVE MotionEvent
* vX:X轴上的移动速度,像素/秒
* vY:Y轴上的移动速度,像素/秒
* 触发条件 :
* X坐标位移大于minX,Y坐标位移小于maxY,移动速度大于minV像素/秒
*
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float vX, float vY)
{
final int minX = 120 ,maxY = 20, minV = 150;
int x1 = (int) e1.getX(), x2 = (int) e2.getX();
int y1 = (int) e1.getY(), y2 = (int) e2.getY();
if( Math.abs(x1-x2)>minX && Math.abs(y1-y2)<maxY && Math.abs(vX)>minV) {
if(x1>x2) {
Log.v("MY_TAG", "Fling Left");
flingState = FLING_LEFT;
}
else {
Log.v("MY_TAG", "Fling Right");
flingState = FLING_RIGHT;
}
}
return false;
}
@Override
public void onLongPress(MotionEvent e) {}
@Override
public void onShowPress(MotionEvent e) {}
@Override
public boolean onDown(MotionEvent e) {return false;}
@Override
public boolean onSingleTapUp(MotionEvent e) {return false;}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float dX,float dY) {
return false;
}
}
[/mw_shl_code]
源码见附件,测试运行正常。
