在网格布局上进行手势检测
我想fling
手势检测工作在我的Android应用程序。
我拥有的是一个包含9个ImageView
的GridLayout
。 来源可以在这里找到:Romain Guys的网格布局。
我使用的文件来自Romain Guy的Photostream应用程序,并且只是稍作改动。
对于简单的点击情况我只需要设置onClickListener
每个ImageView
我添加是主要的activity
,它实现View.OnClickListener
。 实施能够识别fling
东西似乎是无限复杂的。 我认为这是因为它可能会跨越views
?
如果我的活动实现了OnGestureListener
我不知道如何将它设置为我添加的Grid
或Image
视图的手势监听器。
public class SelectFilterActivity extends Activity implements
View.OnClickListener, OnGestureListener { ...
如果我的活动实现了OnTouchListener
那么我没有onFling
方法来override
(它有两个事件作为参数,允许我确定是否值得注意)。
public class SelectFilterActivity extends Activity implements
View.OnClickListener, OnTouchListener { ...
如果我做一个自定义的View
,如GestureImageView
扩展ImageView
,我不知道怎么跟一个活动fling
已经从视图中发生。 无论如何,我尝试过这种方法,当我触摸屏幕时不会调用这些方法。
我真的需要一个具体的例子来说明这种观点。 什么时候以及如何附加这个listener
? 我还需要能够检测到单击。
// Gesture detection
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int dx = (int) (e2.getX() - e1.getX());
// don't accept the fling if it's too short
// as it may conflict with a button push
if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.absvelocityY)) {
if (velocityX > 0) {
moveRight();
} else {
moveLeft();
}
return true;
} else {
return false;
}
}
});
是否可以在屏幕顶部放置透明视图来捕捉fl光?
如果我选择不inflate
从XML我的孩子形象的意见我可以传递GestureDetector
作为构造函数参数的一个新的子类ImageView
,我创造?
这是我试图让fling
检测工作的非常简单的活动:SelectFilterActivity(从照片流改编)。
我一直在看这些来源:
检测手势 - 教程
SDK文档
计算器代码
到目前为止,我没有任何工作,我希望得到一些指示。
感谢Code Shogun,其代码适应了我的情况。
让您的活动照常执行OnClickListener
:
public class SelectFilterActivity extends Activity implements OnClickListener {
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private GestureDetector gestureDetector;
View.OnTouchListener gestureListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* ... */
// Gesture detection
gestureDetector = new GestureDetector(this, new MyGestureDetector());
gestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
};
}
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) {
Toast.makeText(SelectFilterActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(SelectFilterActivity.this, "Right Swipe", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// nothing
}
return false;
}
@Override
public boolean onDown(MotionEvent e) {
return true;
}
}
}
将您的手势监听器附加到您添加到主布局的所有视图;
// Do this for each view added to the grid
imageView.setOnClickListener(SelectFilterActivity.this);
imageView.setOnTouchListener(gestureListener);
onFling
观看重写的方法,即活动的onClick(View v)
和手势监听器的onFling
。
public void onClick(View v) {
Filter f = (Filter) v.getTag();
FilterFullscreenActivity.show(this, input, f);
}
这个帖子'扔'舞是可选的,但鼓励。
上面的答案之一提到处理不同的像素密度,但建议手动计算滑动参数。 值得注意的是,您实际上可以使用ViewConfiguration
类从系统获取缩放的合理值:
final ViewConfiguration vc = ViewConfiguration.get(getContext());
final int swipeMinDistance = vc.getScaledPagingTouchSlop();
final int swipeThresholdVelocity = vc.getScaledMinimumFlingVelocity();
final int swipeMaxOffPath = vc.getScaledTouchSlop();
// (there is also vc.getScaledMaximumFlingVelocity() one could check against)
我注意到,使用这些值会导致应用程序和系统其余部分之间的投掷“感觉”更加一致。
我做了一些改变,写了一个额外的检测器类来实现View.onTouchListener
onCreate
简单地将它添加到像这样的最低布局:
ActivitySwipeDetector activitySwipeDetector = new ActivitySwipeDetector(this);
lowestLayout = (RelativeLayout)this.findViewById(R.id.lowestLayout);
lowestLayout.setOnTouchListener(activitySwipeDetector);
其中id.lowestLayout是布局层次结构中视图最低的id.xxx,而lowestLayout则声明为RelativeLayout
然后是实际活动滑动检测器类:
public class ActivitySwipeDetector implements View.OnTouchListener {
static final String logTag = "ActivitySwipeDetector";
private Activity activity;
static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;
public ActivitySwipeDetector(Activity activity){
this.activity = activity;
}
public void onRightSwipe(){
Log.i(logTag, "RightToLeftSwipe!");
activity.doSomething();
}
public void onLeftSwipe(){
Log.i(logTag, "LeftToRightSwipe!");
activity.doSomething();
}
public void onDownSwipe(){
Log.i(logTag, "onTopToBottomSwipe!");
activity.doSomething();
}
public void onUpSwipe(){
Log.i(logTag, "onBottomToTopSwipe!");
activity.doSomething();
}
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
downY = event.getY();
return true;
}
case MotionEvent.ACTION_UP: {
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// swipe horizontal?
if(Math.abs(deltaX) > Math.abs(deltaY))
{
if(Math.abs(deltaX) > MIN_DISTANCE){
// left or right
if(deltaX > 0) { this.onRightSwipe(); return true; }
if(deltaX < 0) { this.onLeftSwipe(); return true; }
}
else {
Log.i(logTag, "Horizontal Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
return false; // We don't consume the event
}
}
// swipe vertical?
else
{
if(Math.abs(deltaY) > MIN_DISTANCE){
// top or down
if(deltaY < 0) { this.onDownSwipe(); return true; }
if(deltaY > 0) { this.onUpSwipe(); return true; }
}
else {
Log.i(logTag, "Vertical Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
return false; // We don't consume the event
}
}
return true;
}
}
return false;
}
}
对我真的很好!
链接地址: http://www.djcxy.com/p/2651.html