Not Allowing Multiple Button Presses - java

I'm building a camera app with Camera2 API, relatively new to Android development. Everything is working just working out the bugs. But I have a switch camera button, going from the front camera to the back or vise-versa. If the user continuosly presses the button, the app will crash. Trying to set it up in a way that it finishes everything it needs to do before the button can be used again.
I have the button set to enabled, but after press, it disables the button until everyting finishes, then renables, but that doesn't seem to work:
//The button to switch the camera to front and back camera.
mChangeCamera = (ImageButton) findViewById(R.id.change_camera);
mChangeCamera.setEnabled(true);
mChangeCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mChangeCamera.setEnabled(false);
closeCamera();
// stopBackgroundthread();
if (mTextureView.isAvailable()) {
setUpCamera(mTextureView.getWidth(), mTextureView.getHeight());
transformImage(mTextureView.getWidth(), mTextureView.getHeight());
connectCamera();
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
mChangeCamera.setEnabled(true);
}
});
there has to be a simple way to do this, but not finding anyting from searchs. Anyone know how I can set it up not to crash when the user smashes the button?

Alight, so I ended up figuring out how to do this. You can use a handler with a post delay like so:
mChangeCamera = (ImageButton) findViewById(R.id.change_camera);
mChangeCamera.setEnabled(true);
mChangeCamera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mChangeCamera.setEnabled(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mChangeCamera.setEnabled(true);
}
},1000);
closeCamera();
// stopBackgroundthread();
if (mTextureView.isAvailable()) {
setUpCamera(mTextureView.getWidth(), mTextureView.getHeight());
transformImage(mTextureView.getWidth(), mTextureView.getHeight());
connectCamera();
} else {
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
}
});

i did this by calculate time between multiple button presses...
create global variable in your class first
private long mLastClickTime = 0;
and a final int for duration between clicks
public static final int CLICK_TIME = 400;
then paste this code in on click of button
if (SystemClock.elapsedRealtime() - mLastClickTime < CLICK_TIME) {
return; //button pressed repeatedly so do nothing
}
mLastClickTime = SystemClock.elapsedRealtime();
// button is not pressed repeatedly so add your desired action
and of course you can increase the CLICK_TIME value if error still occurs

Related

How to disable momentarily onClick event of ImageView and Button in Android Studio

I have 2 elements:
Button answer;
Imageview play;
When 'answer' is clicked - the app records the user.
When 'play' is clicked - the app plays a clue to the user.
So when one of the above is clicked, the other should be disabled and not allow an onclick event.
Problem is - I've tried both setClickable() and setEnabled() but they don't do what I expected them to do.
Also, I've tried using a boolean flag, but it also didn't do the trick.
What am I doing wrong?
Here is the attempt with the boolean flag:
answer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mIsAudioResourcesFree)
{
mIsAudioResourcesFree = false;
//RECORDS AND STOPS RECORDING
mIsAudioResourcesFree = true;
}
}
});
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mIsAudioResourcesFree)
{
mIsAudioResourcesFree = false;
//PLAYS SOME SHORT AUDIO
mIsAudioResourcesFree = true;
}
}
});

Tap button again to confirm action

