2017-02-22 21 views
2

私は、Androidのタイマーベースのクラスを使用せず、ハンドラーとスレッドを使用してUIを更新するAndroid電卓アプリを開発中です。私のロジックに問題があるかどうかは分かりませんが、何らかの理由で時間を設定してスタートボタンを押すと、何も画面に何も表示されません。ターゲットとなるTextViewは必要なだけ減少しません。再び、私は単純なエラー(またはいくつか)を作ったかもしれませんが、あなたのために私のjavaとxmlファイルをすべて投稿しています。すべての応答に事前に感謝します。Android Calculatorのスタートボタンに関する問題

TimerActivity.java

package com.example.stins.intentsandtimer; 


import android.content.DialogInterface; 
import android.support.v7.app.AlertDialog; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.NumberPicker; 
import android.widget.TextView; 
import android.os.Handler; 
import android.os.Message; 
import android.content.Context; 
import android.os.Vibrator; 



public class TimerActivity extends AppCompatActivity implements View.OnClickListener { 
    TextView hours, minutes, seconds; 
    Button numberPicker; 
    private int hrs, min, sec; 
    private boolean start; 

    Handler timerHandler = new Handler(){ 

     /** 
     * Handler for the timer class. It receives the onStart runnable to allow the textviews 
     * to be updated. It checks to see if all textviews are empty and only updates them if 
     * they follow the conditions of a traditional timer. Including moving from 1 hour to 59 minutes. 
     * The handler also sends the Vibrator function once the timer is complete. 
     * @param msg 
     */ 
     @Override 
     public void handleMessage(Message msg){ 
      super.handleMessage(msg); 
      TextView txtSeconds = (TextView) findViewById(R.id.textview_seconds); 
      TextView txtMinutes = (TextView) findViewById(R.id.textview_minutes); 
      TextView txtHours = (TextView) findViewById(R.id.textview_hours); 
      int zeroCheck = Integer.parseInt(txtSeconds.getText().toString()); 

      if (zeroCheck > 0) { 
       sec -= 1; 
       txtSeconds.setText(sec + ""); 
      } else if (min > 0 && sec == 0) { 
       min -= 1; 
       txtMinutes.setText(min + ""); 
       sec = 59; 
       txtSeconds.setText(sec + ""); 
      } else if (hrs > 0 && min == 0 && sec == 0) { 
       hrs -= 1; 
       txtHours.setText(hrs + ""); 
       min = 59; 
       txtMinutes.setText(min + ""); 
       sec = 59; 
       txtSeconds.setText(sec + ""); 
      } else { 
       Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
       v.vibrate(1000); 
      } 
     } 

    }; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_timer); 
     this.setTitle("Timer"); 

     Button btnStart = (Button) findViewById(R.id.start_button); 
     Button btnStop = (Button) findViewById(R.id.stop_button); 
     Button btnReset = (Button) findViewById(R.id.reset_button); 


     hours = (TextView) findViewById(R.id.textview_hours); 
     numberPicker = (Button) findViewById(R.id.btn_set_hours); 
     numberPicker.setOnClickListener(this); 

     minutes = (TextView) findViewById(R.id.textview_minutes); 
     numberPicker = (Button) findViewById(R.id.btn_set_minutes); 
     numberPicker.setOnClickListener(this); 

     seconds = (TextView) findViewById(R.id.textview_seconds); 
     numberPicker = (Button) findViewById(R.id.btn_set_seconds); 
     numberPicker.setOnClickListener(this); 


     btnReset.setOnClickListener(new Button.OnClickListener() { 
             public void onClick(View view) { 
              TextView txtSeconds = (TextView) findViewById(R.id.textview_seconds); 
              TextView txtMinutes = (TextView) findViewById(R.id.textview_minutes); 
              TextView txtHours = (TextView) findViewById(R.id.textview_hours); 
              sec = 0; 
              min = 0; 
              hrs = 0; 
              txtSeconds.setText(sec+""); 
              txtMinutes.setText(min+""); 
              txtHours.setText(hrs+""); 

             } 
            } 
     ); 

     btnStart.setOnClickListener(new Button.OnClickListener() { 
             public void onClick(View view) { 
              start = true; 
              onStart(); 
             } 
            } 
     ); 

     btnStop.setOnClickListener(new Button.OnClickListener() { 
             public void onClick(View view) { 
              start = false; 
             } 
            } 
     ); 


    } 

    protected void onStart(){ 
     super.onStart(); 
     final Thread myThread = new Thread(new Runnable(){ 

      @Override 
      public void run() { 

       while (sec > 0 || min > 0 || hrs > 0) { 
        if(start) { 
         try { 

          Thread.sleep(1000); 
          timerHandler.sendMessage(timerHandler.obtainMessage()); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } 
        } 
        else{ 

        } 
       } 

      } 

     }); 
     myThread.start(); 
    } 




    public void onClick (View v){ 
     switch (v.getId()) { 

      case R.id.btn_set_hours: 
       hourPickerDialog(); 
       break; 

      case R.id.btn_set_minutes: 
       minutePickerDialog(); 
       break; 

      case R.id.btn_set_seconds: 
       secondPickerDialog(); 
       break; 

      default: 
       break; 
     } 


    } 



    private void hourPickerDialog(){ 
     NumberPicker myNumberPicker = new NumberPicker(this); 
     myNumberPicker.setMaxValue(99); 
     myNumberPicker.setMinValue(0); 
     NumberPicker.OnValueChangeListener myValChangedListener = new NumberPicker.OnValueChangeListener() { 
      @Override 
      public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 
       hours.setText(""+newVal); 
      } 
     }; 
     myNumberPicker.setOnValueChangedListener(myValChangedListener); 
     AlertDialog.Builder builder = new AlertDialog.Builder(this).setView(myNumberPicker); 
     builder.setTitle("Set Hours"); 
     builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 

      } 
     }); 
     builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 

      } 
     }); 
     builder.show(); 


    } 

    private void minutePickerDialog(){ 
     NumberPicker myNumberPicker = new NumberPicker(this); 
     myNumberPicker.setMaxValue(59); 
     myNumberPicker.setMinValue(0); 
     NumberPicker.OnValueChangeListener myValChangedListener = new NumberPicker.OnValueChangeListener() { 
      @Override 
      public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 
       minutes.setText(""+newVal); 
      } 
     }; 
     myNumberPicker.setOnValueChangedListener(myValChangedListener); 
     AlertDialog.Builder builder = new AlertDialog.Builder(this).setView(myNumberPicker); 
     builder.setTitle("Set Minutes"); 
     builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 

      } 
     }); 
     builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 

      } 
     }); 
     builder.show(); 


    } 

    private void secondPickerDialog(){ 
     NumberPicker myNumberPicker = new NumberPicker(this); 
     myNumberPicker.setMaxValue(59); 
     myNumberPicker.setMinValue(0); 
     NumberPicker.OnValueChangeListener myValChangedListener = new NumberPicker.OnValueChangeListener() { 
      @Override 
      public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 
       seconds.setText(""+newVal); 
      } 
     }; 
     myNumberPicker.setOnValueChangedListener(myValChangedListener); 
     AlertDialog.Builder builder = new AlertDialog.Builder(this).setView(myNumberPicker); 
     builder.setTitle("Set Seconds"); 
     builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 

      } 
     }); 
     builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 

      } 
     }); 
     builder.show(); 


    } 


} 

