我有一个自定义SwipeRefreshLayout,其中具有自定义GridView。我想基于捏/缩放手势更改该GridView的列号。我已经成功实现了。问题是,规模太敏感了。
例如,我的列号为3-5。它很容易缩放到3或5,但很难将其设置为4,因为缩放本身太敏感了。
这是我自定义的SwipeRefreshLayout类
/**
* This class contains fix from http://stackoverflow.com/questions/23989910/horizontalscrollview-inside-swiperefreshlayout
*/
public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {
private int mTouchSlop;
private float mPrevX;
private ScaleGestureDetector mScaleGestureDetector;
private ScaleListener mScaleListener;
public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
public void setScaleListener(Context context, ScaleListener scaleListener) {
this.mScaleListener = scaleListener;
mScaleGestureDetector = new ScaleGestureDetector(context, new MyOnScaleGestureListener());
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (mScaleGestureDetector != null) {
mScaleGestureDetector.onTouchEvent(event);
}
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
setEnabled(false);
if (mScaleListener != null) {
mScaleListener.onTwoFingerStart();
}
break;
case MotionEvent.ACTION_POINTER_UP:
setEnabled(true);
mPrevX = MotionEvent.obtain(event).getX();
if (mScaleListener != null) {
mScaleListener.onTwoFingerEnd();
}
break;
case MotionEvent.ACTION_DOWN:
mPrevX = MotionEvent.obtain(event).getX();
break;
case MotionEvent.ACTION_MOVE:
final float eventX = event.getX();
float xDiff = Math.abs(eventX - mPrevX);
if (xDiff > mTouchSlop) {
return false;
}
}
return super.onInterceptTouchEvent(event);
}
class MyOnScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
private static final String TAG = "MyOnScaleGestureListene";
@Override
public boolean onScale(ScaleGestureDetector detector) {
if (mScaleListener != null) {
// Too sensitive, must change to other approach
float scaleFactor = detector.getScaleFactor();
Log.d(TAG, "onScale: " + scaleFactor);
if (scaleFactor > 1F) {
mScaleListener.onScaleUp(scaleFactor);
} else if (scaleFactor < 1F) {
mScaleListener.onScaleDown(scaleFactor);
} else {
// no scale
}
}
return true;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
}
}
public interface ScaleListener {
void onTwoFingersStart();
void onTwoFingersEnd();
void onScaleUp(float scaleFactor);
void onScaleDown(float scaleFactor);
}
}
有什么办法可以降低ScaleGestureDetector.SimpleOnScaleGestureListener的敏感度?如果没有办法,是否有其他解决办法?
这是显示问题的简短视频
https://www.youtube.com/watch?v=0MItDNZ_o4c
最佳答案
您应该有一个公差距离,在Android世界中称为“倾斜”。如果手势小于该公差,则应忽略它。
private static final int SPAN_SLOP = 7;
...
@Override
public boolean onScale(@NonNull ScaleGestureDetector detector) {
if (gestureTolerance(detector)) {
// performing scaling
}
return true;
}
private boolean gestureTolerance(@NonNull ScaleGestureDetector detector) {
final float spanDelta = Math.abs(detector.getCurrentSpan() - detector.getPreviousSpan());
return spanDelta > SPAN_SLOP;
}
作为示例,您可以看到@rallat制作的展示开源应用程序。
在这里您可以找到source code和presentation at GOTO Copenhagen 2016。