如何停止自定义视图刷新?

发布于 2024-12-25 21:54:46 字数 1481 浏览 0 评论 0原文

我在扩展 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();

    }  

I have created a custom view using onDraw(Canvas canvas) method in a class which extends View class.I am using invalidate() method to refresh my view in every 2 second.But now I want to stop refreshing the view after some time say after 120 seconds.How will I stop invalidate() method. Any suggestions or help will be highly appreciated.

EDIT

Here's my code:-

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();

    }  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

也只是曾经 2025-01-01 21:54:46

好吧,我个人不会通过在我的绘制方法中调用 Thread.sleep(1000) 来阻止 UI 线程。相反,我将使用 Handler 对象,然后调用递归 postDelayed 调用以安排重复的 invalidate() 调用。最后,我编写了 2 个特殊函数来启动“动画”并在需要时中断它(以下代码未经测试......只是我在几秒钟内编写的一个片段来说明我的观点。买者自负。)。请注意,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

} 

Well, I wouldn't personally block the UI thread by calling Thread.sleep(1000) within my draw method. Instead, I would use a Handler object, then I'd call recursive postDelayed calls in order to schedule repeated invalidate() calls. Finally, I'd code 2 special functions to start the "animation" and to interrupt it if needed (following code is NOT tested... Just a snippet I wrote in a few sec to illustrate my point. Caveat emptor.). Note that what which was described by Aderito Brinca is accurate as well, although it doesn't solve the UI thread blocking issue as mentioned above.

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

} 
深陷 2025-01-01 21:54:46

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

You just need to use a counter (e.g. int myCounter) and increase its value by 2 in each cycle. You can then enclose your code that calls the thread and the invalidate() inside a check instruction in order for you to execute this program block only if you variable myCounter is less than 120.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文