当用户在屏幕上向下移动手指时,我想更改视图高度.
new OnTouchListener() {
float lastY = Float.MIN_VALUE;
@Override
public boolean onTouch(View v, MotionEvent event) {
if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE) {
if (lastY != Float.MIN_VALUE) {
final float dist = event.getRawY() - lastY;
myView.post(new Runnable() {
@Override
public void run() {
ViewGroup.LayoutParams lp = myView.getLayoutParams();
lp.height += dist;
myView.setLayoutParams(lp);
}
});
view.invalidate();
}
lastY = event.getRawY();
}
if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {
lastY = Float.MIN_VALUE;
}
return true;
}
}
但是,仅当用户停止移动手指时,视图高度才会改变!
如何在ACTION_MOVE发生时立即更改视图高度?
解决方法:
首先,您不需要调用invalidate()或requestLayout(),因为setLayoutParams()already does that如此再次手动调用只会造成不必要的开销.
其次,丢失mView.post()调用:无论如何,onTouch()是在主(aka UI)线程上执行的.只需在onTouch()主体中执行layoutparams内容以及其他所有内容即可.
第三,您的mView.post()调用可能是造成所有麻烦的原因,因为View.post()有效地将作业发布到UI线程的Handler,后者将作业排入队列,直到UI线程可以*执行它们为止.在您的情况下,在每个事件上都运行onTouch()方法太忙了,因此,当您停止传递触摸事件(即停止拖动)时,发布的所有内容都会被执行.
最后,这是当我必须实现可调整大小的视图时使用的主题的很好的参考,它也很可能涵盖了您尝试手动实现的所有功能:k9mail’s own SplitView
class on GitHub.请注意它们如何将坐标保存在ACTION_DOWN中块,然后只是从那里测量高度,而不是调用getHeight()并使用最后一个坐标增量将其递增.这样可以减少一个处理ACTION_DOWN的操作,并且具有mDragging布尔值标志将使您可以删除模糊的lastY = Float.MIN_VALUE;事情.