image button changing in android - android

In my application i'm changing image of button for 1sec.how to compare image of button.i tried a lot.please help me.when i chang image 1st tyme after 1sec its not changing agian.its remain the same.below is the code-
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
if(time==-1){
onStop();
}
else
runOnUiThread(new Runnable() {
public void run() {
Random rand=new Random();
System.out.println("timer...."+time);
time=time-1;
int num = rand.nextInt(buttonIds.length);
int buttonId = buttonIds[num];
Button bb=(Button) findViewById(buttonId);
if((bb.getBackground()).equals(button.getBackground()))
{
bb.setBackgroundResource(R.drawable.happy);
wrong++;
System.out.println("llllllllllll"+wrong);
}
else
{
bb.setBackgroundResource(R.drawable.whoa);
count++;
System.out.println("mmmmmm"+count);
}
}
});
}
},0, 1000);
}

Edit
you are getting the button freshly like this
Button bb=(Button) findViewById(buttonId);
so it will always remains whoa....because the condition is always false.....
I would suggest you to set Content Description while setting the background resource and then compare the content Description....You can't compare by bb.getBackground()).equals(button.getBackground())
do something like this
but1=(Button) findViewById(R.id.b1);
but1.setBackgroundResource(R.drawable.happy);
but1.setContentDescription("happy");
and
if(bb.getContentDescription().equals(button.getContentDescription())

Related

How to disable button for 1 sec after clicked in Android?

I am using following code for using a button. I works.(sendBtn is a button in a fragment)
sendText = view.findViewById(R.id.send_text);
View sendBtn = view.findViewById(R.id.send_btn);
sendBtn.setOnClickListener(v -> send(sendText.getText().toString()));
Now i want to disable the button for 1 sec after a click
I found following solution but above code works "without onClick(View v)"method and without implementing View.OnClickListener in class. How to provide delay in such case..How code is working without onClick method.
#Override
public void onClick(View v) {
((Button) findViewById(R.id.click)).setEnabled(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
((Button) findViewById(R.id.click))
.setEnabled(true);
}
}, 1000);
}
});
Use this method when you want to interrupt user clicks:
private static long mLastClickTime = 0L;
public static boolean isOpenRecently() {
if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) {
return true;
}
mLastClickTime = SystemClock.elapsedRealtime();
return false;
}
Usage:
if (v.getId() == R.id.sendBtn) {
if (isOpenRecently()) return;
// Your logic
}
Basically you are using lambda in your code, where v->{} represents the onCLick(View v) function.
sendBtn.setOnClickListener(v -> send(sendText.getText().toString()));
You can do the following to disable the button for 1 second
void doOnSendButtonClick(View v){
//Send the message (your logic here)
send(sendText.getText().toString());
//Disable button
sendBtn.setEnabled(false);
//enable button after 1000 millisecond
new Handler(Looper.getMainLooper()).postDelayed(() -> {
sendBtn.setEnabled(true);
}, 1000);
}
And call this method when user clicks on the button
sendButton.setOnClickListener(view -> doOnSendButtonClick(view));
You could use a CountDownTimer.
CountDownTimewr timer = new CountDownTimer(1000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
// enable button
((Button) findViewById(R.id.click)).setEnabled(true);
}
}
#Override
public void onClick(View v) {
// disable btn and start timer of one second in millis
((Button) findViewById(R.id.click)).setEnabled(false);
timer.start();
}
});
Please try this way
Handler(Looper.getmainLooper()) and remove callback after you done your task inside runnable thread...also try to put this logic in any method outside in this class and call from setonclicklistener
Try the Timer.shedule with timertask
you can use runOnUIThread method inside where you can update UI.
you can also try to check the time difference of click and enable again in looping like while.

getVisibility() from inner Thread

