【问题标题】:Change view height in onTouch ACTION_MOVE在 onTouch ACTION_MOVE 中更改视图高度
【发布时间】:2013-02-22 04:25:05
【问题描述】:

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

    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 发生时立即改变视图高度?

【问题讨论】:

    标签: android touch touch-event layoutparams


    【解决方案1】:

    首先,你不需要调用invalidate()requestLayout(),因为setLayoutParams()already does that所以再次手动调用只会造成不必要的开销。

    第二,失去mView.post() 调用:onTouch() 无论如何都会在主(又名 UI)线程上执行。只需将 onTouch() 正文中的 layoutparams 内容与其他所有内容一起执行即可。

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

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

    【讨论】:

    • 我看着 SplitView 并让我的触摸监听器像那里一样。身高不会立即增加!可能是由于我需要更改高度的视图,是我布局中其他视图的锚点,android 必须重新布局所有视图层次结构?
    • @Nik 好吧,这应该不是问题,因为setLayoutParams() 确实在内部调用了requestLayout()。唔。你为什么不更新你的问题并添加新代码,受SplitView启发的代码,然后我们可以看看那里可能有什么问题
    【解决方案2】:

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

    但这不会很快,因为它会导致很多布局事件。不看你的布局,不知道你想要什么样的效果,很难给出更多的建议。

    【讨论】:

    • 没用!像 view.invalidate() 一样工作
    猜你喜欢
    • 1970-01-01
    • 2011-08-14
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多