【问题标题】:View is not automatically being drawed when overriding dispatchDraw覆盖 dispatchDraw 时不会自动绘制视图
【发布时间】:2011-05-10 13:45:25
【问题描述】:

我正在尝试镜像 LinearLayout。 为了完成这项工作,我扩展了 LinerLayout 以创建自己的 View 组件。

这就是它的样子:

    public class FlipLayout extends LinearLayout implements Runnable {
        private boolean isMirroring = true;
        private Handler handler;

        public FlipLayout(Context context) {
            super(context);
            this.setWillNotDraw(false);
        }

        public FlipLayout(Context context, AttributeSet attr) {
            super(context, attr);
            this.setWillNotDraw(false);
            handler = new Handler();
            handler.postDelayed(this, 30);

        }

        @Override
        protected void dispatchDraw(Canvas canvas) {
            canvas.save();
            if (isMirroring) {
                canvas.rotate(180, getWidth() / 2, getHeight() / 2);
            }
            super.dispatchDraw(canvas);
            canvas.restore();
        }

        @Override
        public boolean dispatchTouchEvent(MotionEvent event) {
            if (isMirroring)
                event.setLocation(getWidth() - event.getX(),
                        getHeight() - event.getY());
            return super.dispatchTouchEvent(event);
        }

        @Override
        public void run() {
            invalidate();
            handler.postDelayed(this, 30);
        }

    }

该类运行良好,但仅在实现 Runnable 接口并每隔几毫秒调用一次 invalidate() 时。

如果我只旋转画布而不使视图无效,则不会绘制子视图的更改。 现在我想知道这种行为的原因是什么,以及是否有办法让它在没有 Runnable/Handler 实现的情况下工作。 如果我删除行 canvas.rotate(...) 正确绘制子视图的更改(例如,这是一个经常更新自身的进度条。)

希望有人能帮忙! 非常感谢。 克里斯

【问题讨论】:

    标签: android view canvas rotation mirroring


    【解决方案1】:

    在我看来,动态更改 Gui 不会更新屏幕是正常的。在任何 Gui 框架中,它们都需要程序员手动请求重绘。

    这是因为如果我更改 Gui 中的 10 个项目,我不想重绘 10 次,但最后只重绘一次。当我完成对 Gui 的重构时,框架无法猜测。所以我需要以某种方式显式调用刷新方法。

    或者,您可以在完成旋转内容后直接使 Gui 无效,而不是在单独的线程中。

    【讨论】:

    • 好吧,我明白你的意思了。但是为什么在不进行旋转的情况下正确绘制视图(所有子视图更新)?我尝试在旋转画布后使视图无效。这也很有效。但我在另一个论坛上读到,从 witin dispatchDraw() 调用 invalidate() 并不是一个好主意,因为 invalite() 本身会导致 dispatchDraw() 被执行 - 但我不确定这是否正确。
    • 我不确定你到底在做什么,但我可以告诉你 Gui 中有两种变化。正常变化:例如,如果您滚动,滚动条必须移动。异常变化:我删除了一个按钮并添加了一个文本视图。正常更改将自动反映在屏幕上,因为它是框架功能的一部分。而异常更改是您决定作为程序员使用的高级功能,您需要手动刷新 Gui。对于您的调度问题,也许您可​​以尝试将旋转代码移到调度方法之外。
    猜你喜欢
    • 2013-06-25
    • 2012-02-05
    • 2015-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多