In my testing code app I have a problem with setting if statement with getVisibility in it.
Basicaly, app should reveal (from GONE to VISIBLE) 1 TextView tv1, and then reveal 1 LinearLayout LL1 with 2 Buttons inside it btn1 & btn2. When either is pressed, LL1 should disappear (from VISIBLE back to GONE) and in its place, new tv2 or tv3 should appear (from GONE to VISIBLE) depending on which button is pressed. tv4 should wait until LL1 is GONE, and then appear. A 1s interval is set between appearances.
Everything runs ok, until IF part which doesnt work. I have also tried
if (btn1.isPressed() || btn2.isPressed())
and
if (tv2.getVisibility()==View.VISIBLE || tv3.getVisibility()==View.VISIBLE)
but it didnt work. I guess the problem is the way I acces getVisibility.
I even tryed defining global boolean x=false;, and then in OnClickListener setting x=true; but then if (x) {... returns false!?
HOW TO MAKE IF STATEMENT WORK!?
Everything (tv1..tv4, btn1, btn2, LL1) in layout file is predefined and inittialy set to GONE.
This is my activity>
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_layout);
Thread mainThread = new Thread(
new Runnable() {
#Override
public void run() {
startApp();
}
}
);
mainThread.start();
}
public void startApp() {
Button btn1 = (Button) findViewById(R.id.btn1);
Button btn2 = (Button) findViewById(R.id.btn2);
TextView tv1 = (TextView) findViewById(R.id.line1);
TextView tv2 = (TextView) findViewById(R.id.line2);
TextView tv3 = (TextView) findViewById(R.id.line3);
TextView tv4 = (TextView) findViewById(R.id.line4);
LinearLayout LL1 = (LinearLayout) findViewById(R.id.LL1);
show_line(tv1, 1000);
btnLL(LL1, btn1, btn2, tv2, tv3);
//THIS IS THE PROBLEM IT ALWAYS RETURNS TRUE
if (LL1.getVisibility()==View.GONE) show_line(tv4, 1000);
}
public void show_line (final TextView tv, int duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
tv.getHandler().post(new Runnable() {
public void run() {
tv.setVisibility(View.VISIBLE);
}
});
/*tv.setVisibility(View.VISIBLE); CANT USE THIS BECAUSE IM NOT IN UI THREAD*/
}
public void btnLL (final LinearLayout LL, Button btnLeft, Button btnRight, final TextView tvLeft, final TextView tvRight) {
//LL.setVisibility(View.VISIBLE); AGAIN NOT IN UI THREAD
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.VISIBLE);
}
});
btnLeft.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.GONE);
}
});
tvLeft.getHandler().post(new Runnable() {
public void run() {
tvLeft.setVisibility(View.VISIBLE);
}
});
}
});
btnRight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LL.getHandler().post(new Runnable() {
public void run() {
LL.setVisibility(View.GONE);
}
});
tvRight.getHandler().post(new Runnable() {
public void run() {
tvRight.setVisibility(View.VISIBLE);
}
});
}
});
}
//THIS IS THE PROBLEM IT ALWAYS RETURNS TRUE
if (LL1.getVisibility()==View.GONE) show_line(tv4, 1000);
most likely because it has not been rendered yet, thus not visible yet.
You will need to place that check in something like this:
LL1.getHandler().post(new Runnable() {
public void run() {
if (LL1.getVisibility()==View.GONE) show_line(tv4, 1000);
}
});
Which will wait for LL1 to be rendered/visible, before checking for getVisibility().
note: like GVillani82 said, you are unnecessarily using threads and posts. You don't really need Thread mainThread = new Thread() (and along with those view.getHandler().post()), only some view.post().
OK, just as I wrote a comment with my "primitive" solution, I realized the problem, tested it and confirmed :) Why that IF didn't work...
execution steps:
1) show_line() gets from GONE to VISIBLE
2) btnLL() gets from GONE to VISIBLE and sets up 2 buttons with their onClick()
3) this is the important part
this is where the user should interact with app and make a choice so onClick could execute and then 4) IF statement should execute.
What actually happened is that IF statement executed before user interaction so, the LL1 was still VISIBLE, therefore if (LL1.getVisible()==View.GONE) returned false, and by the time user presses the button and LL1 switches to GONE, IF is already executed and doesn't check any more.

How to program a pause in my app without locking up the app