How to make a button which when pressed would show a toast message asking the user to tap button again to confirm the action. Here is what I have so far,
Button myExitClose = alertLayout.findViewById(R.id.homeExitClose);
ImageView myExitDismiss = alertLayout.findViewById(R.id.homeExitDismiss);
final LinearLayout adContainer = alertLayout.findViewById(R.id.homeExitAdView);
myExitClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
exitDialog.dismiss();
finish();
}
});
myExitDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
exitDialog.dismiss();
}
});
alert.setView(alertLayout);
alert.setCancelable(false);
exitDialog = alert.create();
}
When the button is pressed, record the timestamp of the press. If the button is pressed again, compare the new timestamp to the old one, and perform the special action if the two presses happend close enough together.
private Long lastPressedTime = null;
button.setOnClickListener(v -> {
long currentTime = System.currentTimeMillis();
if (lastPressedTime == null || (currentTime - lastPressedTime) > 2000) {
Toast.makeText(v.getContext(), "Tap again to exit", Toast.LENGTH_SHORT).show();
lastPressedTime = currentTime;
} else {
finish();
}
});
You can change the 2000 to any number you want; 2000 millis is two seconds, but maybe you want a longer window.
Use handler to schedule for setting button action like this:
final OnClickListener listener = new OnClickListener(){
public void onClick(View v) {
Toast.makeText(YourActivity.this,"press back one more time to exit",Toast.LENGTH_SHORT).show();
myExitClose.setOnClickListener(new OnClickListener(){
YourActivity.this.finish();
});
new Handler().postDelay(new Runable(){
myExitClose.setOnClickListener(listener);
},2000); //wait 2 second for the next pressed
}
}
myExitClose.setOnClickListener(listener);
Example of how to exit app on double back press within a defined interval:
private long backPressed;
private static final int TIME_INTERVAL = 2000;
#Override
public void onBackPressed() {
if( backPressed + TIME_INTERVAL > System.currentTimeMillis() ) {
finish();
super.onBackPressed();
return;
} else {
Toast.makeText(this, "Tap again to exit", Toast.LENGTH_SHORT).show();
}
backPressed = System.currentTimeMillis();
}
Paste code to a listener for an onClick().
This is the basic gist of it. Toast.maketext takes a context, string and a duration.
myExitClose.setOnClickListener( (click) -> {
Toast.makeText(getActivity(), "StringRes", Toast.LENGTH_SHORT).show();
});
You could also make a Toast object and manipulate placement etc before you show it.

How to change widget visibility from outside of OnCreate method? Java Android Studio

I have a seekbar that I want to disappear when I press a button, and reappear after a countdown. I have used seekBarTimeToPlay.setVisibility(view.INVISIBLE); in the onFinish() method after the countdown.
However, I get the error "cannot resolve symbol 'view'." And also "cannot resolve symbol 'seekBarTimeToPlay'." but seem to resolve this by adding another SeekBar seekBarTimeToPlay = (SeekBar) findViewById(R.id.seekBarTimeToPlay); inside the method.
//change timeToPlay seekBar
SeekBar seekBarTimeToPlay = (SeekBar) findViewById(R.id.seekBarTimeToPlay);
//set progress/thumb pos to right place
seekBarTimeToPlay.setProgress(timeToPlay);
seekBarTimeToPlay.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
timeToPlay = progress;
updateTimeToPlay(timeToPlay, false);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
updateTimeToPlay(timeToPlay, true);
}
});
//start playing, countdown
final Button buttonMain = (Button) findViewById(R.id.buttonMain);
buttonMain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//countdown, updating time to tidy text view, progress bar or clock animation
SeekBar seekBarTimeToPlay = (SeekBar) findViewById(R.id.seekBarTimeToPlay);
if (phase == "none") { //parent presses button, child starts playing
phase = "playing";
buttonMainText = "Pack Away Now";
//hide seekBar, doesn't change layout
seekBarTimeToPlay.setVisibility(View.INVISIBLE);
startCountDown(timeToPlay);
} else if (phase == "playing") {//parent presses button to pack away before time ended
phase = "tidying";
buttonMainText = "Confirm tidied up";
countDownTimer.cancel(); //maybe error if countdown isn't running, if statement might solve
updateTimeToPlay(timeToTidy, false);
startCountDown(timeToTidy); //new 10 minute countdown to wait for conformation that toys are away
//waiting to receive conformation, if received cancel countdown n that
} else if (phase == "tidying") { //parent presses button confirming packed away
countDownTimer.cancel(); //maybe error if countdown isn't running, if statement might solve
phaseWasTidying();
}
buttonMain.setText(buttonMainText); //change text to whatever stage
//returns here after button pressed
seekBarTimeToPlay.setVisibility(View.VISIBLE); //make visible again
}
});
}
How do I change visibility from another method? I also cannot use static which I don't understand.
View should start from uppercase beacue it's class name:
seekBarTimeToPlay.setVisibility(View.GONE);
or
seekBarTimeToPlay.setVisibility(View.VISIBLE);
And remember about import:
import android.view.View;

how to set different onclicklisteners on same button click?

