- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试实现一个可拖动的按钮,该按钮也应该是可滑动的。
不幸的是,系统在拖动开始后停止发送 MotionEvents。因此,永远不会调用 GestureDetector.OnGestureListener.onFling() 方法。
有没有办法在拖动系统消耗这些事件之前拦截它们?
我也尝试创建自己的 FlingDetector,但它在不同的设备和屏幕密度上并不可靠:
public class FlingDetector {
private final int MIN_FLING_SPEED = 3;
private OnFlingListener mOnFlingListener;
private float mCurrentX = 0;
private float mCurrentY = 0;
private long mLastMovementTime = 0;
private double mCurrentVelocity = 0;
private final float mDensity;
public FlingDetector(OnFlingListener onFlingListener, Context context) {
mOnFlingListener = onFlingListener;
mDensity = context.getResources().getDisplayMetrics().density;
}
public void onMovementStart(float x, float y) {
mCurrentX = x;
mCurrentY = y;
mLastMovementTime = System.currentTimeMillis();
mCurrentVelocity = 0;
}
public void onMovementEnd(float x, float y) {
long currentTime = System.currentTimeMillis();
float distanceX = Math.abs(mCurrentX - x) / mDensity;
float distanceY = Math.abs(mCurrentY - y) / mDensity;
float distance = (float) Math.sqrt(Math.pow(distanceX, 2) +
Math.pow(distanceY, 2));
mCurrentVelocity = (distance / (currentTime - mLastMovementTime));
if(mCurrentVelocity > MIN_FLING_SPEED) {
mOnFlingListener.onFling((int) (mCurrentVelocity + 0.5));
} else {
Log.d("test", "Distance: " + distance);
Log.d("test", "Time Delta: " + (currentTime - mLastMovementTime));
Log.d("test", "Speed: " + mCurrentVelocity);
}
}
public interface OnFlingListener {
void onFling(int speed);
}
}
最佳答案
您可以使用 GestureDetector 通过按钮实现滑动和拖动。GestureDetector 有点直截了当,它有自己的默认方法来处理以下运动事件。
你可以这样实现。
public class MainActivity extends AppCompatActivity {
Button button;
GestureDetector buttonGestureDetector;
static final int SWIPE_MIN_DISTANCE = 60;
static final int SWIPE_THRESHOLD_VELOCITY = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button) findViewById(R.id.button);
buttonGestureDetector=new GestureDetector(this,new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
Log.i("Drag","DragListening");
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(button);
button.startDrag(null, shadowBuilder, button, 0);
button.setVisibility(View.INVISIBLE);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.i("FlingListened","FlingListened");
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(MainActivity.this,"OnRightToLeft Fling",Toast.LENGTH_SHORT).show();
}
else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
{
Toast.makeText(MainActivity.this,"OnLeftToRight Fling",Toast.LENGTH_SHORT).show();
}
if (e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(MainActivity.this,"onBottomToTop Fling",Toast.LENGTH_SHORT).show();
}
else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(MainActivity.this,"OnTopToBottom Fling",Toast.LENGTH_SHORT).show();
}
return true;
}
});
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
buttonGestureDetector.onTouchEvent(event);
return false;
}
});
button.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View dragView, DragEvent event)
{
int action = event.getAction();
switch (action) {
case DragEvent.ACTION_DRAG_STARTED:
Log.d("Drag", "Drag event started");
break;
case DragEvent.ACTION_DRAG_ENTERED:
Log.d("Drag", "Drag event entered into "+dragView.toString());
break;
case DragEvent.ACTION_DRAG_EXITED:
Log.d("Drag", "Drag event exited from "+dragView.toString());
break;
case DragEvent.ACTION_DROP:
Log.d("Drag", "Dropped");
View view = (View) event.getLocalState();
ViewGroup owner = (ViewGroup) view.getParent();
owner.removeView(view);
LinearLayout container = (LinearLayout) dragView;
container.addView(view);
view.setVisibility(View.VISIBLE);
break;
case DragEvent.ACTION_DRAG_ENDED:
Log.d("Drag", "Drag ended");
break;
default:
break;
}
return true;
}
});
}
}
关于android - 拖放 + Fling 检测器不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34434241/
我有一个包含多个全屏图像的画廊。我想将滑动手势限制为一次仅前进一张图像(如 HTC Gallery 应用程序)。实现此目标的正确/最简单方法是什么? 最佳答案 只需覆盖 Gallery Widget
我有一个使用 HorizontalScrollView 和 horizontal-LinearLayout 的简单布局,如下所示:
有没有办法在附加到 ListView 的 ScrollListener 中获取 Fling 的方向(向上或向下)?我得到 OnScrollListener.SCROLL_STATE_FLING 没有问
我无法让我的应用程序注册特定 Actor 的 throw Action 。当向 Actor 添加一个简单的tap并检查 table 上的点击时,我没有任何问题。对 flick 做同样的事情,但不起作用
package com.example.flingtry; import android.os.Bundle; import android.app.Activity; import android.
这是一个不言自明的问题。我无法在 nestedScrollView 中使用滑动手势展开折叠的工具栏。在挥动手势(注意溢出)后,我手动滚动到顶部以使工具栏展开。我尝试了滚动标志的一些变体,例如 scro
我正在尝试实现一个可拖动的按钮,该按钮也应该是可滑动的。 不幸的是,系统在拖动开始后停止发送 MotionEvents。因此,永远不会调用 GestureDetector.OnGestureListe
我想检测屏幕 block 中的快速运动。我为此使用以下代码。 public class MyinfoActivity extends Activity implements OnGestureList
简单的问题 - 如何在滑动项目时禁用 recyclerview 滚动?我在 recyclerView 项目 View 持有者中创建了 OnTouchListener,但它仅在用户制作水平直线时才捕获滑
我想在我的 ListView 中添加一个监听器,用于检测用户何时触发了一个 fling。我已经有一个滚动监听器,但希望在用户决定“飞”离当前位置时执行后台操作。 谢谢,劳伦斯 最佳答案 试试 List
在 Android 开发者 gesture design section ,使用了“滑动”一词。 在 developer section ,使用了“fling”这个词。 这些术语是同义词吗?根据我的发
我想让 fling 手势检测在我的 Android 应用程序中工作。 我拥有的是一个包含 9 个 ImageView 的 GridLayout。来源可以在这里找到:Romain Guys's Grid
我正在尝试实现一个 ImageSwitcher 以移动到下一张图片。 单击“下一步”按钮时效果很好,但我无法让它与 fling GestureDetector 一起使用。 基本上,我在 onFling
为了提高列表滚动的性能,我有 implemented this suggestion而且它肯定会提高性能。 我的是这样实现的 @Override public void onScrollStateCh
我有一个水平的RecyclerView。我需要滚动它但要通过滑动手势禁用 throw 。 最初所有工作都是在 onTouchEvent 方法中完成的,我不知道如何在不重写所有触摸处理的情况下禁用它 最
这真是令人抓狂。我有以下 XML 布局: 还有 Java: viewFlipper = (ViewFlipper)findViewById(R.i
有没有办法以编程方式在 ListView 上执行 Fling?我知道有 monkey 可以做所有这些事情,但这需要与 adb 等计算机连接。我想在任何手机上用我的应用程序来做,没有 monkey。 谢
我正在开发一个应用程序,它需要我手动处理发送过程,而不是将其交给框架。我想要实现的基本上是计算 ListView 在收到 throw Action 时移动的像素数量。由于滚动方法已经提供了增量形式的距
我必须实现一个画廊,它可以移动到下一张带有动画的幻灯片。我在这里找到了一些解决方案: How to have scrolling animation programmatically 我正在使用这段代
我需要限制我的用户可以在 map View 中导航到的区域(除非他们会得到一个空白屏幕!)。我创建了一个扩展 mapview 并覆盖 onTouchEvent 的类。我正在检测“ACTION_UP”
我是一名优秀的程序员,十分优秀!