I have a function attached to a button that when pressed removes an item from an arraylist and then displays a toast saying "Item Removed!". If I press the remove button several times then ALL the toasts show up making it look like one really long toast display. I want to cancel the toast each time before displaying a new toast. I was displaying my toast as such
public void removeItem(View view)
{
Toast.makeText(getApplicationContext(),"Text",toast.LENGTH_LONG).show();
}
Now I am trying to make a toast object, cancel it, set the text, and then display it each time the button is pressed. This way the previous toast is cancelled. Not sure if this is the right way to do it.
public void removeItem(View view)
{
Toast toast = Toast.makeText(this,"",Toast.LENGTH_SHORT);
toast.cancel();
toast.setText("Text");
toast.show();
}
This ends up showing nothing at all. Any help?
Your given example does not work because you are calling cancel() on the newly created instance of your Toast object. You'll have to keep a reference to the currently shown Toast somehow, and cancel it before displaying it again.
Toast mMyToast // declared within the activity class
public void removeItem(View view)
{
if(mMyToast!=null) mMyToast.cancel() // Avoid null pointer exceptions!
mMyToast = Toast.makeText(this,"Text",Toast.LENGTH_SHORT);
mMyToast.show();
}
A couple of thoughts:
1: you could make the text more specific so that they can see which item was removed and they don't look like one long toast: "Removed Item: Bob", "Removed Item: Mary".
2: Make the toast display length short.
3: Consider skipping the toast all together. I assume they will see the items being removed from the list as you click.
Related
I was creating a simple calculator with android. I searched the google and found this fragment of code which worked perfectly for me. But I cannot understand this fragment of the code which was implemented on the onCreate() method. Can someone please explain me this part of code?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Welcome :)", Toast.LENGTH_SHORT).show();
int[]Btn_Id={ R.id.Btn0, R.id.Btn1, R.id.Btn2, R.id.Btn3,R.id.Btn4, R.id.Btn5, R.id.Btn6, R.id.Btn7, R.id.Btn8, R.id.Btn9, R.id.BtnClear, R.id.BtnDecimal, R.id.BtnDivide, R.id.BtnMultiply, R.id.BtnSubtract, R.id.BtnAdd, R.id.BtnEqual };
for(int i: Btn_Id) {
((Button)findViewById(i)).setOnClickListener(this);
}
}
int[]Btn_Id
it is a array of button which contain id of buttons defined in layout resource file
The below code is used to set ClickListener to all Button in your Btn_Id array
for(int i: Btn_Id) {
((Button)findViewById(i)).setOnClickListener(this);
}
The method onCreate is called when activity starts, its the entry point for the activity.
And activity is empty window, the setContentView is used to fill the resource of id R.layout.activity_main
super.onCreate(savedInstanceState);, you tell the Dalvik VM to run your code in addition to the existing code in the onCreate() of the parent class. If you leave out this line, then only your code is run. The existing code is ignored completely.
R.id.Btn0.... means its defined in resource file and used to show 0 and other buttons. int[]Btn_Id variable holds the resource id of the used buttons.
The following line assigns listener for button click for all the buttons:
for(int i: Btn_Id) {
((Button)findViewById(i)).setOnClickListener(this);
}
Hear is the solution of your problem hope you understand code till
Toast.makeText(this, "Welcome :)", Toast.LENGTH_SHORT).show();
which will create toast message 'welcome' when activity launch.
int[]Btn_Id={ R.id.Btn0, R.id.Btn1, R.id.Btn2, R.id.Btn3,R.id.Btn4, R.id.Btn5, R.id.Btn6, R.id.Btn7, R.id.Btn8, R.id.Btn9, R.id.BtnClear, R.id.BtnDecimal, R.id.BtnDivide, R.id.BtnMultiply, R.id.BtnSubtract, R.id.BtnAdd, R.id.BtnEqual };
Above the Btn_Id is an integer array that will store ID of the all button from btn0 to btnEqual
for(int i: Btn_Id) {
((Button)findViewById(i)).setOnClickListener(this);
}
this function called for each loop. It work like for every int ID in array Btn_Id and assign to int i. and for every i set Button.setOnClickListner(this)\ this is a context.
if you try to find a source code of android calculator then you can get from hear free.
Download Source code:https://www.youtube.com/playlist?list=PLdMmtAIsH0KYiKrdpbzat6t96Nb1_k3_1
I have an app how to make some notification when reaching specific time ...
I would to show some pop-up or custom layout when my app is onStop or onDestroy.
I would like this photo.
(click to enlarge)
If you just want to give a message then Toast is enough and easy.
#override
public void onStop() {
Toast.MakeText(context, "Your message here", Toast.LENGTH_LONG).show();
}
#override
public void onDestroy() {
Toast.MakeText(context, "Your message here", Toast.LENGTH_LONG).show();
}
EDIT: I won't recommend you to write long messages in Toast and show it for longer durations, instead consider a Statusbar Notification. Status Bar Notifications can be programmatically canceled when they are no longer relevant.
BUT If you still want to increase the duration of Toast message then here is a workaround.
private Toast mToastToShow;
public void showToast(View view) {
// Set the toast and duration
int toastDurationInMilliSeconds = 10000;
mToastToShow = Toast.makeText(this, "Hello world, I am a toast.", Toast.LENGTH_LONG);
// Set the countdown to display the toast
CountDownTimer toastCountDown;
toastCountDown = new CountDownTimer(toastDurationInMilliSeconds, 1000 /*Tick duration*/) {
public void onTick(long millisUntilFinished) {
mToastToShow.show();
}
public void onFinish() {
mToastToShow.cancel();
}
};
// Show the toast and starts the countdown
mToastToShow.show();
toastCountDown.start();
}
Here is how it works: the countdown has a notification time shorter than the duration for which the toast is displayed according to the flag, so the toast can be shown again if the countdown is not finished. If the toast is shown again while it is still on screen, it will stay there for the whole duration without blinking. When the countdown is finished, the toast is canceled to hide it even if its display duration is not over.
Simplest way would be to use a Toast (easy and immediate). More complex way is that you've to grant 2 special permissions "draw over other apps" and "app with usage access" (which are special permissions, so you need to create your own page to prompt the user to grant it), after which you can add your custom view directly to the windows manager of the system. Last but not least, you should seriously think if there's any benefit for the user to be notified on main screen about something after your main page has been stopped or destroyed, because that goes against the system design quite a lot.
I am building a very basic vocabulary application. The feature I am trying to implement right now is a go to feature, that is taking the user to a specific vocab term. i am doing this by prompting the user with a dialog fragment that asks the user for a page number. (dialog fragment will get triggered via a callback, button press)
This is my code for doing so
public class GoToDialog extends DialogFragment{
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String pgn = pageNumber.getText().toString();
if(!isNumeric(pgn) || pgn.isEmpty()) {
Toast.makeText(getActivity(), "Please enter a valid number", Toast.LENGTH_SHORT).show();
} else {
int pagina = Integer.parseInt(pgn);
if(pagina <= 0 || pagina > total) {
Toast.makeText(getActivity(), String.format("Please enter a valid " +
"term number between 0 and %d", total), Toast.LENGTH_SHORT).show();
} else {
getDialog().dismiss();
getFragmentManager().executePendingTransactions();
communicator.onDialogMessage(pagina);
}
}
}
});
Here are screenshots when I run my application
Screenshot2(right after screenshot 1)
In terms of functionality The dialog loads up fine and is able to take the user to the right location. However in that example of taking the user from term 7 to term 5, the user is taken to the
right term but the dialog doesn't close as it should from getDialog().dismiss(). I know dismiss is being called because I walked through the code and communicator.onDialogMessage(pagina) returns the right term number to the activity. The dialog does close when I select another term number to go to. Does anyone see the issue? This doesn't make sense to me at all.
To close a dialog, dismiss is the correct method to use
- How to correctly dismiss a DialogFragment?
I also tried what a user suggested in Correct way to remove a DialogFragment: dismiss() or transaction.remove()?, which is to call executePendingTransactions().
If anyone's having a similar issue, the issue with my application was my OnTouchListener.
When I set up on OnTouchListener to trigger the DialogFragment, here was my original code for doing so
goTo - TextView
private void setUpGoToTouchListener() {
goTo.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
FragmentManager fm = MainActivity.this.getFragmentManager();
GoToDialog dialog = new GoToDialog();
Bundle bundle = new Bundle();
bundle.putInt("Size", defMan.getTotalCount());
dialog.setArguments(bundle);
dialog.show(fm, "Manager");
return true;
}
});
}
When the gesture(a touch) on the TextView occurs, two MotionEvents will be generated, the press, ACTION_DOWN - first finger has touched the screen, and the release, ACTION_UP - the last of the fingers has stopped touching the screen. Because two motion events occurred, two dialog fragments were created. Thats why dismiss had to be called twice in my situation to get rid of both dialog fragments. I fixed this by having a conditional test for event.getAction()
I have an Android app that displays a list using a ListView, and there's an action bar button to clear said list. I decided to add a confirmation dialog so people don't accidentally delete all their entries, and I'm running into problems. If I use setListAdapter inside the onclick for the "yes" button within the dialog, it won't compile. If I use it outside that onclick, it'll work but not refresh the list until the user backs out of the activity and goes back into it, which for obvious reasons is not appropriate. Here's my method that gets called when the "clear list" action bar button is pressed, which contains the relevant onclick for the internal buttons.
I have a feeling I shouldn't be using "this" in setListAdapter since with the dialog, this no longer corresponds to the listview activity I think? But I'm not sure what to put instead.
public void clearTrigger(MenuItem item) {
//Set up a dialog with two buttons to verify that the user really wants to delete
everything
confirm = new Dialog(display.this);
confirm.setContentView(R.layout.conf);
confirm.setTitle("Confirm deletion");
yes = (Button)confirm.findViewById(R.id.yes);
//If the user says yes, then delete everything
yes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Remove everything from Hours.
Hours.clear();
String tempH = " ";
String tempW = " ";
//Then save it again in it's new, empty state so that it doesn't reappear the next time the app is run.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
SharedPreferences.Editor edit = prefs.edit();
edit.putString("SAVEDATA", TextUtils.join(",", Hours));
edit.remove("totalh");
edit.remove("totalw");
edit.commit();
//And finally... refresh the list view - doesn't work
setListAdapter(new ArrayAdapter<String>(this, R.layout.activity_list, R.id.listText, Hours));
confirm.dismiss();
}
});
confirm.show();
}
The first argument of ArrayAdapter constructor is a Context, so you need to pass the Activity to it, something like new ArrayAdapter<String>(MyActivity.this, ...). Right now you're passing it your instance of OnClickListener which is why it's giving compiler error.
But the best way to update a ListView is to make changes on the ArrayAdapter itself using methods like adapter.add and adapter.remove, and then call adapter.notifyDataSetChanged(). In your case, you would call adapter.clear().
I have a menu button, that when I click it, it sends some data to the cloud. While it is sending the data, I display a progress dialog. Every thing goes swimmingly and seems to be fine and I can press the button as many times as I want and the data is properly sent to the cloud.
But when I go to exit the activity I get a error saying that there was a window leak:
com.android.internal.policy.impl.PhoneWindow$DecorView{4321fd38 V.E..... R......D 0,0-1026,288} that was originally added here
the "here" is referring to when I insatiate my progress dialog.
Here is my code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
progressDialog = ProgressDialog.show(CruiseDetailRollCallActivity.this, "", "Loading...", true);//set up & show progress dialog
switch(item.getItemId()){
case R.id.menu_roll_call_opt_in:
//saveing something into Parse -- (a database online, check Parse.com if you want more info, but just treat this like I am saving something into the cloud)
currentUser.put("somethingBoolean", false);
currentUser.saveInBackground(new SaveCallback(){
#Override
public void done(ParseException e) { //once data has been put into the cloud
progressDialog.dismiss();//dismiss the dialog
supportInvalidateOptionsMenu();//refreshes the options menu
}
});
return true;
default:
return super.onOptionsItemSelected(item);
}
}
I should mention that this is not crashing my application but merely displaying the error. I have no clue why it is happening, and I feel like I shouldn't just ignore it.
EDIT: found my mistake. It was failing because works was because I was hitting back on the action bar and the progress dialog would be created but never dismissed since it was only being dismissed inside the done code.
My guess is that you're leaking the activity into the currentUser object, when you pass the CruiseDetailRollCallActivity into currentUser.saveInBackground(new SaveCallback().... The SaveCallback class that you just created now has a strong reference to the Activity. It will never be garbage collected, even though you exit the method. You should use a WeakReference and then it can be garbage collected.
WeakReference<CruiseDetailRollCallActivity> weakRef = new WeakReference<CruiseDetailRollCallActivity>(CruiseDetailRollCallActivity.this)
Then, pass the weakRef in to the ProgressDialog constructor:
progressDialog = ProgressDialog.show(weakRef.get(), "", "Loading...", true);
Whenever you're passing around the Context in Android, check to see if you need a WeakReference so it can be garbage collected. It's easy to leak the entire application.
It was failing because works was because I was hitting back on the action bar and the progress dialog would be created but never dismissed since it was only being dismissed inside the done code.
I moved
progressDialog = ProgressDialog.show(CruiseDetailRollCallActivity.this, "", "Loading...", true);//set up & show progress dialog
into
case R.id.menu_roll_call_opt_in:
//saveing something into Parse -- (a database online, check Parse.com if you want more info, but just treat this like I am saving something into the cloud)
currentUser.put("somethingBoolean", false);
currentUser.saveInBackground(new SaveCallback(){
#Override
public void done(ParseException e) { //once data has been put into the cloud
progressDialog.dismiss();//dismiss the dialog
supportInvalidateOptionsMenu();//refreshes the options menu
}
});
return true;
so looks something like this
case R.id.menu_roll_call_opt_in:
progressDialog = ProgressDialog.show(CruiseDetailRollCallActivity.this, "", "Loading...", true);//set up & show progress dialog
//saveing something into Parse -- (a database online, check Parse.com if you want more info, but just treat this like I am saving something into the cloud)
currentUser.put("somethingBoolean", false);
currentUser.saveInBackground(new SaveCallback(){
#Override
public void done(ParseException e) { //once data has been put into the cloud
progressDialog.dismiss();//dismiss the dialog
supportInvalidateOptionsMenu();//refreshes the options menu
}
});
return true;