2013-03-20 82 views
1

我刚刚实现了一个简单的应用程序,它随机更改屏幕的颜色并在文本视图中显示颜色的十六进制代码。经过大量搜索(特别是在stackoverflow上的很多帖子)后,我几乎有代码可以做我想做的事情;只有一个差异。当我点击重新开始颜色闪烁的runnable时,它会从其停止的位置“恢复”,即它不会在最初完成延迟,但似乎只会延迟停止它时可能停止的时间。Android:停止可运行并重新启动它

我的完整代码如下。目前,我有一个短按开始屏幕颜色闪烁runnable,并长按停止它。

package com.example.colorflashingproject; 

import android.os.Bundle; 
import android.app.Activity; 
import android.content.Intent; 
import android.graphics.Color; 
import android.view.Menu; 
import android.view.View; 
import android.os.Handler; 
import android.widget.TextView; 

public class MainActivity extends Activity { 

//initialize a boolean variable (true or false only) 
//to check whether the overlay is tinted or not 
boolean isTinted = false; 
boolean colorIsFlashing = false; 

//initialize a handler that we will use to loop a section of code 
//that constantly changes the color of the screen 
public Handler mHandler = new Handler(); 

//this creates the UI and screen view, and sets up some 
//other aspects of the program 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    //set the current view in the user interface as our xml file: 
    setContentView(R.layout.activity_main); 

    //set the background color, and the initial overlay tint: 
    ((View)findViewById(R.id.background_view)).setBackgroundColor(0xFF000000); 
    ((View)findViewById(R.id.overlay_view)).setBackgroundColor(0x00000000); 

    //create the overlayView variable that replesents our overlay for tinting 
    View overlayView = findViewById(R.id.overlay_view); 

    //implement a method that will listen for a short press 
    overlayView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      //implement function to change tint of our overlay 
      if (!colorIsFlashing) { 
       colorIsFlashing = true; 
       mHandler.post(startColorFlashing); 
      } else { 

      } 
     } 
    });  

    //implement a method that will listen for long press: 
    overlayView.setOnLongClickListener(new View.OnLongClickListener() { 
     @Override 
     public boolean onLongClick(View v) { 

      //stop the color flashing if it was started: 
      if (colorIsFlashing) { 
       colorIsFlashing = false; 
       stopColorFlashing(); 
      } 

      //return true tells the system that the long press registered 
      //return false doesn't. A false return would cause 
      //the long click to register as a short click as well 
      return true; 
     } 
    }); 

} 


//this function generates a random color and sets it to the screen 
public void randomChangeTint(){ 
    //generate random color components: 
    int randa = (int) Math.round((int) 0xff * (float) Math.random()); 
    int randr = (int) Math.round((int) 0xff * (float) Math.random()); 
    int randg = (int) Math.round((int) 0xff * (float) Math.random()); 
    int randb = (int) Math.round((int) 0xff * (float) Math.random()); 
    int randColor = Color.argb(randa, randr, randg, randb); 

    //convert color integer to string: 
    String strColor = String.format("#%08X", randColor); 

    //set overlay to our generated random color: 
    ((View)findViewById(R.id.overlay_view)).setBackgroundColor(randColor); 
    ((TextView)findViewById(R.id.textView2)).setText(strColor); 
} 


//this is our 'runnable' that randomly sets the screen color over 
//an interval of time in milliseconds (timeInterval) 
public Runnable startColorFlashing = new Runnable(){ 
    //set overlay view to randomly switch colors 
    int timeInterval=600; 
    public void run() { 
     if (colorIsFlashing){ 
      randomChangeTint(); 
     } else { 

     } 
     mHandler.postDelayed(this, timeInterval); 
    } 
}; 


//this method stops the color flashing: 
public void stopColorFlashing() { 

    //pauses the runnable: 
    mHandler.removeCallbacksAndMessages(startColorFlashing); 

    //re-initializes the runnable as an empty one 
    startColorFlashing = new Runnable(){ 
     public void run() { 
      //empty, nothing here 
     } 
    }; 
} 
} 

如果我离开了stopColorFlashing()的

//re-initializes the runnable as an empty one 
    startColorFlashing = new Runnable(){ 
     public void run() { 
      //empty, nothing here 
     } 
    }; 

部分,然后,通过短按屏幕多次连续似乎开始可运行一遍又一遍,并停止之后再短按重新启动它,它会再次开始闪烁,似乎从停止的位置恢复。我希望它能够“重新开始”。

我已经尝试了一些与Thread.start()和Thread.pause()的东西,但无法弄清楚。有没有办法“杀死”或“销毁”可运行的?