activity_timer.xmlあなたのコードで起こっているいくつかのものがあります

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_margin="16dp" 
       android:gravity="center_horizontal" 
       android:orientation="vertical"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_weight="2" 
     android:orientation="horizontal" 
     android:gravity="center"> 

     <TextView 
      android:id="@+id/textview_hours" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="16dp" 
      android:text="00" 
      android:textSize="70sp" /> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="16dp" 
      android:text=":" 
      android:textSize="70sp"/> 

     <TextView 
      android:id="@+id/textview_minutes" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="16dp" 
      android:text="00" 
      android:textSize="70sp" /> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="16dp" 
      android:text=":" 
      android:textSize="70sp"/> 

     <TextView 
      android:id="@+id/textview_seconds" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="16dp" 
      android:text="00" 
      android:textSize="70sp" /> 


    </LinearLayout> 


    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:gravity="center"> 

     <Button 
      android:id="@+id/btn_set_hours" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Hours"/> 

     <Button 
      android:id="@+id/btn_set_minutes" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Minutes"/> 

     <Button 
      android:id="@+id/btn_set_seconds" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Seconds"/> 



    </LinearLayout> 

    <Button 
     android:id="@+id/start_button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="16dp" 
     android:layout_marginTop="16dp" 
     android:background="?selectableItemBackgroundBorderless" 
     android:text="@string/timer_start" 
     style="@style/MyButton" 
     /> 

    <Button 
     android:id="@+id/stop_button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="16dp" 
     android:layout_marginTop="16dp" 
     android:background="?selectableItemBackgroundBorderless" 
     android:text="@string/timer_stop" 
     style="@style/MyButton"/> 

    <Button 
     android:id="@+id/reset_button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="16dp" 
     android:background="?selectableItemBackgroundBorderless" 
     android:text="@string/timer_reset" 
     style="@style/MyButton"/> 

