问题
I have a simple Android program that calculates how long it takes the phone to compute a certain mathematical problem. I want the mathematical problem to start when I hit the button, and while it is running I want a spinning progress bar to be displayed, and I want it to disappear after the math problem is done. This is the code I currently have:
public class main extends AppCompatActivity {
private TextView mScore;
private Button mRunButton;
private TextView mScoreText;
private ProgressBar mSpinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mScore = (TextView) findViewById(R.id.score);
mRunButton = (Button) findViewById(R.id.runbutton);
mScoreText = (TextView) findViewById(R.id.scoreText);
mSpinner = (ProgressBar) findViewById(R.id.progress);
mSpinner.setVisibility(View.GONE);
View.OnClickListener listener = new View.OnClickListener(){
@Override
public void onClick(View v) {
mSpinner.setVisibility(View.VISIBLE);
long startTime = System.nanoTime();
long start = System.currentTimeMillis();
long count = 0l;
for(long x=0;x<Integer.MAX_VALUE ;x++){
count+=1;
}
long end = System.currentTimeMillis();
long endTime = System.nanoTime();
long duration = ((endTime - startTime) / 1000000);
mScore.setText(duration + "");
mSpinner.setVisibility(View.GONE);
}
};
mRunButton.setOnClickListener(listener);
}
}
From what I can tell, nothing in the view of the app updates until after the phone is done with the entire onClick method, which is not what I want it to do. I want the progress bar to be displayed ONLY while the program is 'working'. How would I go about doing this?
Thank you
回答1:
As Blackbelt and vilpe89 mentioned, you have to separate the threads. You can do this by having another class that extends ASyncTask which will handle the calculations. The problem with that is that the progress dialog needs to run on the UI thread. You can have an interface that changes the progress dialog in the main class.
Calculator class:
public final class Calculator extends AsyncTask<Void, Void, Void> {
Context context;
calcCallback mCallback;
public Calculator(Context c) {
this.context = c;
this.mCallback = (calcCallback) c;
}
//The main class needs to implement this interface
public interface calcCallback {
Void calcDone();
Void calcStarted();
//Other methods if necessary
}
@Override
protected Boolean doInBackground(Void... params) {
mCallback.calcStarted();
//Your calculations here
mCallback.calcDone();
return null;
}
}
MainActivity
public class MainActivity extends Activity implements Calculator.calcCallback, {
private TextView mScore;
private Button mRunButton;
private TextView mScoreText;
private ProgressBar mSpinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mScore = (TextView) findViewById(R.id.score);
mRunButton = (Button) findViewById(R.id.runbutton);
mScoreText = (TextView) findViewById(R.id.scoreText);
mSpinner = (ProgressBar) findViewById(R.id.progress);
mSpinner.setVisibility(View.GONE);
View.OnClickListener listener = new View.OnClickListener(){
@Override
public void onClick(View v) {
Calculator calculator = new Calculator(MainActivity.this);
calculator.execute();
}
};
mRunButton.setOnClickListener(listener);
}
@Override
public Void calcStarted() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mSpinner.setVisibility(View.VISIBLE);
}
});
}
return null;
}
@Override
public Void calcDone() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mSpinner.setVisibility(View.GONE);
}
});
}
return null;
}
}
You can also set up your calcDone() as calcDone(int duration) so that you can pass the calculated duration back to the main thread.
来源:https://stackoverflow.com/questions/35434147/how-to-get-progressbar-to-show-while-onclicklistener-is-running