我是新来的java(我知道matlab),任何想法或建议表示赞赏。我确定我的代码写得非常糟糕,而且效率不高。

回答

1

好吧,我找到了一个解决方案,按照AOSP桌面时钟的例子,它是如何在屏幕保护程序模式下每分钟左右移动时间显示的。我认为的关键是Handler的removeMessages方法(这是一个方法,是否正确?)。另外,我只是简单地使用被调用的UI更新方法generateRandomColor()向处理程序发送延迟的消息,然后再次调用generateRandomColor()方法,从而导致循环,而不是让Runnable发布UI更新。我认为这可能还不是最好的方式,但它简洁而且有效。

下面的代码完全符合我的要求。我希望这可以帮助别人寻找与处理类似问题......

package com.example.testproject04; 

/* import necessary libraries for 
* our objects classes and widgets 
* that we use here 
*/ 
import android.os.Bundle; 
import android.app.Activity; 
import android.graphics.Color; 
import android.view.View; 
import android.os.Handler; 
import android.widget.TextView; 
import android.os.Message; 

/* declare the main class/activity of this program */ 
public class MainActivity extends Activity { 

/* initialize a boolean variable (true or false only) to 
* check whether the screen is flashing new colors or not */ 
boolean colorIsFlashing = false; 

/* update interval in milliseconds */ 
public int updateDelay = 800; 

/* 'message' to change color (used by handler) */ 
int CHANGE_COLOR_MSG = 0x0; 

/* this creates the UI and screen view, 
* and sets up some other aspects of the program */ 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    /* set the current view in the 
    * user interface as our xml file: 
    */ 
    setContentView(R.layout.activity_main); 

    /* set the background color, 
    * and the initial overlay tint: 
    */ 
    ((View)findViewById(R.id.background_view)).setBackgroundColor(0xFF000000); 
    ((View)findViewById(R.id.overlay_view)).setBackgroundColor(0x00000000); 

    /* create the overlayView variable that 
    * represents our overlay for tinting 
    */ 
    View overlayView = findViewById(R.id.overlay_view); 

    /* implement a method that will listen for a short press, 
    * when short press occurs, if the screen is not currently 
    * flashing, it will start flashing periodically 
    */ 
    overlayView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (!colorIsFlashing){ 
       colorIsFlashing = true; 
       mHandler.sendEmptyMessageDelayed(CHANGE_COLOR_MSG, updateDelay); 
      } 
     } 
    }); 

    /* implement a listener for long presses on the screen, 
    * when a long press occurs, 
    * if the screen is flashing, it will stop 
    */ 
    overlayView.setOnLongClickListener(new View.OnLongClickListener() { 
     @Override 
     public boolean onLongClick(View v) { 
      if (colorIsFlashing) { 
       colorIsFlashing = false; 
       mHandler.removeMessages(CHANGE_COLOR_MSG); 
      } 
      return true; 
     } 
    }); 

} 

/* initialize a handler that we will use 
* to change the color of the screen 
*/ 
private final Handler mHandler = new Handler() { 
    @Override 
    public void handleMessage(Message m) { 
     if (m.what == CHANGE_COLOR_MSG) { 
      generateRandomColor(); 
     } 
    } 
}; 

/* this function generates a random color 
* and sets it to the screen 
*/ 
public void generateRandomColor(){ 
    if (!colorIsFlashing) return; 

    /* generate random color components: */ 
    int randa = (int) Math.round((int) 0xff * (float) Math.random()); 
    int randr = (int) Math.round((int) 0xff * (float) Math.random()); 
    int randg = (int) Math.round((int) 0xff * (float) Math.random()); 
    int randb = (int) Math.round((int) 0xff * (float) Math.random()); 
    int randColor = Color.argb(randa, randr, randg, randb); 

    /* convert color integer to string: */ 
    String strColor = String.format("#%08X", randColor); 

    /* set overlay to our generated random color 
    * and update textview to display color in hex code 
    */ 
    ((View)findViewById(R.id.overlay_view)).setBackgroundColor(randColor); 
    ((TextView)findViewById(R.id.textView2)).setText(strColor); 

    mHandler.sendEmptyMessageDelayed(CHANGE_COLOR_MSG, updateDelay); 
} 

} 

额外的搜索标签/信息:在UI线程内循环的代码,使用处理器在android系统活动停止循环,从处理程序中删除邮件,发送延时给处理者的信息

+0

这一切看起来都很复杂,只是让颜色发生变化。为什么不只是一个在预定时间点火的计时器? – greenapps 2013-03-21 08:43:25

+0

我还没有学会如何制作一个计时器......猜测将不得不考虑它!感谢指针... – jdods 2013-03-21 21:37:34

相关问题