I'm making a game in Android that has 1 ImageView and 4 images and buttons. I set up the ImageView so that a random image is placed in it and a new random image is displayed after so much time has passed. I need to find a way to put a delay between the changing of the images that doesn't lock the UI. Here is the code that is relevant.
public class MainGameActivity extends Activity {
int points = 0, score = 0, timer = 1000;
ImageView imgView = (ImageView)findViewById(R.id.image);
Random randy = new Random();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_game_activity);
while(points >= 0) {
changeImage();
//Timer goes here
}
}
private void changeImage() {
int randyInt = randy.nextInt(4);
if (randyInt == 0){
imgView.setImageDrawable(getResources().getDrawable(R.drawable.cheese));
} else if (randyInt == 1) {
imgView.setImageDrawable(getResources().getDrawable(R.drawable.worm1));
} else if (randyInt == 2) {
imgView.setImageDrawable(getResources().getDrawable(R.drawable.worm2));
} else if (randyInt == 3) {
imgView.setImageDrawable(getResources().getDrawable(R.drawable.minnow));
}
}
}
The 4 buttons use the same drawables as the ImageView. When the button is pressed the drawable in the ImageView and the drawable in the Image Button are checked for equivalence, so the UI still has to work while the while loop containing the pause in changing the ImageView drawable is still running. Thanks for any assistance you can give.
Sounds like you need a timer.
That has been asked and answered. Please have a look at this stackoverflow answer Android timer? How-to?
also you may try a Switch case instead of all those ifs
Switch(randyInt){
case 1:imgView.setImageDrawable(getResources().getDrawable(R.drawable.cheese));
break;
case 2:imgView.setImageDrawable(getResources().getDrawable(R.drawable.worm1));
break;
case 3:imgView.setImageDrawable(getResources().getDrawable(R.drawable.worm2));
break;
case 4:imgView.setImageDrawable(getResources().getDrawable(R.drawable.minnow));
break;
default:imgView.setImageDrawable(getResources().getDrawable(R.drawable.cheese));
break;
}
You can use the Timer like Lasse pointed in his answer. First of all you need to declare it:
private CountDownTimer timer;
Then in your onCreate you can call the timer (In this example, I'm changing the image every 5 seconds (5000ms), but you can change it if you want):
timer = new CountDownTimer(5000, 20) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
try{
callImage();
}catch(Exception e){
}
}
};
Then in your callImage method, you set the image on the imageView and start the timer again:
private void callImage(){
int randyInt = randy.nextInt(4);
if (randyInt == 0){
imgView.setImageDrawable(getResources().getDrawable(R.drawable.cheese));
} else if (randyInt == 1) {
imgView.setImageDrawable(getResources().getDrawable(R.drawable.worm1));
} else if (randyInt == 2) {
imgView.setImageDrawable(getResources().getDrawable(R.drawable.worm2));
} else if (randyInt == 3) {
imgView.setImageDrawable(getResources().getDrawable(R.drawable.minnow));
}
try{
imgView.post(new Runnable() {
#Override
public void run() {
timer.start();
}
});
}catch(Exception e){
Log.e("Error", "Error: " + e.toString());
}
}
So, every 5 seconds (or the time that you need) it will change the image, and will not block the UI.
Hope it helps!

Handler post delay not work in for loop

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.
}
});

Android TimerTask SetColorFilter of Button

this is my first Question, i hope i do it right.
I need to change the color of some buttons in a specific interval.
I decided to do it with the Colorfilter, because the setBackground method makes the Button look ugly.
The Problem is the following:
If i set the ColorFilter within a Runnable, it is not working.
But:
Setting the ColorFilter in the onCreate or click method is working.
And:
Setting the BackgroundColor with setBackgroundColor within the Runnable is working.
I forgot to mention, that it is all working fine if i run it on an emulator with android 4.1 but not with 2.3.3.
Any ideas? Here is the code
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
int counter = 0;
Button b = null;
final Handler handler = new Handler();
final Runnable doit = new Runnable() {
public void run() {
if ( counter % 2 == 0) {
b = (Button) findViewById(R.id.button1);
b.setBackgroundColor(0xffff0000); // working
//b.getBackground().setColorFilter(0xFFD2691E, PorterDuff.Mode.MULTIPLY); // doesnt work
}
else {
//b.getBackground().clearColorFilter();
b.setBackgroundColor(0xff00ff00);
}
counter++;
}
};
public void click(View view) {
// configure timer 1
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
handler.post(doit);
}
};
timer.schedule(task, 1111, 1111);
}
}
I had the same problem with imageviews.
I found a solution, you have to call the invalidate()-methode:
ImageView img =(ImageView) findViewById(R.id.myimageview);
img.getDrawable().clearColorFilter();
img.invalidate();

Categories

Resources