【问题标题】:How to stop the custom view refreshing?如何停止自定义视图刷新?
【发布时间】:2012-10-26 13:35:43
【问题描述】:

我在扩展 View 类的类中使用 onDraw(Canvas canvas) 方法创建了一个自定义视图。我正在使用 invalidate() 方法每 2 秒刷新一次视图。但是现在我想在之后停止刷新视图一段时间后说 120 秒。我将如何停止 invalidate() 方法。任何建议或帮助将不胜感激。

编辑

这是我的代码:-

public GameView(Context context){ 
super(context);

Display display = ((WindowManager)context.getSystemService(
             Context.WINDOW_SERVICE)).getDefaultDisplay();
}

@Override
    public void draw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.draw(canvas);

        int x = 0;
        int y = 0;

        bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
        int imageWidth = bmp.getWidth();
        int imageHeight = bmp.getHeight();

        int width = display.getWidth();
        System.out.println("Width = " +width);
        int height = display.getHeight();
        System.out.println("Height = " +height);
        Random randomX,randomY;
        randomX = new Random();
        randomY = new Random();

        x = randomX.nextInt(width - imageWidth);
        System.out.println("X = " +x);
        y = randomY.nextInt(height - imageHeight);
        System.out.println("Y = " +y);

        Rect dst = new Rect(x , y , x + imageWidth , y + imageHeight);
        canvas.drawBitmap(bmp, null , dst , null);
        System.out.println("dst = " +dst);
        try{
        Thread.sleep(1000)
        }
        catch(Exception e){

        }
        invalidate();

    }  

【问题讨论】:

  • 从哪里调用 invalidate()?
  • 你能发布一些示例代码吗?
  • 请看修改后的内容。
  • 我不相信没有人能回答这个问题。

标签: android android-canvas android-view


【解决方案1】:

好吧,我个人不会通过在我的 draw 方法中调用 Thread.sleep(1000) 来阻止 UI 线程。相反,我会使用一个 Handler 对象,然后我会调用递归 postDelayed 调用以安排重复的 invalidate() 调用。最后,我编写了 2 个特殊函数来启动“动画”并在需要时中断它(以下代码未经测试......我在几秒钟内写了一个 sn-p 来说明我的观点。警告购买者。) .请注意,Aderito Brinca 所描述的内容也是准确的,尽管它并没有解决上面提到的 UI 线程阻塞问题。

private Handler mHandler = new Handler();
private boolean isAnimStarted=false;
final private long refreshIntervalMsec = 2000;     //2 seconds refresh rate
final private long maxRefreshTimeMsec = 120000; //120 seconds deadline
private long systemTimeMillisOnStart = -1L;
private Display display = null; //within a local variable declared in GameView
//constructor this variable was useless. Now that it is a private
//class member, it can be used by overridden onDraw or Draw methods.

public GameView(Context context){ 
    super(context);
    display = ((WindowManager)context.getSystemService(
             Context.WINDOW_SERVICE)).getDefaultDisplay();
    //INSERT THE REST OF YOUR CONSTRUCTOR CODE HERE
}

public boolean isGameViewAnimStarted(){ //CALL this in order to check for running anim
    return isAnimStarted;
}

public void startGameViewAnim(){ //CALL this to start your anim thing
    isAnimStarted=true;
    systemTimeMillisOnStart = SystemClock.uptimeMillis();
    refreshAnim();
}

private void refreshAnim(){
    invalidate();
    if(  (SystemClock.uptimeMillis() - systemTimeMillisOnStart) < maxRefreshTimeMsec){
        mHandler.postDelayed(new Runnable(){
            public void run(){              
                refreshAnim();
            }
        }, refreshIntervalMsec);
    }
    else{
        stopGameViewAnim();
    }
}

public void stopGameViewAnim(){ //CALL this to interrupt your anim thing
    mHandler.removeCallbacksAndMessages(null);
    isAnimStarted=false;
}



@Override
public void draw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.draw(canvas);
    //INSERT YOUR CODE HERE

} 

【讨论】:

    【解决方案2】:

    您只需要使用一个计数器(例如 int myCounter)并在每个周期中将其值增加 2。然后,您可以将调用线程和 invalidate() 的代码包含在检查指令中,以便仅当变量 myCounter 小于 120 时才执行此程序块。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      相关资源
      最近更新 更多