I have a handler and a runnable, Handler has a loop that runs from 0 to 5. when i start the runnable in handler it runs and increment value to 0 to 5. But if i double click or click more than 1 time than it takes the value of temp above 5. How can i reset (0) the value of temp on every click of handler.
final Handler deneme = new Handler();
final Runnable post_score = new Runnable(){
public void run(){
Log.i("TAG", Integer.toString(temp));
temp++;
}
};
Button tv = (Button )findViewById(R.id.button1);
tv.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
temp = 0;
for(int i=0; i < 5;i++){
deneme.postDelayed(post_score, i *250);
}
}
});
the best way is to use removecallback
Related
Here is the code e.g. of result set in android first activity with UI having 3 EditText and 3 Buttons or TextView. I need to set values in 2nd TextView to display total marks which is calculated from first 3 EditText and sleep for 10sec in main method without using thread but I am getting op ie after going to sleep 10sec and immediately showing total TextView and navigated to next activity ie mentioned in code so how to wait for 10sec after setting total
EditText etMarkOne,etMarkTwo,etMarkThree;
TextView tvTMarks,tvTotal,tvGrade;
int m1,m2,m3,Tmarks;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inilizeViewControls();
eventHandlingonViewControls();
}
private void eventHandlingonViewControls(){
tvTotal.setOnClickListener(this);
}
private void inilizeViewControls() {
etMarkOne = (EditText) findViewById(R.id.etMarkOne);
etMarkTwo = (EditText) findViewById(R.id.etMarkTwo);
etMarkThree = (EditText) findViewById(R.id.etMarkThree);
tvGrade = (TextView) findViewById(R.id.tvGrade);
tvTMarks = (TextView) findViewById(R.id.tvTMarks);
tvTotal= (TextView) findViewById(R.id.tvTotal);
}
#Override
public void onClick(View v) {
m1 = Integer.parseInt(etMarkOne.getText().toString());
m2 = Integer.parseInt(etMarkTwo.getText().toString());
m3 = Integer.parseInt(etMarkThree.getText().toString());
Tmarks = m1 + m2 + m3;
tvTMarks.setText(""+Tmarks);
Thread.sleep(2000);
Intent i = new Intent(MainActivity.this,ResultActivity.class);
i.putExtra("Tmarks",Tmarks);
i.putExtra(" m1", m1);
i.putExtra(" m2", m2);
i.putExtra(" m3",m3);
startActivityForResult(i,1);
}
}
You can use Handler for your task (10000 in postDelayed() means 10sec = 10000ms):
Handler handler = new Handler();
// do work before delay here
...
handler.postDelayed(new Runnable() {
public void run() {
// do work after delay here
...
}
}, 10000);
i am new to app development and i am currently trying to make a counter app.
i have set up the buttons so that the text changes with the button pressed.
although, i am trying to make the text display the adding or subtracting value and then show the total number afterwards.
For example, my counter starts at 20;
if i press the add button i want the textview text to change to +1, +2, +3 and so on for however many times the button is pressed within a time of 2 seconds. After 2 second i want the textview to show the total again. So if i pressed it 3 times, after 2 seconds on the 3rd press i want it to display "23" and not "+3" anymore.
Then, if i pressed the minus button just once the textview will display "-1" and then after 2 seconds change to "22", etc. I also want the text color to change to green when the add button is pressed, red when the minus is pressed and white when displaying the total or at default.
Here is my code so far, i am probably off by a mile but i would really like some help to be shown in the right direction.
public class MainActivity extends Activity {
private Thread timer;
TextView lifepointsP1;
ImageButton p1AddL, p1SubL;
int counter1;
int count;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
counter1 = 20;
count = 0;
lifepointsP1 = (TextView) findViewById(R.id.tvP1LP);
p1AddL = (ImageButton) findViewById(R.id.bP1add);
p1SubL = (ImageButton) findViewById(R.id.bP1take);
//the timer
timer = new Thread() {
#Override
public void run(){
try {
synchronized(this){
wait(2000);
}
} catch(InterruptedException e){
e.printStackTrace();
}
count = 0;
lifepointsP1.setTextColor(Color.argb(0, 0, 0, 0));
}
};
p1AddL.setOnClickListener(new View.OnClickListener() {
//the buttons
public void onClick(View v) {
counter1++;
count++;
if (count == 0) {
if (counter1 >= 9|counter1 <= -1) {
lifepointsP1.setText("" + counter1);
} else {
lifepointsP1.setText("0" + counter1);
}
} else if (count > 0) {
lifepointsP1.setText("+" + count);
lifepointsP1.setTextColor(Color.argb(0, 0, 188, 0));
}
}
});
p1SubL.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
counter1--;
count--;
if (count == 0) {
if (counter1 >= 9|counter1 <= -1) {
lifepointsP1.setText("" + counter1);
} else {
lifepointsP1.setText("0" + counter1);
}
} else if (count < 0) {
lifepointsP1.setText("-" + count);
lifepointsP1.setTextColor(Color.argb(0, 214, 0, 0));
}
}
});
}
//the counter reset if pressed
#Override
public boolean onTouchEvent(MotionEvent evt) {
if(evt.getAction() == MotionEvent.ACTION_DOWN) {
synchronized(timer){
timer.start();
}
}
return true;
}
}
Ive also set it up so that if the button is pressed while the timer is counting it will reset the count to start again.
Thanks in advanced for any help, its really appreciated!
What you need is a CountdownTimer
You can implement your logic in the onFinish() method then.
You should go with Handler class
A Handler allows you to send and process Message and Runnable objects
associated with a thread's MessageQueue. Each Handler instance is
associated with a single thread and that thread's message queue. When
you create a new Handler, it is bound to the thread / message queue of
the thread that is creating it -- from that point on, it will deliver
messages and runnables to that message queue and execute them as they
come out of the message queue.
There are two main uses for a Handler: (1) to schedule messages and
runnables to be executed as some point in the future; and (2) to
enqueue an action to be performed on a different thread than your own.
public int i = 0;
Then:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
if(i != 20) {
text.append(" " + i);
i++;
handler.postDelayed(this, 1000);
} else {
handler.removeCallbacks(this);
text.append(" Stopped");
}
}
}, 1000);
}
The purpose of my app is: User enters a number and clicks a button. The button uses the input to calculate the Fibonacci sequence with a timer - with each number in the sequence displaying each second to a textView. But when I try to run the timer I get the CalledFromWrongThreadException. I've posted my code below. As you can tell by my log statements I believe I know which line is causing the problem. I think it's because I'm calling a method which is outside my onclicklistener but when I move that other method around I just cause more problems.
I've read a couple other posts and I'm not really sure what the proper way is to print to a text area using my method. Does anyone know how I can make this work?
public class MainActivity extends Activity {
// primary widgets
private EditText editText;
private TextView textView;
private Button button1;
static int seconds = 0;
static Timer timer;
static ArrayList<Integer> fibList = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText1);
textView = (TextView) findViewById(R.id.textView2);
button1 = (Button) findViewById(R.id.button1);
final int delay = 1000;
final int period = 1000;
timer = new Timer();
//Attempt to clear TextView
textView.setText("");
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Clear Textview
String array = " ";
fibList.clear();
textView.setText(array);
//Log.i("ARRAY", "ATTEMPT to CLEAR"+fibList);
String input = editText.getText().toString();
int number = Integer.parseInt(input);
int tmp = 0;
// confirm input
if (number < 20) {
Toast.makeText(getApplicationContext(),
"You entered: " + number, Toast.LENGTH_LONG).show();
for (int i = 0; i <= number; i++) {
fibList.add(fib(i));
// sum even numbers
if (fib(i) % 2 == 0) {
tmp += fib(i);
}
}
} else {
Toast.makeText(getApplicationContext(),
"Number is too Large: " + number, Toast.LENGTH_LONG)
.show();
}
//I believe error occurs in this method
Log.i("TEST", "START TIMER");
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.i("TEST", "RUN TIMER");
int nextIndex = setInterval();
Log.i("TEST", "SET INTERVAL");
if (nextIndex < fibList.size()) {
Log.i("TEST", "TRY TO PRINT");
//It looks like error occurs here when I try to print to textView
textView.setText(fibList.get(nextIndex)+ " ");
Log.i("TEST", "NEXT INDEX"+fibList.get(nextIndex));
Log.i("TEST", "DID PRINT");
}
}
}, delay, period);
Log.i("TEST", "END TIMER");
}
});
}
// run fibonacci sequence
public static int fib(int n) {
if (n < 2) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
//counts up for every element through the array
public static final int setInterval() {
if (seconds >= fibList.size())
timer.cancel();
return seconds++;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
You can use
runOnUiThread(new Runnable(){
public void run(){
textView.setText("aaa");
}
});
Have your timer post a message to a Handler. The handler will, by default, run on the main thread. IT can then change the UI as needed, so just put the body of your timer into that handler.
I just had this problem and came on to StackOverflow to check out a solution. Didn't find anything proper but a little more experimenting with lot many Logs and debugging got me my solution.
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText("Your String");
}
});
In my code, the problem was due to me accessing Two TextViews in seperate threads one after another using TextView.post(new Runnable...). I guess this was due to it not being able to access UI Thread (as it was busy with previous thread changes). Setting both TextViews together in UI Thread solved the problem. So posting here for anyone else who might be perplexed by similar problem. Hope it helps.
Spannable WordtoSpan;
TextView tvView;
public void btnStart(View v)
{
tvView = (TextView)findViewById(R.id.tvTest);
changeColorOfText("I know just how to whisper, And I know just how to cry,I know just where to find the answers.");
}
int sIndexOfWord;
int fIndexOfWord;
private void changeColorOfText(String sentences)
{
String[] arrWords = sentences.split(" ");
WordtoSpan = new SpannableString(sentences);
int k = 1;
for(String word : arrWords) {
sIndexOfWord = sentences.indexOf(word);
fIndexOfWord = sIndexOfWord + word.length();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
WordtoSpan.setSpan(new BackgroundColorSpan(Color.YELLOW), sIndexOfWord, fIndexOfWord, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tvView.setText(WordtoSpan);
}
}, 2000*k++);
}
}
This code not work, just color the last text of sentence. How can i color word one by one with handler.postDelayed method.
Thanks.
may be you can try this: call setTextColor() method recursively at interval of 2 seconds
int k = 0;
private void setTxtColor(){
if(k < arrWords.length){
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
sIndexOfWord = sentences.indexOf(arrWords[k]);
fIndexOfWord = sIndexOfWord + word.length();
WordtoSpan.setSpan(new BackgroundColorSpan(Color.YELLOW), sIndexOfWord, fIndexOfWord, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tvView.setText(WordtoSpan);
k++;
setTxtColor();
}
}, 2000);
}
}
The below displays words with green color as the foregr0und for words every 1 second.
Textview will have hello! displayed first with green color and after a delay for 1 second next word will be appended to the textview with green color. This repeats till it reaches the length of string s. If you don't want to append you just set text of the new word
_tv.setText(text); and remove the append part.
Also i have used a timer and set the text on the ui thread. You can also use a handler.
String s;
int _count=0;//counter
Timer _t;
TextView _tv;
String[] each;//holds each word in an array
Button b;
b= (Button) findViewById(R.id.button1);
_tv = (TextView) findViewById( R.id.tv );
b.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//s=et.getText().toString();
s="hello!. how are you";
_tv.setText("");
for(int i=0;i<s.length();i++)
{
each = s.split("\\s+");
}
_t = new Timer();
_t.scheduleAtFixedRate( new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
if(_count<=each.length-1)
{
SpannableString text = new SpannableString(each[_count]);
text.setSpan(new ForegroundColorSpan(Color.GREEN), 0,text.length(), 0);
_tv.append(text);
_tv.append(" ");
System.out.println("................"+each[_count]);
_count=_count+1;
}
else
{
_t.cancel();
}
}
});
}
}, 1000, 1000 ); //change to 2000 for 2 second delay.
}
});
I have two buttons in my sample Android app. I want to select a button randomly and change its background image(to yellow) and display it for 4-seconds. After the 4-seconds now again I want to change the background image(to blue) and display it for 4-seconds. Now to repeat the process of buttons random selections and do the same with the radomly selected button as I stated above.
I have developed some code, when I test the code for indvidual button it works fine but when I run for both the buttons its not working accordingly.
Please help me, I would be very thankfull to you. You can check my code as wl....
int mainCount =0;// mainCount- could be a random number
int count_1 =0;
int count_2 =0;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.mlayout);
mainHandler = new Handler();
mHandler1 = new Handler();
mHandler2 = new Handler();
.
.
.
mainRunnable.run();
}
Runnable mainRunnable = new Runnable(){
public void run(){
mainHandler.postDelayed(new Runnable(){
public void run(){
switch(mainCount){
case 0:
runButton1.run();
mainCount++; // mainCount- could be a random number to select a button randomly
break;
case 1:
runButton2.run();
mainCount++;// mainCount- could be a random number to select a button randomly
break;
}
if(count==2)
mainCount =0;
mainHandler.postDelayed(this,4000);
}
}, 4000);
}
};
Runnable runButton1 =new Runnable(){
public void run(){
mHandler1.postDelayed(new Runnable(){
public void run(){
switch(count_1){
case 0:
button1.setBackgroundResource(R.drawable.buttonyellow);
count_1++;
break;
case 1:
button1.setBackgroundResource(R.drawable.buttonblue);
count_1++;
break;
}
if(count_1==2)
count_1 = 0;
mHandler1.postDelayed(this,4000);
}
}, 4000);
}
};
Runnable runButton2 =new Runnable(){
public void run(){
mHandler2.postDelayed(new Runnable(){
public void run(){
switch(count_2){
case 0:
button2.setBackgroundResource(R.drawable.buttonyellow);
count_2++;
break;
case 1:
button2.setBackgroundResource(R.drawable.buttonblue);
count_2++;
break;
}
if(count_2==2)
count_2 = 0;
mHandler2.postDelayed(this,4000);
}
}, 4000);
}
};
First off, you don't need multiple Handlers, one will be enough. Second, you're calling mainRunnable.run() in onCreate to run another inner runnable so this would be better suited to just being a method. Regardless, here's my take:
public class MyActivity extends Activity {
private Runnable mEndlessRunnable;
#Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.my_activity);
mEndlessRunnable = new UpdateRunnable(new Handler(), new Button[] {
(Button) findViewById(R.id.button_1),
(Button) findViewById(R.id.button_2)
});
mEndlessRunnable.run();
}
private static class UpdateRunnable extends Runnable {
private Random mRand = new Random();
private Handler mHandler;
private Button[] mButtons;
private Button mCurButton;
private int mState;
public UpdateRunnable(Handler handler, Button[] buttons) {
mHandler = handler;
mButtons = buttons;
}
public void run() {
// select a button if one is not selected
if (mCurButton == null) {
mCurButton = mButtons[mRand.nextInt(mButtons.length)];
}
// check internal state, `0` means first bg change, `1` means last
switch (mState) {
case 0:
mCurButton.setBackgroundResource(R.drawable.blue_bg);
mState = 1;
break;
case 1:
mCurButton.setBackgroundResource(R.drawable.yellow_bg);
// reset state and nullify so this continues endlessly
mState = 0;
mCurButton = null;
break;
}
mHandler.postDelayed(this, 4000);
}
}
}
I haven't tested the above, but I'd use the above as a reference. Enjoy