I am implementing a timer in android with one text view and one button for start/stop.
How do I set register different events on clicklistener of the same button, such that when it is clicked the first time it will start a timer and when clicked a second time it will stop the timer and report the time between events?
I am implementing a timer in android with one text view and one button for start/stop.
How do I set register different events on clicklistener of the same button, such that when it is clicked the first time it will start a timer and when clicked a second time it will stop the timer and report the time between events?
Edit1
what i did is,
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_depth);
findViewById(R.id.btn).setOnClickListener(this);
}
boolean showingFirst = true;
public void generate(View view){
if(showingFirst){
long startTime = System.currentTimeMillis();
showingFirst = false;
}else{
long difference = System.currentTimeMillis() - startTime;
showingFirst = true;
TextView myText = (TextView)findViewById(R.id.tv);
myText.setText(String.valueOf(difference));
}
}
but since long starttime is started in if when the control enters else loop it shows
cannot resolve symbol 'startTime'
please help and special thanks to eliamyro
You can do it using a global boolean isStart and start or stop the timer depending on the value of the isStart.
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isStart) {
// Stop timer
isStart = false;
} else {
// Start timer
isStart = true;
}
}
});
try this,
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(btn.getText().toString().equals("Start")){
btn.setText("Stop");
// start timer
}else{
btn.setText("Start");
// stop timer
}
}
});
on click (start/stop) button start the timer according to your code and return a value to button and when you click again that flag value can be used to create a if condition for stop as well as start
As you are starting and stopping a Timer with your button you can just check if the timer is running or not. I would suggest extending a TimerTask for that use case (I took that code from here):
public class YourTimerTask extends TimerTask {
private boolean isRunning = false;
#Overrides
public void run() {
this.isRunning = true;
//rest of run logic here...
}
public boolean isRunning() {
return this.isRunning;
}
}
Then in your onClickListener you can just check if your timer is running or not:
startStopBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (yourTimer.isRunning()) {
stopTimer();
} else {
startTimer();
}
}
});

Waiting One Second for a button click, if button not clicked call function

I am creating an android application and have run into a problem.
There is 12 buttons. A button is to change color and then the user has one second to click the button, otherwise the button changes back to the original color and a different button changes color.
I would like to repeat this until the user misses a certain amount of button clicks.
I have discovered how to do the changing in colors, however I am not sure how to do an infinite loop in android or how to wait for one second.
Thanks for your help. This is my first attempt at an android application.
You can implement a timer by posting a Runnable object to run on a Handler with a specified delay. If you don't stop it from running, then the Runnable executes. However, you can also stop it from running before that:
private static final long ONE_SECOND = 1000L;
private static final int MISS_LIMIT = 10;
int misses = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_layout);
final Handler handler = new Handler();
final Runnable timer = new Runnable() {
#Override
public void run() {
// user too late: increment miss counter
if (++misses >= MISS_LIMIT) {
//TODO miss limit reached
finish(); // close this activity
}
}
};
final View btn1 = findViewById(R.id.button1);
final View btn2 = findViewById(R.id.button2);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// change color of other button, and start timer
btn2.setBackgroundResource(R.color.new_color);
handler.removeCallbacks(timer);
handler.postDelayed(timer, ONE_SECOND);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// user clicked button in time: restore color and stop timer
btn2.setBackgroundResource(R.color.orig_color);
handler.removeCallbacks(timer);
}
});
}
Firstly create a method something like this to change the color of button..
public void changeButton(int i){
switch (i) {
case 0:
button0.setClickable(true);
button0.setBackgroundResource(color1);
break;
case 1:
button0.setClickable(false);
button0.setBackgroundResource(color2);
button1.setClickable(true);
button1.setBackgroundResource(color1);
break;
case 2:
button1.setClickable(false);
button1.setBackgroundResource(color2);
button2.setClickable(true);
button2.setBackgroundResource(color1);
break;
.....
case 11:
button10.setClickable(false);
button10.setBackgroundResource(color2);
button11.setClickable(true);
button11.setBackgroundResource(color1);
break;
default:
break;
}
}
then you can implement a Runnable with some delay to call that method in loop like this..
Handler handler=new Handler();
int j=0;
final Runnable r = new Runnable()
{
public void run()
{
changeButton(j);
j++;
// next button color change
if(j<12){
handler.postDelayed(this, 1000);
}
else{
j=0;
handler.postDelayed(this, 1000);
}
}
};
handler.post(r)

Categories