4

当用户在屏幕上向下移动手指时,我想更改视图高度。

    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 时如何立即更改视图高度?

4

2 回答 2

5

首先,您不需要调用invalidate(),或者requestLayout()因为setLayoutParams() 已经这样做了,所以再次手动调用它只会导致不必要的开销。

其次,丢失mView.post()调用:onTouch()无论如何都在主(又名 UI)线程上执行。只需在正文中执行 layoutparams 的内容onTouch()以及其他所有内容。

第三,您的mView.post()调用可能是造成所有麻烦的原因,因为View.post()有效地将作业发布到 UI 线程Handler,该线程将作业排队,直到 UI 线程可以一一自由地执行它们。在您的情况下,它太忙onTouch()于在每个事件上运行您的方法,因此当您停止提供触摸事件时,您发布的所有内容都会被执行 - 即停止拖动。

最后,这是我在实现可调整大小视图时使用的主题的一个很好的参考,它也很可能涵盖了您尝试手动实现的所有功能: GitHub 上的 k9mail 自己的SplitView。请注意他们如何将坐标保存在ACTION_DOWN块中,然后从那里测量高度,而不是getHeight()使用最后一个坐标增量调用和递增它。这允许减少一次操作 + 处理ACTION_DOWN,并且拥有 mDragging 布尔标志将允许您删除晦涩lastY = Float.MIN_VALUE;的东西。

于 2013-03-07T07:25:51.427 回答
0

而不是view.invalidate()你可以使用view.requestLayout().

不过这不会很快,因为它会导致很多布局事件。如果不查看您的布局并且不知道您的目标是哪种效果,很难提供更多建议。

于 2013-03-07T05:32:30.933 回答