2013-08-06 147 views
2

我想提出一個簡單的圖像瀏覽器(Android版)後加速。我還需要實施幻燈片演示。我完成了,除了我有一個惱人的錯誤。當我運行幻燈片時(按下按鈕)它就可以工作。但是當我取消幻燈片並再次運行(同一個按鈕)時,幻燈片顯示速度會加快。定時器每次運行

編輯:添加固定代碼,看看代碼的幻燈片部分的意見,看看有什麼需要固定

package csc2002.imageviewer; 
    //imports 

public class MainActivity extends Activity implements OnClickListener { 
    static Timer timer = new Timer(); 
    int arrayIndex = 0; 
    int checker=0; 
    int start,delay = 1800; 
    boolean toggle; 


    private static Integer[] imageIds = { //Hard coded array 
     R.raw.bulbasaur,R.raw.switch_brain,R.raw.quote,R.raw.victory,R.raw.penguins,R.raw.jellyfish,R.raw.koala}; 

    private static final int IMAGE_COUNT = imageIds.length; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { // Called when the app is opened 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Button back = (Button)findViewById(R.id.backButton); 
     back.setOnClickListener(this);  
     Button next = (Button)findViewById(R.id.nextButton); 
     next.setOnClickListener(this); 
     Button slideshow = (Button)findViewById(R.id.slideButton); 
     slideshow.setOnClickListener(this); 
     displayImage(); 
    } 

    // responsible for displaying the image and the name of the image. 
    private void displayImage() { // Displays the image on the screen according the the current array index 

     ImageView imgView = (ImageView) findViewById(R.id.myimage);    
     imgView.setImageResource(imageIds[arrayIndex]); 
     TextView text = (TextView)findViewById(R.id.name); 
     text.setText(imageIds[arrayIndex]); 
    } 

    // This method allows the cycling of images 

    public void onClick(View v) { 
     if(v.getId()==(R.id.backButton)){ //Back button 
      arrayIndex--; 

      if(arrayIndex==-1){ 
       arrayIndex = IMAGE_COUNT-1; 
      } 
      displayImage(); 
     } 

     else if (v.getId()==(R.id.nextButton)){ //NextButton 
      arrayIndex++; 
     } 
     if(arrayIndex==IMAGE_COUNT){ 
      arrayIndex = 0; 
     } 
     displayImage(); 

     if (v.getId()==R.id.slideButton){ //Slideshow button 
      Button slideshow = (Button)findViewById(R.id.slideButton); 
      toggle^= true; 
      if(toggle==true){ 
       slideshow.setText("Stop Slideshow"); 
      } 
      else{slideshow.setText("Start Slideshow");} 
     } 
     // Slideshow functionality 

     if(toggle==true){ 
      //timer=new Timer(); //this was added in the correct solution(This was the main problem). 
      timer.scheduleAtFixedRate(new TimerTask() { 

       @Override 
       public void run() { 
        if(toggle==true){ 
         MainActivity.this.runOnUiThread(new Runnable() { 
          public void run() { 
           arrayIndex++; 
           if(arrayIndex==IMAGE_COUNT){ 
            arrayIndex=0; 
           } 

           displayImage(); 
          } 
         }); 
        } 
       } 

      },start,delay); 

     } 
     else if(toggle==false){ 
      //timer.cancel(); This was added to correct the solution 
     } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { //This saves data when the app is rotated 
     outState.putInt("KEY", arrayIndex); 
     super.onSaveInstanceState(outState); 

    } 
    @Override 
    protected void onRestoreInstanceState(Bundle save){ //Restores Data after interruption 
     super.onRestoreInstanceState(save); 
     arrayIndex = save.getInt("KEY"); 
     displayImage(); 
    } 


} 
+0

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html#schedule%28java.util.TimerTask,%20long,%20long%29 中,TimerTask類不提供實時保證:它使用Object.wait(long)方法調度任務。 – dseibert

+3

您是否將每個按鈕切換的計時器事件添加到您的計劃程序?如果是這樣,你有多個計時器事件同時發生,這看起來像你的速度。 – Tansir1

+2

+1不用於標記爲Android。 – supersam654

回答

1

我有類似的問題,我在一個項目兩三年前那樣。當然,我使用的是Timer對象,但這裏有幾件事情我做來解決這個問題:

  • 確保您明確停止計時器。
  • 重新初始化定時器,覆蓋原來的定時器。

如果這些建議不工作,嘗試張貼更多的代碼。

編輯

public void onClick(View v) { 
    //... 
    if (v.getId()==R.id.slideButton){ //Slideshow button 
     toggle^= true; 
     if(toggle==true){ 
      timer = new Timer(); 
      timer.schedule(/*Whatever TimerTask you had here before*/);   
     } 
     else{ 
      timer.cancel(); 
     } 
    }//end if(slide button) 
}//end onClick() 

通過做這種方式,計時器纔開始或點擊切換按鈕時結束。定時器在點擊按鈕時創建,並在再次點擊時取消。不應該有兩個主動定時器在同一時間。我不太確定這將適應現在的代碼,但它應該與您第一次使用的代碼一起工作。

+0

正如Tasnsir1所說,每當我點擊幻燈片顯示按鈕時,切換從true變爲false,因此可能觸發多個計時器事件。我該如何改變這一點? timer.cancel()不起作用。 – Seeker

+0

我們的項目之間的不同之處在於我使用了'javax.swing.Timer',所以我們的解決方案可能會略有不同。您的計時器的[documentation](http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html#cancel%28%29)表明,一旦'timer.cancel()'被調用時,定時器將不再採用任何'TimerTask',所以在當前一個停止之後不應該有任何新的定時器事件。我認爲我們需要看到您發佈的代碼的更廣泛的背景。特別是,當使用發佈的代碼時,如何更改'toggle'的值,以及'timer.cancel()'的位置? – Stspurg

+0

將我的整個代碼添加到OP – Seeker