The problem i'm facing at the moment is that the android emulator seems to queue the clicks i do on the button below. If i click in a regular speed, it's no problem what so ever. But whenever i so to say, spam-click the button, it seems that it recieves all clicks and does that number of operations.
Example:
The array is 5 values long, if i stand on index 5 and click on the backbutton 4 times very fast, i end up at index 1, but if i stand at index 2 and spam-clicks three times, it throws
java.lang.ArrayIndexOutOfBoundsException
code as follows:
ButtonGoBack.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// here i set it disabled to prevent mass clicks/taps/touches.
ButtonGoBack.setEnabled(false);
enumCounter--;
temporaryValue = values[enumCounter];
doSomething(temporaryValue);
// hides button
if(enumCounter== 0)
{
ButtonGoBack.setVisibility(4);
}
}
});
100~ or so code-lines after.
ButtonGoBack.setEnabled(true);
does not seem to do the trick.
any suggestions how to do this in a different manner?
Solved by surrounding with try{}catch{} and incrementing the counter by one.
ButtonGoBack.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
try
{
enumCounter--;
temporaryValue = values[enumCounter];
doSomething(temporaryValue);
// hides button
if(enumCounter== 0)
{
ButtonGoBack.setVisibility(4);
}
}
catch(Exception e)
{
ButtonGoBack.setVisibility(4);
enumCounter++;
}
}
});
If you want to start from the last after reaching 0 you can
enumCounter--;
if(enumCounter<0) enumCounter=4;
temporaryValue = values[enumCounter];
doSomething(temporaryValue);
Related
I added the following lines of Code into my OnCreate method.My goal is to assign a button to two functions and to call them up alternately. With the first click the text of the button should be changed and the EditText should be editable. At the second click, the fields should no longer be editable and the button text should change to the first alternative. I have implemented two OnClickListeners and the program structure seems logical to me. Nevertheless, I get an error message; "Cannot resolve symbol onClickListener". What can I do to get the setup described above up and running? Thanks for all responses!
private Button ProfilUpdate;
ProfilUpdate=findViewById(R.id.buttonProfilUpdate);
.
.
.
.
final ProfilUpdate.OnClickListener listener2 = new View.OnClickListener() {
#Override
public void onClick(View v) {
ProfilUpdate.setText("Profil bearbeiten");
profilVorname.setFocusable(false);
}
};
ProfilUpdate.OnClickListener listener1 = new View.OnClickListener() {
#Override
public void onClick(View v) {
ProfilUpdate.setText("Ă„nderungen speichern");
profilVorname.setFocusable(true);
v.setOnClickListener(listener2);
}
};
ProfilUpdate.setOnClickListener(listener1);
why don't you create a boolean isFirstClick = true , and then check it in the same listener
ProfilUpdate.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(isFirstClick){
//Do the job for the first click process
isFirstClick= false;
}else {
//Do the job for the second click process
isFirstClick= true;
}
}
};
ProfilUpdate.setOnClickListener(listener);
There can only be one click listener on one view at a time. Use ProfileUpdate.setOnClickListener(listener object). To get the alternate functionality, you can define a Boolean to keep track of the state, for the example, define a class variable at the top Boolean shouldChangeText = true, and in the onClick body in the listener, do something like:
If (shouldChangeText) { // change the text
}
else { // clear the text
}
shouldChangeText = !shouldChangeText
Sorry for the terrible title, I am bad at describing these things.
I am building a metronome and have a (-) UI button that decreases the tempo by 1, and a (+) UI button that increases the tempo by 1.
My problem currently is that whenever I press either buttons, the metronome restarts itself since there's a new tempo, and plays immediately. So if you press the (-) button 10 times in a row, each time you press it you hear the initial metronome "beep".
I would like my app to do the following:
When the user clicks either (-) or (+) buttons, wait for 200 milliseconds
IF the user didn't click the buttons again in that timeframe, play the metronome
If the user DID click the button again, don't play the metronome, repeat the process: wait 200 milliseconds, if no click was made play the metronome, etc
The end result would be that if I'm at 100 bpm and I repeatedly press the (+) button 20 times until I am at 120 bpm, the metronome wouldn't start playing until I am done tapping.
How do I go about implementing this? Thank you!
Declare and instantiate the below in your activity:
private Handler timeoutHandler = new Handler();
private Runnable delayStartThread = new Runnable() {
public void run() {
startMetronome();
}
};
Then insert the below code block in your onClickListener for both + and - buttons:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timeoutHandler.removeCallbacks(delayStartThread);
tempoOfMetronome++; //tempoOfMetronome--; for decrease button
stopMetronome();
timeoutHandler.postDelayed(delayStartThread, 200);
}
});
For more details on how the code works, refer the below links for examples (I used these examples to formulate the answer):
Android: clicking TWICE the back button to exit activity - How to use handler.postDelayed()
How to cancel handler.postDelayed? - How to cancel handler.postDelayed()
You should also look at the Android documentation for those methods.
If you want a delay between the action and the effect, there are several ways you can achieve it. This is one.
private boolean pressedAction = false;
#override
public void onClick(View v) {
if (pressedAction) return;
pressedAction = true;
new Thread(new Runnable(
#override
public void run() {
try {
Thread.sleep(200); // 200 miliseconds
} catch (Exception e) {}
// Update views or do work (program logic)
pressedAction = false;
}
}
}
Then, the metronome logic is your bussiness.
The problem is that I have an Android app that doesn't seem to show the xml layout when I put this while loop into the class file. The loop is as follows:
while(!clicked){
button_a.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
player= MediaPlayer.create(GameActivity.this, R.raw.a);
player.start();
clicked = true;
letterTapped = 0;
}
});
}
The whole project works completely fine without it so I'm pretty sure that there must be something wrong with the loop that I am overlooking.
If you want me to put any other bits of code up here I will be more than happy to.
To stop listening as soon as the button is pressed, you can use this code:
button_a.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
player= MediaPlayer.create(GameActivity.this, R.raw.a);
player.start();
letterTapped = 0;
// Ignore further clicks
button_a.setOnClickListener(null);
// Disable button so the user knows that he can't click again
button_a.setEnabled(false);
}
});
I have a android project that generates random numbers as the button's text. If you click a button the value of the corresponding button should be displayed in the edittext.
I am already getting the value of the buttons and also able to display it in the edittext. I have 12 buttons and 2 edittexts. What I want is, if I will do the first click then first value will display in the first edittext and in the second click the value will display in the second edittext.
My problem is that in the first click the value is getting displayed in the 2 edittexts simultaneously. Hope you can help me, here is my code:
b1=(Button)findViewById(R.id.b1);
et1=(EditText)findViewById(R.id.first);
et2=(EditText)findViewById(R.id.second);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
str=((Button)v).getText().toString();
et1.setText(str);
et2.setText(str);
}
});
b1 = one of the buttons.
et1 and et2= the two edittexts.
str = empty string
That doesn't surprise me. You don't distinguish your cases within your onClickListener.
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
str=((Button)v).getText().toString();
// Check which edit text
if(isFirstClick()) {
et1.setText(str);
setFirstClick(false);
} else {
et2.setText(str);
}
}
});
See the 'isFirstClick()' like some kind of pseudo code, maybe you can also check if your first editbox is still empty or something like that.
Both #Averroes and #Sambuca have provided a smiliar solution which should work:
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
str=((Button)v).getText().toString();
if((et1.getText().toString()).equals(""))
et1.setText(str);
else
et2.setText(str);
}
});
In case you can do more than 2 clicks and your requirement is to output to textBox1 on odd clisk and Textbox2 on even click - use a boolean variable.
I'm trying to build a SMS application that sends a SMS with one press on a button, this part is working but now I'm trying to implement a spam protection.
The spam protection means that you only can send 1 SMS per 10 seconds (or higher).
I've tried this:
sentSMS.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Timer timer = new Timer();
int seconds = 10000;
timer.schedule(new TimerTask() {
public void run() {
processClick();
}
}, seconds);
}});
But this is not working when I press the button twice the SMS is also sending twice.
Maybe it's also a idea to make a toast which contains how many seconds the user have to wait, something like this:
Toast.makeText(getBaseContext(), "Spam protection, wait "+secondstowait,
Toast.LENGTH_SHORT).show();
Is this all possible to make?
why dont you just take a timestamp when the button was first clicked then compare the time when the button was clicked again and see if the difference is greater than the allotted amount of time?
Potentially, the easier thing to do in my opinion is to disable the button, and use the built-in handler (on the view object) to re-enable the button.
sentSMS.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
final View view = v;
v.setEnabled(false);
v.postDelayed(new Runnable(){
public void run(){
view.setEnabled(true);
}
}, 1000*10);
}});
You need to store when the button was last clicked and then see if 10 seconds have passed.
long lastTimeSent = 0; //start at 0
sentSMS.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(System.currentTimeMillis() > lastTimeSent + 10000){ //if at least 10 secs has passed from last click
processClick();
lastTimeSent = System.currentTimeMillis(); //last time sent is now current time
}else{
Toast.makeText(getBaseContext(), "Spam protection, please wait.",
Toast.LENGTH_SHORT).show();
}
}});
if you want to show a toast message to user, notifying him about how many seconds are left,
you must write the toast.maketext code inside the timer schedule event too
using timestamp will not be easier way, rather it will make task more difficult.
You can also try to disable the button onclick for ten seconds and re-enable it after the time period is expired.