2

在我正在尝试构建的相关视图的研发中,我开始了一个简单的项目来掌握如何在超越自己之前完成更多的基本绘图“东西”。

就像我的其他问题状态一样,SurfaceView 线程和动画有很多信息,但我觉得这个应用程序可能有点矫枉过正。我将一次在屏幕上显示 10 到数百个最终视图,从我收集到的 SurfaceView 中,它通常用作 Activity 的主视图(游戏屏幕等)。

这个研发应用画了几个圆圈,并计算目标(红线)和之前位置(白线)之间的距离:

当前实现的屏幕截图

onDraw的非常简单,但是我很难弄清楚如何实现线程或处理程序,或任何类型的非 UI 循环来计算目标和主圆之间的值。

我有一个私有的静态内部线程,我认为这很容易,但没有骰子。最新的弗兰肯码:

private static class DragThread extends Thread {
    private DragTest view;
    private boolean animate;

    private float currentY, targetY, delta, inc;

    public DragThread(View v){
        view = (DragTest)v;
        targetY = view.mTargetData.getY();
        currentY = view.mMainData.getY();
    }
    public void run(){
        while(Math.abs(currentY - targetY) >= 0){
            view.mMainData.setY(currentY + 10f);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {

            }finally{
                view.postInvalidate();    
            }
        }
        Log.e(TAG, "Loop finished");
    }
}

mMainData并且mTargetData只是持有每个圆的位置值的 POJO,我的 onDraw 使用它来更新位置:

mMainData = new CircleData(startXposition, startYposition, radius);

...并使用标准吸气剂检索。

本质上,我知道当我抬起手指时我需要启动循环逻辑,但是我遇到了一些错误,从“线程已经启动”到冻结和崩溃。处理程序给我泄漏警告......伙计。我花光了。

这是onTouchEvent我的观点,并解释了每个事件:

@Override
public boolean onTouchEvent(MotionEvent event) {
    int action = event.getAction();

    if(action == MotionEvent.ACTION_DOWN){

        // set some flags for drawing, update "hero" circle Y position
        // based off event data
    }else if(action == MotionEvent.ACTION_UP){

        // reset flags that dictate ghost circle drawing, etc. and invalidate
        // I think I need to start the loop here, but how?! 
        // new Thread().start()? Some sort of Handler? GAH!

    }else if(action == MotionEvent.ACTION_MOVE){
        // update mMainData Y position which is passed into onDraw, invalidate to reflect movement changes
    }        
    return false;
}
4

1 回答 1

2

根据这篇文章,解决方案显然是盯着我的脸,但我认为它比实际更难。

有问题的示例应用程序的最终解决方案是让视图实现,当用户抬起手指时Runnable设置一个新动画,并使用 a来计算偏移量。ThreadScroller

@Override
public boolean onTouchEvent(MotionEvent event) {
    int action = event.getAction();

    if(action == MotionEvent.ACTION_DOWN){
        // ...
    }else if(action == MotionEvent.ACTION_UP){
        // ...

        startAnimation();
        return true;
    }else if(action == MotionEvent.ACTION_MOVE){
        // ...
    }        
    return false;
}
public void run(){
    int start = (int)mMainData.getY();
    int end   = (int)mTargetData.getY();

    mScroller.startScroll(0, start, 0, -Math.round(mMainData.getY() - end), 500);

    while(canAnimate()){
        while(mScroller.computeScrollOffset()){
            mMainData.setY(mScroller.getCurrY());
            postInvalidate();
        }
        stopAnimation();
    }
}
private void startAnimation(){
    mThread = new Thread(this);
    mThread.start();
}
private void stopAnimation(){
    animate = false;
}
private boolean canAnimate(){
    return animate == true;
}
于 2012-10-22T07:53:00.447 回答