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.
Related
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
I have 1 button in activity. i want to use this 1 button for multiple task.
So how can i do ?
If i pressed 1st time this button then it's change 2 button
if i pressed 2nd time then it's update my data
but it's only work 1st time 2nd time it's not work
see my code what i tried
Intent extras = getIntent();
{
if (extras.hasExtra("edit")) {
if (extras.getStringExtra("edit").equals("home")) {
etCompanyName.setEnabled(false);
etWebsite.setEnabled(false);
etEmail.setEnabled(false);
etPhoneHome.setEnabled(false);
etPhonePrimary.setEnabled(false);
etAddressLine1.setEnabled(false);
etAddressLine2.setEnabled(false);
etCity.setEnabled(false);
spStates.setEnabled(false);
etZip.setEnabled(false);
spContries.setEnabled(false);
//1st time use hear
txtSave.setText(getResources().getString(R.string.label_edit));
txtClose.setText(getResources().getString(R.string.label_back));
txtSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
txtSave.setText(getResources().getString(R.string.label_add));
txtClose.setText(getResources().getString(R.string.label_cancel));
etCompanyName.setEnabled(true);
etWebsite.setEnabled(true);
etEmail.setEnabled(true);
etPhoneHome.setEnabled(true);
etPhonePrimary.setEnabled(true);
etAddressLine1.setEnabled(true);
etAddressLine2.setEnabled(true);
etCity.setEnabled(true);
spStates.setEnabled(true);
etZip.setEnabled(true);
spContries.setEnabled(true);
}
});
if (extras != null) {
Company value = (Company) extras.getSerializableExtra("company");
etCompanyName.setText(value.getName());
etWebsite.setText(value.getWebsite());
etEmail.setText(value.getEmail());
etPhoneHome.setText(value.getPhoneHome());
etPhonePrimary.setText(value.getPhonePrimary());
etAddressLine1.setText(value.getAddressLine1());
etAddressLine2.setText(value.getAddressLine2());
etCity.setText(value.getCity());
etZip.setText(value.getZipcode());
}
} else {
//2nd time use hear
txtSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Company company = new Company();
company.setName(etCompanyName.getText().toString().trim());
company.setWebsite(etWebsite.getText().toString().trim());
company.setEmail(etEmail.getText().toString().trim());
company.setPhoneHome(etPhoneHome.getText().toString().trim());
company.setPhonePrimary(etPhonePrimary.getText().toString().trim());
company.setAddressLine1(etAddressLine1.getText().toString().trim());
company.setAddressLine2(etAddressLine2.getText().toString().trim());
company.setZipcode(etZip.getText().toString().trim());
company.setCity(etCity.getText().toString().trim());
company.setState(spStates.getSelectedItem().toString());
company.setCountry(spContries.getSelectedItem().toString());
company.setDate(Util.getInstance(AddCompanyActivity.this).getCurrentDate());
long isUpdated = myDb.updateCompany(company);
if (isUpdated != -1) {
Toast.makeText(getApplicationContext(), "Company Update Successfully: " + isUpdated, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Something wrong", Toast.LENGTH_SHORT).show();
}
finish();
}
});
}
}
}
You can see my above code i can used txtSave button for perform 2 task but it's only change two buttons and i'll change data and click on button then it's can't perform
Try this way, first declare global variable on your activity class file like below :
int count = 0;
After that add your click listener like that:
yourButton.setOnClickListener(v -> {
if (count == 0) { // the first click
count++;
// do your stuff
}else { // the second click
count = 0; // initialize the count to limit the button click just for the first and the second time only
// do your stuff
}
});
You should not create multiple OnClickListener for Button , Create only 1 and use it
example:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(btn.getText().equals("1")){
//perform action for 1
btn.setText("2");
//change button1 to button2
}else if(btn.getText().equals("2")){
//perform action for 2
btn.setText("3");
}
}
});
you could use single onclicklistener with switch case
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
swtich(extras.getStringExtra().toLowerCase(){
case "1":
// do something
break;
case "2":
// do something else
break;
}
});
}
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();
}
}
});
My goal is add data to listView, after push on notification shows dialog, if user press Yes, app will show activity with fragment, and again will display new dialog to add new item. But if I press add, I get:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.LoaderManager android.support.v4.app.FragmentActivity.getSupportLoaderManager()' on a null object reference
My dialog to add new item to listview be in MainActivity, but I need to refresh my listview in Fragment, i am using ViewPager.
It seems like my fragment not initialized yet, but dialog at display now. How to implement this solution? One more thing, in my notification I set AutoCancel(true), but notif is still being on screen.
Here is the screen chronology:
Step 1
Step 2
one more image i can't add(
My dialog activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final String text = getIntent().getStringExtra("text");
new AlertDialogWrapper.Builder(this)
.setTitle(R.string.title_alert)
.setMessage(R.string.title_alert)
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(DialogActivity.this, MainActivity.class);
intent.putExtra("notification",true);
intent.putExtra("text",text);
startActivity(intent);
finish();
}
}).show();
}
My method which will cal if user press add item in second dialog
private void showTrackerDialog(TrackersFragment f, final String text,boolean isFromNotif) {
final TrackersFragment trackersFragment = f;
tracker = new Tracker();
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title("New tracker :)")
.customView(R.layout.add_track, true)
.positiveText("ADD")
.positiveColorRes(R.color.primary_light_green)
.negativeText(android.R.string.cancel)
.negativeColorRes(R.color.primary_red)
.callback(new MaterialDialog.ButtonCallback() {
#Override
public void onPositive(MaterialDialog dialog) {
if (hours.getValue() == 0 && minutes.getValue() == 0 && isLimit.isCheck()) {
Toast.makeText(getApplicationContext(), "Please check your the input values!", Toast.LENGTH_SHORT).show();
return;
}
//limited
if ((((hours.getValue() != 0 && minutes.getValue() == 0) || (hours.getValue() == 0 && minutes.getValue() != 0))
|| (hours.getValue()!=0 && minutes.getValue()!=0)) && isLimit.isCheck()) {
try {
hoursToMillis = Long.parseLong(String.valueOf(hours.getValue()));
minutesToMillis = Long.parseLong(String.valueOf(minutes.getValue()));
tracker.setLimitTime((hoursToMillis * 60 * 60 * 1000) + (minutesToMillis * 60 * 1000));
tracker.setName(name.getText().toString());
tracker.setElapsedTime((long) 0);
tracker.setIsFinished(false);
tracker.persist(RemindMe.db);
trackersFragment.updateListView(true,tracker);
return;
} catch (Exception ex) {
ex.printStackTrace();
Toast.makeText(getApplicationContext(), "Something goes wrong :(", Toast.LENGTH_SHORT).show();
return;
}
}
//no limit
if (!isLimit.isCheck()) {
tracker.setLimitTime(0L);
tracker.setName(name.getText().toString());
tracker.setElapsedTime((long) 0);
tracker.setIsFinished(false);
tracker.persist(RemindMe.db);
trackersFragment.updateListView(true,tracker);
}
}
#Override
public void onNegative(MaterialDialog dialog) {
}
}).build();
And here is the NullPointerExeption, getSupportLoaderManager()
public void updateListView(boolean isAdded,Tracker tracker) {
if(isAdded && tracker!=null){
trackerList.add(tracker);
getActivity().getSupportLoaderManager().getLoader(TRACKLOADER_ID).forceLoad();
adapter.swapCursor(Tracker.getAll(db));
}
}
Your problem here isn't trying to add to the list, but understanding the lifecycle. It seems to me that you have not setup the fragment, or possible have crossed paths of which fragment library you are using. Your error says v4.Support.Fragment. Make sure you use that same class everywhere. Even when opening it. (Check your imports. Make sure they are all v4).
Also check that your MainActivity does not extend Activity, but FragmentActivity
After which, If you are trying to notify your app from a notification, your best solution is going to be a BroadcastReceiver.
I have to check whether the button is clicked or not.if clicked application has to do one task and if not, application has to do another task. I tried to do this, but I am getting no connection error which I have put at the end of the code in catch block.
protected void onCreate(Bundle savedInstanceState) {
PracticeVO practiceObj;
try {
setTitle("Klarity");
setPrefBtn = (Button) findViewById(R.id.setPrefBtn);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_klarity_home);
/*
* asynchronous calls
*/
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
final ConnectionHelper con = new ConnectionHelper();
/*
* It will connect to DB and fetches the Practice Information
*/
if (Btnclicked == false) {
String allPracticesStr = null;
here I have set the boolean variable 'Btnclicked' true.
setPrefBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Btnclicked=true;
Intent setPrefIntent = new Intent(KlarityHome.this,
SetPreferences.class);
startActivity(setPrefIntent);
}
});
But After executing this The cursor is directly goin here and displaying 'no connection'.
catch (Exception ex) {
Context context = getApplicationContext();
CharSequence text = "There is some error in application";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
System.out.println("no connection");
}
}
Anyone has solution on this.
as you said
"the button is clicked or not.if clicked application has to do one task and if noapplication has to do another task"
so, if i were you, i'll put 2 radio buttons, every one with the text of the task you want to do, and add a listener for them, like this:
radiobutton1.setOnCheckedChangeListener(new RadioButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
radiobutton2.setChecked(false);
}
});
radiobutton2.setOnCheckedChangeListener(new RadioButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
radiobutton1.setChecked(false);
}
});
and last, in the button do the task you want to do:
Button.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
if(radiobutton1.isChecked){
//do task 1
}else{
//do task2}
}
});
You are getting an NPE(NullPointerException) since you havent initialised Btnclicked in your code at the time of usage.ie you are checking whether Btnclicked is false like
if (Btnclicked == false) {
But at the time of this checking, the value of Btnclicked is null and hence an NPE.
So to get rid of this, you just add either
Btnclicked=true;
or
Btnclicked=false;
before the if loop according to your logic.
OR
or just replace the declaration from Boolean Btnclicked; to Boolean Btnclicked=false;
Hope this helps.
Remove Btnclicked you don't need that. OnClickListner is meant for what you're trying to do. The code which you want to run when button is not pressed put it before
//When button is not pressed
setPrefBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//When button is pressed
}
});
And the code which you want to run when the button is clicked place it inside the onClick(){}