</LinearLayout> 

答えて

1

。私はそれらのすべてに対処しようとはしませんが、あなたのコードが何をすべきかについてあなたのコードをやるようにするだけです。私は&あなたのコードを試しました&私は実際に表示を変更コピーしました。時間ピッカーダイアログをスキップしました& sec=20を開始するだけです。表示が変化していない場合は、最初は時間ピッカーから表示が設定されていますか?

とにかく、まずはデバッグについてお話しましょう。これを行う1つの方法は、Logステートメントをコードに入れることです。

// put this in the start button click listener 
Log.d(TAG, "Start clicked"); 

// or this in handleMessage 
Log.d(TAG, "handleMessage(), seconds = " + sec); 

は、あなたのプログラムは、それがhasn &何行っているかを知ることができ、これらのログメッセージを持つ:コードに

private final static String TAG = "TimerActivity"; 

次に、ファイルの先頭にこれを置くことによって開始し、このようなものを持っていますいくつかの変数値を表示します。デバッガを使用することもできますが、私はこれからは取り上げません。

あなたのコードのためです。 onStart()はライフサイクルの方法です。あなたはそれを自分で呼ぶべきではありません。メソッド名を変更してください(onStartButton()など)。今のようにスレッドが2回実行され、1秒ごとにカウンタが2回ダウンします。

handleMessage()には、時間を追跡するために使用する変数(hrs、min、sec)がありますが、ディスプレイ上のテキストから読み取った数値はzeroCheckです。もっと良いことは、あなたがすでに保持している変数を使用することです(if(sec > 0) { sec -= 1;...)。私はこれらの条件の残りの部分であなたのロジックを検証しませんでした。ディスプレイが更新されると、私はそれを残すでしょう。

最後にtxtSeconds.setText(sec + "");は、setText()を使用する良い方法ではありません(ログメッセージでは問題ありませんが、他の方法でテキストを使用する方が賢明です)。テキストを表示するには1つ以上の良い方法がありますが、この場合は特殊な書式設定が必要です。つまり、0:9:7ではなく、数字「00:09:07」の先頭に0が表示されます。あなたは

txtSeconds.setText(String.format("%02d", sec)); 

でこの方法では、常に他の有用なフォーマッタは、32ビットの16進数または2つの場所に表示を制限し、「%の.2f」のための「%08X」、0から59まで、2桁表示を与えることを得ることができますドルとセントを表示するような小数点以下を過ぎてください。

これらのどれもあなたの投稿の問題を解決するものではありませんが、最終的なコードを必要なものに近づけるでしょう。私が言ったように、あなたのコードは私のために表示されるように表示を更新します(時間ピッカーを使用しません)。secを固定数に設定してから、「開始」ボタンを押して何が起こるかを見ることができます。時間ピッカーに問題がある場合は、ログメッセージを使用して、&のバグを修正することができます。

EDIT:

だから何始まらないあなたのタイマーで起こっていることは、あなたがあなたの番号ピッカーに表示を変更しながら、あなたは基礎となる変数(secなど)を設定していない、ということであるにいくつかの変数を定義します。あなたのpositiveButton onClick()で今

temp_sec = newVal; 
onValueChange()でこれを設定した後(など temp_sec)一時ストレージとして使用

、あなたは

を持っています
sec = temp_sec; 
+0

うわー!!本当にありがとう!私はまだログメッセージの使用に慣れています。ヒントや他の人にもとても感謝します。これらを適用して問題の根本に到達するために今すぐに戻りましょう。 –

+0

もう1つ、数字ピッカーで値が設定されていないときにディスプレイを更新したと言われました、そうですか? –

+0

これは正しいです。私は怠惰であり、数字ピッカーを扱いたくなかったので、私はこれを 'private int hrs = 0、min = 0、sec = 20;' – Gary99

関連する問題