2017-01-22 14 views
0

ちょっと私はプログラミングで、特にjavaとxmlで新しいです。プログレスバーにタスクが残す時間を表示するゲームを作りたいのですが、Android Studioはi ++とmProgressBar.setProgress(i)を使うために最終変数を宣言する必要があると言っています。内部のクラスのためです。しかし、私が知る限り、最終的な変数はその価値を変えることはできません。コードを再び動作させるために私は何を変えるべきですか?Android Studioは、最終的な変数を宣言する必要があると言っています。

@Override 
public void onResume() { 
    super.onResume(); 

    View decorView = getWindow().getDecorView(); 
    decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
      | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
      | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
      | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 
      | View.SYSTEM_UI_FLAG_FULLSCREEN 
      | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 
    final ImageView ball = (ImageView) findViewById(R.id.ball); 
    ball.setOnTouchListener(new View.OnTouchListener() 
    { 
     PointF DownPT = new PointF(); // Record Finger Position When Pressed Down 
     PointF StartPT = new PointF(); // Record Start Position of 'ball' 

     @Override 
     public boolean onTouch(View v, MotionEvent event) 
     { 
      int eid = event.getAction(); 
      switch (eid) 
      { 
       case MotionEvent.ACTION_MOVE : 
        PointF mv = new PointF(event.getX() - DownPT.x, event.getY() - DownPT.y); 
        ball.setX((int)(StartPT.x+mv.x)); 
        ball.setY((int)(StartPT.y+mv.y)); 
        StartPT = new PointF(ball.getX(), ball.getY()); 
        break; 
       case MotionEvent.ACTION_DOWN : 
        DownPT.x = event.getX(); 
        DownPT.y = event.getY(); 
        StartPT = new PointF(ball.getX(), ball.getY()); 
        break; 
       case MotionEvent.ACTION_UP : 
        // Nothing have to do 
        break; 
       default : 
        break; 
      } 
      return true; 
     } 
    }); 
    ProgressBar mProgressBar; 
    CountDownTimer mCountDownTimer; 
    int i=0; 

    mProgressBar=(ProgressBar)findViewById(R.id.progressBartime); 
    mProgressBar.setProgress(i); 
    mCountDownTimer=new CountDownTimer(3000,1000) { 

     @Override 
     public void onTick(long millisUntilFinished) { 
      Log.v("Log_tag", "Tick of Progress"+ i+ millisUntilFinished); //i needs to be declared as final 
      i++; //i needs to be declared as final 
      mProgressBar.setProgress(i); //mProgressBar needs to be declared as final 

     } 


     @Override 
     public void onFinish() { 
      //Do what you want 
      i++; //i needs to be declared as final 
      mProgressBar.setProgress(i); //mProgressBar needs to be declared as final 
     } 
    }; 
    mCountDownTimer.start(); 
} 

}

答えて

2

あなたはそれが自分自身の外で変更可能な変数にアクセスすることができない内部クラスを使用しているため。あなたが実際に内部でi変数を設定することができ、あなたの特定のケースについて

// Outer class (where I is currently defined) 
final AtomicInteger i = new AtomicInteger(); 

//Inner class (within the onTick function) 
i.incrementAndGet(); 

次に取得するための値を使用i.get()

:それが最終的に設定することができるようAtomicIntegerを使用してみてください、あなたはこのような何かをするだろう内部クラス。

CountDownTimer mCountDownTimer; 

final ProgressBar mProgressBar=(ProgressBar)findViewById(R.id.progressBartime); 
mProgressBar.setProgress(i); 
mCountDownTimer=new CountDownTimer(3000,1000) { 
    int i = 0; 

    @Override 
    public void onTick(long millisUntilFinished) { 
     Log.v("Log_tag", "Tick of Progress"+ i+ millisUntilFinished); //i needs to be declared as final 
     i++; 
     mProgressBar.setProgress(i); //mProgressBar needs to be declared as final 

    } 


    @Override 
    public void onFinish() { 
     //Do what you want 
     i++; 
     mProgressBar.setProgress(i); //mProgressBar needs to be declared as final 
    } 
}; 

mProgressBarは変更可能である必要はないため、問題なくそのまま最終変数として設定できます。

編集:更新最終的な

を使用することができる理由mProgressBarが最終的に設定することができる理由は、オブジェクトの参照が変更することはできないが、上がらない任意の値を最終的な変数を用いて、対象であるということですオブジェクト内の最後の設定が変更される可能性があるので、setProgressが機能します。ただし、プリミティブ変数の場合は一度しか設定できませんが、これはパフォーマンス向上のためのものです。

Thisには、ローカルクラスから最終的ではないローカル変数を変更できない理由についての説明があります。

ローカルクラスはインスタンス変数を参照できます。最終的ではないローカル変数を参照できないのは、メソッドが返ってからローカルクラスインスタンスがメモリ内に残るためです。メソッドが返ってくると、ローカル変数は範囲外になります。そのため、それらのコピーが必要です。変数がfinalでない場合、メソッド内の変数のコピーが変更される可能性がありますが、ローカルクラスのコピーは変更されないため、同期が外れてしまいます。

+1

あなたはprogressBarではなくiに対処しました –

+0

はい、あなたは正しいです!回答 – Ryan

+0

を修正しました。内部クラスは、ローカル変数***にアクセスできませんでした。これは、囲むクラスのインスタンス変数と静的変数にアクセスできます。 –

関連する問題