My progress bar can only use one time,when i click it second time,it likes a loop,never end,what is the problem?
class ProgressThread extends Thread {
final static int DONE = 0;
final static int RUNNING = 1;
int maxBarValue=100;
int delay=40;
Handler mHandler;
int mState;
int total;
// Constructor with an argument that specifies Handler on main thread
// to which messages will be sent by this thread.
ProgressThread(Handler h) {
mHandler = h;
}
#Override
public void run() {
mState = RUNNING;
total = maxBarValue;
while (mState == RUNNING) {
// The method Thread.sleep throws an InterruptedException if Thread.interrupt()
// were to be issued while thread is sleeping; the exception must be caught.
try {
// Control speed of update (but precision of delay not guaranteed)
Thread.sleep(delay);
} catch (InterruptedException e) {
Log.e("ERROR", "Thread was Interrupted");
}
// Send message (with current value of total as data) to Handler on UI thread
// so that it can update the progress bar.
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
total--; // Count down
}
total=maxBarValue;
}
public class ProgressBarActivity extends Activity {
ProgressThread progThread;
ProgressDialog progDialog;
Button button1, button2;
int typeBar; // Determines type progress bar: 0 = spinner, 1 = horizontal
int delay = 40; // Milliseconds of delay in the update loop
int maxBarValue = 200; // Maximum value of horizontal progress bar
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Process button to start spinner progress dialog with anonymous inner class
button1 = (Button) findViewById(R.id.Button01);
button1.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
typeBar = 0;
showDialog(typeBar);
}
});
// Process button to start horizontal progress bar dialog with anonymous inner class
button2 = (Button) findViewById(R.id.Button02);
button2.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
typeBar = 1;
showDialog(typeBar);
}
});
}
// Method to create a progress bar dialog of either spinner or horizontal type
#Override
protected Dialog onCreateDialog(int id) {
switch(id) {
case 0: // Spinner
progDialog = new ProgressDialog(this);
progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progDialog.setMessage("Loading...");
progThread = new ProgressThread(handler);
progThread.start();
return progDialog;
case 1: // Horizontal
progDialog = new ProgressDialog(this);
progDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progDialog.setMax(maxBarValue);
progDialog.setMessage("Dollars in checking account:");
progThread = new ProgressThread(handler);
progThread.start();
return progDialog;
default:
return null;
}
}
// Handler on the main (UI) thread that will receive messages from the
// second thread and update the progress.
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
// Get the current value of the variable total from the message data
// and update the progress bar.
int total = msg.getData().getInt("total");
progDialog.setProgress(total);
if (total <= 0){
dismissDialog(typeBar);
progThread.setState(ProgressThread.DONE);
}
}
};
}
// Set current state of thread (use state=ProgressThread.DONE to stop thread)
public void setState(int state) {
state=ProgressThread.DONE;
mState = state;
}
}
ProgressBar.postInvalidate() you can try this.
Related
I don't know how I can show an AlertDialog, when the progress bar goes
for example to 22%.
I would like when the progress bar reaches 22%, to stop and show an AlertDialog window, showing some text and the default buttons, for example OK and Cancel. When you press OK the progress bar resumes and continues with the progress load. And so complete it until you reach 100% of the progress bar.
The problem is that I don't know how to stop the progress bar, for example at 22% and show the AlertDialog. So this is my doubt. How would be the right way to do it.
This is what I have done so far, and thank you in advance colleagues;)
MainActivity:
public class MainActivity extends AppCompatActivity {
private ProgressBar progressBar4;
private int progressStatus4 = 0;
private Handler handler = new Handler();
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
carga();
}
});
}
private void carga(){
final Dialog dialogCorrect = new Dialog(MainActivity.this);
dialogCorrect.requestWindowFeature(Window.FEATURE_NO_TITLE);
if (dialogCorrect.getWindow() != null) {
ColorDrawable colorDrawable = new ColorDrawable(Color.TRANSPARENT);
dialogCorrect.getWindow().setBackgroundDrawable(colorDrawable);
}
dialogCorrect.setContentView(R.layout.dialog);
dialogCorrect.setCancelable(false);
dialogCorrect.show();
final TextView tv44 = dialogCorrect.findViewById(R.id.tv44);
progressBar4 = dialogCorrect.findViewById(R.id.pb44);
final TextView txt = dialogCorrect.findViewById(R.id.txt);
txt.setText("Connect");
if (progressStatus4 == 100) {
progressStatus4 = 0; //Reset Values
}
new Thread(new Runnable() {
#Override
public void run() {
while (progressStatus4 < 100) {
progressStatus4 += 1;
try {
Thread.sleep(200);
runOnUiThread(new Runnable() {
#Override
public void run() {
if(progressBar4.getProgress() >= 20 && progressBar4.getProgress() <= 41){
txt.setText("Update");
}else if(progressBar4.getProgress() >= 41 && progressBar4.getProgress() <= 71){
txt.setText("GET");
}else if(progressBar4.getProgress() >= 71 && progressBar4.getProgress() <= 99){
txt.setText("WHAIT");
}else if(progressBar4.getProgress() >= 99 && progressBar4.getProgress() <= 100){
dialogCorrect.dismiss(); //Close PopUp
}
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update the progress bar
handler.post(new Runnable() {
#Override
public void run() {
progressBar4.setProgress(progressStatus4);
progressBar4.setSecondaryProgress(progressStatus4 + 15);
// Show the progress on TextView
tv44.setText(progressStatus4 + "%");
}
});
}
}
}).start(); // Start the operation
}
}
I'm working on a tank-game and I have a TextView which represents the shot. Now I want to display the TextView at the specific point and remove it after a second that it looks like the shot goes further step by step. But when I add a countdown or a Thread.sleep the program stops for a second but the TextView doesn't disappear. i want to move the TextView over the screen and after every iteration of my for loop i want to wait a second and then rearrange it again?
Here is the code :
public void shot(float power, float winkel, Button button) {
if(winkel>90) {
winkel = winkel - 10;
}else if(winkel<90){
winkel = winkel +10;
}
for (double i = 0; i<100;i = i+ 1) {
final TextView textView = new TextView(context);
textView.setText(".");
double x = tanks.get(currentTank).getxPos()+(i*power*Math.cos(winkel *(Math.PI/180)));
double y = tanks.get(currentTank).getyPos()+(-1*(i*power*Math.sin(winkel *(Math.PI/180))));
double gravity = (-1*((9.81/2)*Math.pow(i,2)));
y = (y-gravity);
textView.setX((float) x);
textView.setY((float) y);
layout.addView(textView);
for (int j = 0;j<tanks.size();j++){
if(textView.getX()>tanks.get(j).getxPos()&&textView.getX()<tanks.get(j).getxPos()+100){
if(textView.getY()>tanks.get(j).getyPos()&&textView.getY()<tanks.get(j).getyPos()+100){
float k = tanks.get(j).getxPos()-textView.getX();
if(k<0){
k = k*-1;
}
makeDamage(k,tanks.get(j));
}
}
}
new CountDownTimer(2000,1000){
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
layout.removeView(textView);
}
}.start();
}
newTurn();
}
I want to pause the program after adding the TextView for one second and the remove it. The program stops but the TextView doesn't disappear till the for-loop finished. Then all TextViews disappear.
Problem solved:
i've added all positions in a array and then this
public void drawShot(final Button firework, final ArrayList<TextView> toDraw){
final int[] i = {0};
final Handler mHandler = new Handler();
firework.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onClick(View v) {
firework(firework,toDraw.get(i[0]).getX(),toDraw.get(i[0]).getY());
}
});
Runnable runnable = new Runnable() {
#Override
public void run() {
layout.addView(toDraw.get(i[0]));
if(!check(toDraw.get(i[0]))) {
mHandler.postDelayed(this, (long) 1);
}
i[0]++;
}
};
// start it with:
mHandler.post(runnable);
}
probably need to run the remove command on main thread
Handler mainHandler = new Handler(context.getMainLooper());
Runnable myRunnable = new Runnable() {
#Override
public void run() {
layout.removeView(textView);
}
};
mainHandler.post(myRunnable);
I am trying to display values inside ArrayList on single line textView one by one after some interval. How to achieve this without blocking the main thread?
I have written code which is able to do this with Thread.sleep but, after a few seconds of running, activity is getting crashed. I have used For Loop & Thread.sleep to iterate every ArrayList value after some interval.
When activity crashes, I am getting IndexOutOfBondException after a few seconds of running.
public void errorRepeater() {
Thread t = new Thread() {
#Override
public void run() {
// !isInterrupted()
while (!isInterrupted()) {
for (xz = 0; xz < errorList.size(); xz++) {
try {
Thread.sleep(2000); //1000ms = 1 sec
runOnUiThread(new Runnable() {
#Override
public void run() {
String sErrorList = errorList.get(xz);
String sErrorListOkBox = errorListOkBox.get(xz);
Log.i("MQTT sErrorList", sErrorList);
TextView tvC1HPLP = findViewById(R.id.errormsg);
tvC1HPLP.setText(sErrorList);
TextView tvok = findViewById(R.id.ok);
tvok.setText(sErrorListOkBox);
rl.setBackgroundResource(R.drawable.errorred);
tvC1HPLP.setTextColor(Color.RED);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
t.start();
}
textView should display values inside ArrayList one by one without crashing activity.
Just for reference, you can try something like this.
// You can define those both textview globally.
TextView tvC1HPLP = findViewById(R.id.errormsg);
TextView tvok = findViewById(R.id.ok);
Handler mHandler = new Handler();
final Runnable runnable = new Runnable() {
int count = 0;
#Override
public void run() {
String sErrorList = errorList.get(count%errorList.size);
String sErrorListOkBox = errorListOkBox.get(count%errorListOkBox.size);
tvC1HPLP.setText(sErrorList);
tvok.setText(sErrorListOkBox);
rl.setBackgroundResource(R.drawable.errorred);
tvC1HPLP.setTextColor(Color.RED);
count++;
mHandler.postDelayed(this, 4000); // four second in ms
}
};
mHandler.postDelayed(runnable, 1000);
I am developing an android app and want to save a rand2(Double type) value using savedInstanceState so that i can use rand2 value whenever app is reopened but while retrieving rand2 value it always comes NULL, Either the value is not saving or value is not retrieving . Why it is happening and what should i do to save rand2 value so that i can reuse it when the app is reopened?
public class MainActivity extends AppCompatActivity {
double rand2;
private boolean started = false;
private Handler handler = new Handler();
public Runnable runnable = new Runnable() {
#Override
public void run() {
double rand1 = Math.random() * 5;
rand2 = rand2 + rand1 * 0.04;
DecimalFormat df = new DecimalFormat("0.00");
String message1 = "" + df.format(rand1);
DecimalFormat dff = new DecimalFormat("000000.00");
String message2 = "" + dff.format(rand2);
displayRate(message1);
displaySatoshi(message2);
if (started) {
start(started);
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// recovering the instance state
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
if (savedInstanceState != null) {
rand2 = savedInstanceState.getDouble("abc");
} else {
rand2 = 0.00;
}
setContentView(R.layout.activity_main);
// Find the View that shows the numbers category
TextView numbers = (TextView) findViewById(withdraw);
// Set a click listener on that View
numbers.setOnClickListener(new View.OnClickListener() {
// The code in this method will be executed when the numbers View is clicked on.
#Override
public void onClick(View view) {
Intent numbersIntent = new Intent(MainActivity.this, Withdraw.class);
startActivity(numbersIntent);
}
});
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putDouble("abc", rand2);
// call superclass to save any view hierarchy
super.onSaveInstanceState(savedInstanceState);
}
public void Start(View v) {
ToggleButton starStopTogglrButton = (ToggleButton) findViewById(R.id.start_stop);
boolean hasStartStop = starStopTogglrButton.isChecked();
if (hasStartStop) {
start(hasStartStop);
} else {
stop(hasStartStop);
}
}
public void stop(Boolean hasStartStop) {
//Checking start or stop
started = hasStartStop;
handler.removeCallbacks(runnable);
}
public void start(Boolean hasStartStop) {
started = hasStartStop;
handler.postDelayed(runnable, 1000);
}
private void displayRate(String message1) {
TextView orderSummaryTextView = (TextView) findViewById(R.id.rate);
orderSummaryTextView.setText(message1);
}
private void displaySatoshi(String message2) {
TextView orderSummaryView = (TextView) findViewById(R.id.satoshis);
orderSummaryView.setText(message2);
}
}
onSaveInstanceState is called when the app is closed, but onCreate is only called when the app is booted after it's been finished. Remember the acitvity lifecycle:
So since onSaveInstanceState is called at closing and onCreate only is called when the activity is (re)created, it is null because it isn't added at that time.
You're looking for onRestoreInstanceState. Override that method and grab the variable and assign it from there.
Remember that using the savedInstanceState does not save the data if the activity is completely destroyed. For persistent data storage, use sharedprefs, files or SQL
My Code should frequently update a number (not only show the result, delay of 100) from a loop in an EditText after you click on a button.
Old Code:
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
while (repeat > 0) {
num1 = new Random().nextInt(6)+1;
edit1.setText(String.valueOf(num1));
repeat = repeat - 1;
rep.setText(String.valueOf(repeat));
}
}
});
Now I have this:
final Handler randomHandler = new Handler();
final Runnable randomUpdate = new Runnable() {
#Override
public void run() {
num1 = new Random().nextInt(6) + 1;
edit1.setText(String.valueOf(num1));
repeat--;
rep.setText(String.valueOf(repeat));
randomHandler.postDelayed(this, 1000);
}
};
btnpl5.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
repeat = repeat + 5;
rep.setText(String.valueOf(repeat));
button2.setClickable(true);
button2.setEnabled(true);
}
});
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
randomUpdate.run();
button2.setClickable(false);
button2.setEnabled(false);
}
Problem: it won't stop after repeat is 0 (it goes on -1 -2 -3 -4 ..)?
You must always be on the UI thread when calling any method on any
view. If you are doing work on other threads and want to update the
state of a view from that thread, you should use a Handler.
Try this,
handler.postDelayed(new Runnable(){
#Override
public void run() {
num1 = new Random().nextInt(6)+1;
// get previous value and append new generated
edit1.setText(edit1.getText().toString()+String.valueOf(num1));
}
}, (1000)); // run this method in every 1000 milliseconds
This may help you.
You can use an AsyncTask to delay in the background, and publishProgress() to update the UI.
class TextDisplayTask extends AsyncTask<Integer, Integer, Void> {
private int DELAY_MILLIS = 100; // ... set your delay here
#Override
protected Void doInBackground(Integer... params) {
for (int i = 0; i < params[0]; i++) {
int num = new Random().nextInt(6) + 1;
publishProgress(num);
Thread.sleep(DELAY_MILLIS);
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
edit1.setText(String.valueOf(values[0]));
}
}
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
new TextDisplayTask().execute(20); // show a number 20 times
}
});