I'm trying to make a repeating loop to display increasing numbers in a single textview.
The general idea is this
....
int rep = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.Layout);
do { meth(); } while (rep < 11);
}
private void meth() {
final TextView textv = (TextView) findViewById( R.id.tex );
String srep = Integer.toString(rep);
textv.setText(srep);
if(rep <11) { rep = rep +1; }
}
....
The idea is to display the numbers 1 to 10 in the textview textv ONE BY ONE on screen. But when I ran it, it just shows 10. I'm tried to put in a CountDownTimer inside meth() and also inside the do {} loop but it just crashes the program.
Would appreciate if anyone can point me the right way of doing this.
Try this
private class MethTask extends AsyncTask<String, String, String> {
protected String doInBackground(String... urls) {
do { meth(); SystemClock.sleep(1000);
} while (rep < 11);
return "";
}
}
And call from onCreate() like this:
new MethTask().execute("");
First thing you cannot run this code into oncreate otherwise you won't see anything since onCreate is run before the activity is rendered.
So what you should do is first create a CountownTimer, start it in the onStart method this way:
handler.postDelayed(new Runnable() {
startCountDown();
}, 1000);
This way you will be sure the activity is displayed
UPDATE
If you use CountownTimer there is no need to call sleep or other similar methods
Related
I have got some problems to understand runOnUiThread(). I want to update the TextView continously but nothing happens. The GUI is still blocked. Could somebody help me?
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
runner();
}
public void runner (){
String[] testFiles = GeneralHelper.getPictureFileList();
TextView text = (TextView) findViewById(R.id.textfeld);
for (int i = 0; i < 2; i++)
{
runOnUiThread(new Runnable() {
public void run() {
text.setText("\n" + GeneralHelper.getPictureFileList()[i]);
}
});
...
// image analysis
}}
The loop has only 2 iterations and it is done so fast that you even can't see changes. You only see result GeneralHelper.getPictureFileList()[1]
And you are inside UiThread so you shouldn't use it. Just:
public void runner (){
String[] testFiles = GeneralHelper.getPictureFileList();
TextView text = (TextView) findViewById(R.id.textfeld);
for (int i = 0; i < 2; i++)
{
text.setText("\n" + GeneralHelper.getPictureFileList()[i]);
}
}
Sounds like you need to create your own timer class where you can include runOnUiThread() to update your TextView. That's what I did on a program I wrote where I needed to display the time counting up every second as soon as the user pressed a button.
I'm learning Android and since I'm a beginner I thought it could be appropriate to make some kind of stopwatch as my first app. I also need one since I want to measure my long walks.
I have done the part with the buttons and all that stuff, now I'm not sure how to get this time thing to get hours, minutes and seconds to update the textView?
I also wonder how I should do to get calls to a method, like each, 30 minutes?
Preciate some guidance and hints! Thanks!
Just create a thread for that task the same as we did here:
http://www.itcuties.com/android/how-to-create-android-splash-screen/
Let's modify our code a little bit :)
public class MainActivity extends Activity {
private static String TAG = MainActivity.class.getName();
private static long SLEEP_TIME = 1; // Sleep for some time
private TextView hoursText;
private TextView minutesText;
private TextView secondsText;
// TODO: time attributes
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hoursText = (TextView) findViewById(R.id.hoursView);
minutesText = (TextView) findViewById(R.id.minutesView);
secondsText = (TextView) findViewById(R.id.secondsView);
// TODO: Get start time here
// Start timer and launch main activity
ClockUpdater clockUpdater = new ClockUpdater();
clockUpdater.start();
}
private class ClockUpdater extends Thread {
#Override
/**
* Sleep for some time and than start new activity.
*/
public void run() {
try {
// Sleeping
while (true) {
Thread.sleep(SLEEP_TIME * 1000);
// TODO: Get current time here
// current time - start time ...
// Set new values
hoursText.setText("10"); // don't know if you walk this long
// :)
minutesText.setText("10");
secondsText.setText("10");
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
}
}
I'm very new to Android. I've used Java before but not for around a year and a half. I'm having problems getting the screen to update, or rather the TextView. I have looked around the net for hours for solutions and I sort of know why its not working, but I don't know how to fix it.
public class PreliminaryActivity extends Activity {
//private static final int MENU_QUIT = Menu.FIRST;
int i = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getWindow().setBackgroundDrawableResource(R.drawable.background);
mainComputations();
}
public void mainComputations(){
runOnUiThread(new Runnable(){
//#Override
public void run(){
TextView tv = (TextView) findViewById(R.id.time_display);
tv.setText(new Integer(i).toString());
i++;
}
});
}
I've cut my program down so it should just increment an int value on the screen for testing and it still will not work. Instead it just displays '0'. If I add a for loop before the runOnUiThread() method, it will increment the i value but I have a feeling it is simply increasing the value then displaying it rather than it updating in real time. Any help would be greatly appreciated.
Go for TextSwitcher
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/TextSwitcher1.html
If you want your textview to update with some delay.
use something like this.
final int length = 10;
Thread t = new Thread(new Runnable() {
#Override
public void run() {
for(int i=0 ; i<length; i++) {
runOnUiThread(new Runnable() {
#Override
public void run() {
tv.setText(new Integer(i).toString());
}
}) ;
i++;
Thread.sleep(500);
}
}
});
t.start();
In android, You can not update the UI from another thread. This is the restriction (which I consider a feature to remove unncecessary bugs) in android development. You can use AsyncTask for this...
In use, you can perform long task inside donInBackground() and than UI can be updated using onProgressUpdate()... see the AsyncTask example here
EDIT
see this similar question for more information...
Your problem is because you call the mainComputations() only once. You should take a look at AsyncTask and the Android Developer resource Updating the UI from a Timer
You can not Update Main UI Thread from another thread for that you need to use Handler. Refer this link for more details
http://www.vogella.com/articles/AndroidPerformance/article.html
What I see is that you call mainComputations only one time, so it is 0.
I'm trying to setup a combat system that allows the user to pick between a melee attack and ranged attack (pick one of two radio buttons). Based on variables what actions the buttons can say, "out of range", "attack melee", "attack range", "reload range". onresume radioButtons have the correct text. After firing ranged weapon for the first time (combat starts with ranged weapon already reloaded) The text for rangeRadio changes to "reload range" but wont change back from "reload range" to "attack range" even when the weapon is 'reloaded' and will fire dealing damage when I end the turn (and preform set actions). If the weapon takes 2 turns to reload. I spend 2 turns reloading, click home button then return to activity it will setText correctly and say "range attack", other wise it will stay "reload range".
finds radioButtons, if statements to first check if there is a ranged weapon equip(rangeId == 50 means no weapon) then check to see if weapon is loaded (int rangeReload = 100), then finally check to see if in range to attack/fire.
private void setActions(){
RadioButton meleeRadio = (RadioButton) findViewById(R.id.meleeRadio);
RadioButton rangeRadio = (RadioButton) findViewById(R.id.rangeRadio);
if (meleeRange >= distance){meleeRadio.setText(meleeString);}else{meleeRadio.setText(oorString);}
if (rangeId == 50){rangeRadio.setText(norangeString);}else{if(rangeReload<=99){rangeRadio.setText(reloadString);}else{
if (rangeRange >= distance){rangeRadio.setText(rangeString); Log.e(rangeString, "Range Attack called");}else{rangeRadio.setText(oorString);}}}
}
I call setActions(); in two places. in onresume via preCombat() -> layoutcombat()
#Override
protected void onResume() {
new pullCombatActions().execute();
new prepCombat().execute();
super.onResume();}
private class prepCombat extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
playerBattlePrep();
findNPC();
return null;}
#Override
protected void onPostExecute(String result) {
new layoutCombat().execute();
}
}
private class layoutCombat extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
startCombat();
pullCombatText();
return null;}
#Override
protected void onPostExecute(String result) {
setActions();
popStats();
refreshStats();
combatStartText();}
}
the 2nd place I call setActions(); is in my AsyncTask that I run at the end of a combat turn to refresh the screen and show the user what happened via rolls.
private class replaceScreen extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
pullCombatStory();
return null;
}
#Override
protected void onPostExecute(String result) {
refreshStats();
refreshCombatStory();
highLightPlayerActions();
highLightNpcActions();
setActions();
}
}
I don't understand why it seems to stop half way through my if statement when setting the rangeRadio but onResume lets it complete all the way and display the proper text for rangeRadio.
Just a suggestion, try moving
RadioButton meleeRadio = (RadioButton) findViewById(R.id.meleeRadio);
RadioButton rangeRadio = (RadioButton) findViewById(R.id.rangeRadio);
Outside of your onResume method, and put it on your onCreate (or onActivityCreated if it is a fragment) method and put rangeRadio and meleeRadio as private variables in your activity (or fragment)
Then, since you are using chained AsyncTasks I'm not sure if all of your onPostExecute are running on your UI thread, so I would try to encapsulete all your calls to rangeRadio.setText() on a handler like this:
On your on Activity onCreate:
handler = new Handler();
then when setting your text do :
handler.post(new Runnable() {
public void run() {
rangeRadio.setText("...");
}
});
TY for helping. In my haste to find a good stopping place for the night I forgot to setup AsyncTask for when the character reloads. So setActions() wasn't being called when the player didn't attack because they were out of range or when the player was reloading.
I have an array of drawables, that I would like to change by my own timer to a imageview.
(i tried the other option with xml and setBackgroundResource, but does not work for me as I have hundret of pics and always got memory problem as it looks android assign already the whole memory for all pics at once. (just in this demo i shorted it to 4 images)
Ok, so first i make my array
private static int[] draws = {
R.drawable.frankiearmevor_0001,
R.drawable.frankiearmevor_0002,
R.drawable.frankiearmevor_0003,
R.drawable.frankiearmevor_0002
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imgView = (ImageView) findViewById(R.id.fredi);
// create timer
Timer updateProgressTimer = new Timer();
updateProgressTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
myloop();
}
}, 0, 150);
}
int mycounter;
public void myloop()
{
mycounter++;
if (mycounter > 4) mycounter = 1;
imgView.setImageResource(draws[mycounter-1]);
String hallo; hallo = "now: "+mycounter;
Log.d("1",hallo);
}
when I assign only a fixed image: imgView.setImageResource(draws[2]);
it shows that fine and I see also my thread is logged fine, but when I exchange the
fixed resource draws[2] into a dynamic draws[mycounter-1] .. i just get a black screen, no error, nothing.
what to do, so i will show the images :)
thx
chris
EDIT: 22. August:
I tried now with the comment I got, it compiles fine, but somehow there is an error i guess.. it crash:
imgView = (ImageView) findViewById(R.id.fredi);
Timer updateProgressTimer = new Timer();
updateProgressTimer.scheduleAtFixedRate(new TimerTask()
{
#Override
public void run()
{
//myloop();
imgView.post (new Runnable()
{
public void run()
{
mycounter++;
if (mycounter > 10) mycounter = 1;
imgView.setImageResource(draws[1]);
//imgView.invalidate();
String hallo; hallo = "now: "+mycounter;
Log.d("1",hallo);
}
});
}
}, 0, 150);
The ImageView update should happen on the UI Thread...
Refer this answer. The TimerTask runs on a different thread, so you've to use the imgView.post() to update the UI Component.
Are you sure you need to update the Component every 150ms? That's very expensive.
Good Luck.