0

我有一个包含用户绘图的视图。单击“播放”按钮时,我希望有一个从头到尾绘制图像的循环。

在尝试这样做时,我基本上在播放按钮的 onClickListener 中有一个循环,它基本上使视图无效,等待,设置下一组点并再次无效。

问题是图像直到整个图像被绘制之后才真正重绘。所以基本上什么都没有发生,然后它就突然完成了。在做了一些研究之后,我的假设是 invalidate 是告诉主 UI 线程在有时间时重新绘制,但它已经挂起处理侦听器,所以它实际上直到循环完成才绘制。我试过直接调用 onDraw,使用 postInvalidate,以及我能想到的任何其他荒谬的事情,但我不确定如何让它工作。

以下是一些代码片段:

在我的 PaintActivity(Which has a PaintAreaView) 中,scrubber 指示绘图的进度。onProgressChanged 中的第一行在我手动使用搜索栏时有效,但在按下播放时无效,这就是我尝试添加所有额外内容的原因。

        _scrubber.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            _paintAreaView.setPointsToDraw(_scrubber.getProgress());
            _paintAreaView.invalidate();
            _mainViewGroup.invalidate();
            _paintAreaView.postInvalidate();
            _mainViewGroup.postInvalidate();
            _paintAreaView.drawPoints(_paintAreaView.getCanvas());
            _paintAreaView.invalidate();
        }...

我的播放按钮的东西:

        play.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            ...
            playDrawing();
            ...
        }
    });

    private void playDrawing()
{
    int endPoint = getPaintPointCount();

    while(_scrubber.getProgress() < endPoint)
    {
        _scrubber.incrementProgressBy(1);

        try{
            Thread.sleep(10);
        }catch(InterruptedException e)
        {
            Thread.currentThread().interrupt();
        }
        //_paintAreaView.setPointsToDraw(_scrubber.getProgress());
        //_paintAreaView.invalidate();
        //_mainViewGroup.invalidate();
        if(_isPaused)
            break;
    }
}

我不是使用那种睡眠的超级粉丝,但我一直在努力寻找其他解决方案,这是我接下来要研究的事情。但是对于这个问题,增加进度条确实成功地调用了onProgressChanged,但它只是在它退出播放按钮单击侦听器之前才绘制视图。

如果我必须等到我离开听众才能让它工作,我已经足够新了,我不确定我会如何处理它。

抱歉我的代码不好,非常感谢任何帮助,以帮助我了解这里发生的事情以及我需要了解什么才能使其正常工作。

谢谢!

4

1 回答 1

0

我让它工作了,我不确定我所做的一切是否有必要,但这里是我基于我的主 UI 线程理论所做的更改是问题所在。

我创建了一个类 Thread 成员变量:

private Thread _drawThread;

在 onCreate() 中:

_drawThread = new Thread(){
    public void run(){
        playDrawing();
    }
};

播放按钮 onClick:

play.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
         ...
         _drawThread.start();
    }
});

似乎正在做我想做的事!除了应用程序在我第二次点击播放时崩溃 :) 从这里我认为解决这个问题不会太糟糕。

编辑----- 在我的播放按钮 onClickListener 中创建线程,而不是让它成为修复崩溃的成员变量。我错误地认为一旦侦听器超出主线程的范围,线程就会被销毁,但我想情况并非如此。

于 2013-10-23T00:16:54.937 回答