列に Textviews を表示する ListActivity の簡単な例があり、左から右にスワイプすると、その行が新しいビューに表示されますか? これは、その行のデータを編集したり、その行に関するより詳細な情報を表示したりすることです。コード shogun や他のサイトを参照しないでください。Google で検索しましたが、この回答は見られませんでした。
30912 次
4 に答える
117
私は同じ問題を抱えていましたが、ここで答えが見つかりませんでした。
OnItemClick と OnItemLongClick を引き続きサポートしながら、ListView アイテムでスワイプ アクションを検出し、スワイプとしてマークしたいと考えていました。
これが私の解決策です:
1 つ目 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;
}
}
2 番目に、リスト ビューでスワイプ検出クラスを使用します。
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;
}
于 2012-02-18T09:55:46.170 に答える
1
isSwipe フラグを使用して 2 つのリスナー (スワイプ検出用の onTouch とアイテム クリック検出用の onClickIem) を使用した非常に単純化されたバージョンを次に示します。
最初にスワイプではないことを考慮してクリックを検出する
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
}
})
于 2014-06-17T14:13:56.737 に答える
1
これは、スワイプを検出するために使用するスニペットです。その後、 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;
}
}
于 2011-05-04T11:50:58.993 に答える