Im writing an Android application in which a user selection triggers a custom Dialog, from which a selection may trigger a second Dialog.
When showing the initial Dialog from the Activity class, I'm setting an onDismissListener on it to pull out user selections which works fine other in cases where the 2nd Dialog is not triggered. The issue that I'm having is that I can't figure out how to have the first one Dialog remain open until the 2nd one is dismissed, so that the information from both is sent back to the Activity class.
Hopefully some code will make this a little more clear:
MainActivity class where I am launching the initial CustomDialog:
customDialog = new CustomDialog(this);
customDialog.show();
customDialog.setOnDismissListener(new OnDismissListener(){
public void onDismiss(DialogInterface di){
slection = customDialog.getselection();
updateUI(); //updates a listview with the results
}
});
Within the CustumDialog class where I am launching the SecondDialog on top of it:
if(specify){
SecondDialog secondDialog = new SecondDialog(context);
secondDialog.show();
secondDialog.setOnDismissListener( new OnDissmissListener(){
public void onDismiss(DialogInterface di){
// this is where I want to call the CustomDialog's dismiss() method
// so that they both close at the same time and the data from here
// can be sent back to the MainActiivty through the CustomDialog's
// onDismissListener
}
});
}
dismiss();
So, to reiterate: I'm trying to prevent the CustomDialog's dismiss() method to be called until the SecondDialog is also dismissed. Is there a way that I can call it from the SecondDialog's OnDismissListener?
You should create customDialog as an instance level variable. You then it will be accessible with onDismiss(...) of second dialog. There you can call customDialog.dismiss();
// Instance level variable
private Dialog customDialog = null;
Instanciate your customDialog, then create second dialog from within your customDialog. Your Second dialog's code would look like this.
if(specify){
SecondDialog secondDialog = new SecondDialog(context);
secondDialog.show();
secondDialog.setOnDismissListener( new OnDissmissListener(){
public void onDismiss(DialogInterface di){
// customDialog is accessible as it is declared as instance level variable
MyClassName.this.customDialog.dismiss();
}
});
}
dismiss();
I prefer to save the data in 1st dialog before going to send one and when dismiss the 2nd dialog, open the 1st dialog again with saved data .. i used this way in my developing and its effective ..
Related
After many search I can not resolve my problem.
I start a dialog from adapter then from my dialog i call an activity (by intent). I would like to return to my dialog with the result from my activity. here my code :
final Dialog dialog = new Dialog(MyActivity.context);
dialog_actv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
add_dialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{Intent add = new Intent(MyActivity.context,MySecondActivity.class);
MyActivity.context.startActivity(add);
From the called activity I would like to return to the dialog. How can i do ?
Thanks for help.
Instead of showing your dialog from your adapter you can show it from an activity like below:
In your adapter:
((YourActivity)mContext).showCustomDialog();
In your YourActivity.java
public void showCustomDialog(){
Intent add = new Intent(MyActivity.context,MySecondActivity.class);
startActivityForResult(add);
}
In your activity handle your result and make changes in dialog.
Let me know if it works for you.
You can use a DialogFragment and override onActivityResult callback to get result.
Note
To get the result in your fragment make sure you call startActivityForResult(intent,reqCode) instead of getActivity().startActivityForResult(intent,reqCode) in your fragment.
If the hosting activity already overrides the onActivityResult, make sure it calls super.onActivityResult for unhandled result codes.
I need to clear password field on exit of app,i am exiting the app in other activity and on exit it goes to mainActivity which has login details in which i need to clear password field,how will i do this in other activity ,i tried using setText("") but in vain.
public void backButtonHandler() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
ReminderActivity.this);
// Setting Dialog Title
alertDialog.setTitle("Leave application?");
// Setting Dialog Message
alertDialog.setMessage("Are you sure you want to leave the application?");
// Setting Positive "Yes" Button
alertDialog.setPositiveButton("YES",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//I need to clear here all pwd data present in MainActivity in edittext
finish();
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("NO",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
In your MainActivity do like this:
#Override
public void onResume() {
super.onResume(); // Always call the superclass method first
editText.SetText("");
}
So, it will clear editText value, whenever your MainActivity will get resumed.
Or when you click the login button do
editText.SetText("");
Then it will be cleared before another activity starts
Using setText won't work and may even throw some type of NPE if your activity is no longer in memory.
There are a couple of ways you can do this depending on your requirements:
You can simply clear the text field in the activity/fragment's onStop or onDestroy overrides
If you absolutely have to set the text field from a different activity, then I suggest the following design:
In your Application class, create a nested class that implements ActivityLifeCycleCallbacks. This is a great class to implement as it allows you to monitor the state of all of your activities. It resolved a lot of problems for me
If you have a singleton model, or static String value that binds to your password TextView then you're almost there (other workarounds available if you give us more info).
So let's look at some code:
Design 1:
public void onStop()
{
super.onStop();
myTextField.setText("");
}
Your Application class:
public class MyApplication extends Application
{
...
private static final class MyActivityLifeCycleCallback implements ActivityLifecycleCallbacks
{
#Override
public void onActivityStopped(Activity activity)
{
//Here, I am assuming that your class name is MainActivity
Log.i(TAG, "onActivityStopped:" + activity.getLocalClassName());
if("MainActivity".isEqual(activity.getLocalClassName())
{
myDataModel.getInstance().setPassword("");
//or if your password String member is static
//((MainActivity)activity).myPasswordMember = "";
}
//Or if you want to only clear the password text when RAActivity stops, simply replace "MainActivity" with the RAActivity class name.
}
#Override
public void onActivityDestroyed(Activity activity,
Bundle savedInstanceState)
{
Log.i(TAG, "onActivityDestroyed:" + activity.getLocalClassName());
if(activity.getLocalClassName().contains("MySecondActivity"))
{
//reset your password here - implementation will depend on how you have your data model organized (private, singleton, static, etc.)
}
}
....
}
Remember that this design would work well with some type of a singleton or central data model (think MVC architecture) so that you can propagate the change in data to your components.
Hope it helps
EDIT:
I have added the code according to your comment. But to be honest, I think it's a better idea to simply call the setText("") method in the MainActivity's onStop function like I suggested. This is a simple problem and my second design might be a bit too much. Anyway, the code is updated, so if you like it, mark it as an answer :)
Here's another idea. IF RAActivity calls MainActivity again (probably not) using startActivity, you can simply pass a bundle value to MainActivity that tells it that it's coming from RAActivity. That way, MainActivity can clear the password if it was called from RAActivity. Lots of options.
I have a dialog with some UI elements in there. This dialog is created and shown at some point later on via show(). I can create the dialog with the default constructor Dialog(Context). But my content view is only set on onCreate which is called after show() function. This causes NPE when I try to modify UI elements like this:
public void showNumber(String number)
{
labelNumber.setText(number);
show();
}
But if call change the above function as below, it works most of the time. (Sometimes it fails if the phone gets slower because setContentView wouldn't be called by the time it executed setText)
public void showNumber(String number)
{
show();
labelNumber.setText(number);
}
How do you create the dialog and set content view without showing it at all. If I call setContentView() manually, it will be re-called when i call show() for the first time.
All you need to do is call create(); on the dialog when you construct it.
When you call show it will create the dialog only if create(); hasn't been called and then call onStart(); on the dialog. Finally it will attach the dialog to the window.
Something like:
Dialog myDialog = new Dialog(context) {
protected void onCreate() {
super.onCreate();
doYourThing
}
};
myDialog.create();
I'm assuming you're doing logic in onCreate, because, in Dialog it's just an empty method for subclasses to override.
onCreate:
http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/app/Dialog.java#37
show:
http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/app/Dialog.java#254
Pre API level 21 (if you can't use an AlertDialog.Builder) you should be able to use onRestoreInstanceState to do what you want to do, like this (this is a hack):
Bundle myBundle = new Bundle();
myBundle.putBoolean("android:dialogShowing", false);
myBundle.putBundle("android:dialogHierarchy", new Bundle());
myDialog.onRestoreInstanceState(myBundle);
Info:
http://androidxref.com/4.4_r1/xref/frameworks/base/core/java/android/app/Dialog.java#411
I want to launch a dialog with a custom layout, which I've implemented via a DialogFragment. (I basically just changed onCreateView() and added button handlers). The dialog lets the user quickly change an important setting.
This dialog will be launched from several different activities. The different activities don't have much in common, except that they need to refresh after the user makes a change to the setting. They don't need to get any information from the dialog; they merely need to know when it's closed (dismissed).
What I've Tried
I tried having the activity refresh in onResume(), but launching and dismissing a dialog never seems to call this method. (So I'm not sure why it even exists, but that's probably a topic for another question.)
Next, I tried adding a DialogInterface.OnDismissListener to the dialog:
public static void showMyDialog(OnDismissListener listener, Activity activity)
{
DialogFragment fragment = new MyDialogFragment();
fragment.show(activity.getFragmentManager(), "date");
activity.getFragmentManager().executePendingTransactions();//A
fragment.getDialog().setOnDismissListener(listener);//B
}
When I originally left out the line A, I got a NullPointerException on line B because the dialog is null at that point. Following the advice of this SO answer, I put in the call to executePendingTransaction(). This causes an IllegalStateException on line B, with the message "OnDismissListener is already taken by DialogFragment and cannot be replaced." I also tried putting setOnDismissListener() before the call to show(), but that always caused a NullPointerException.
I then read this other SO answer, which says the original asker was "calling getDialog() too early in the DialogFragment's life cycle." So I tried adding a constructor to my DialogFragment:
public MyDialogFragment(SomeCallback illTakeAnythingICanGet)
{
//I'll store the callback here and call it later
}
Unfortunately, adding a constructor made Android Lint freak out with a fatal warning, and when I looked it up, I found a comment in this question that seems to say this approach will make it impossible to deal with the user rotating the screen while the dialog is open.
The Question
How can an activity figure out when a DialogFragment has closed (been dismissed) in a way that won't break my app if the user rotates the screen? Should I be using something else besides a DialogFragment?
This is just a longer explanation of harism's comment in case anyone else has the same problem I did.
You can accomplish what I wanted by creating an interface like this:
public interface MyDialogCloseListener
{
public void handleDialogClose(DialogInterface dialog);//or whatever args you want
}
Have the activity that launches your dialog (DialogFragment) implement this interface. Then give that DialogFragment the following method:
public void onDismiss(DialogInterface dialog)
{
Activity activity = getActivity();
if(activity instanceof MyDialogCloseListener)
((MyDialogCloseListener)activity).handleDialogClose(dialog);
}
More explanatory code for someone to do the same.
Create the interface as:
package com.example.dialoglistener;
import android.content.DialogInterface;
public interface MyDialogCloseListener {
public void handleDialogClose(DialogInterface dialog);
}
Implement the interface in activity as:
MyDialogCloseListener closeListener = new MyDialogCloseListener() {
#Override
public void handleDialogClose(DialogInterface dialog) {
//do here whatever you want to do on Dialog dismiss
}
};
Write a DismissListener in DialogFragement as
public void DismissListener(MyDialogCloseListener closeListener) {
this.closeListener = closeListener;
}
call DismissListener from your activity as:
dialogFragementObject.DismissListener(closeListener);
and finally write onDismiss method
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if(closeListener != null) {
closeListener.handleDialogClose(null);
}
}
Tyler's example was the only example I could find that actually worked. The only thing that needs changed for the example to work is the call to the DismissListner method in the DialogFragment class. He has it as:
dialogFragementObject.DismissListner(closeListener);
This just needs to be a cast to whatever your class name of that DialogFragment is. For example:
((MyDialogFragment)dialogFragementObject).DismissListner(closeListener);
From activity 1, I open activity 2. Now when I am in the screen of activivty 2, I receive an event of activity 1 and onrecieve of that event i want to display a dialog. How can I do that??
While I am in activity 2 I dont see the dialog, but when I get back to activity 1, i see the dialog.
I want to see the dialog even when i am in screen of activity 2.
I looked into this link as well, but wasnt much helpful
Showing dialog on top of another running activity (Android)?
on receiving the reqd event, i call this method.
First create separate dialog in Activity 2 and do below mentioned
Try to send broadcast when data related to activity 1 is received.
Create a Receiver class which will listen the broadcast
Now you have to use of Observer Design pattern i.e. when ever there is some event in Receiver class it will inform Activity B that data is arrived and show the appropriate dialog.
Please share the result if it not succeeded.
in your first activity (splashScreen ) write this function to create alert box
public static void MyAlertBox(String title, String mymessage, Context context)
{
new AlertDialog.Builder(context)
.setMessage(mymessage)
.setTitle(title)
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
.
}
})
.show();
}
Declare global veriable :
public static Activity currentActivity= null;
in Every activity :
onResume() write "currentActivity=this ;"
Where you want to display alert just write :(activity 1)
SplashScreen.MyAlertBox("Alert",
"Alert box from activity 1",currentActivity );
hope it will work for you !!
It is possible, create a class, let's say a singleton, like this:
Class DialogDisplayer () {
singleton implementation...
weakReference context: Context
fun showDialog(whatever data if needed) {
dialogBuilder implementation ...
which uses the context from above, the rest you have
}
}
on onResume() of each activity use DialogDisplayer.context = this
and finally, show the dialog from using class, in your first activity
like this: DialogDisplayer.showDialog(whatever data if needed)
This way the class will always show the dialog with context of the current active activity. I didn't write all the correct syntax, just the idea. WeakReference to allow this class to be GC collected. Maybe there are better ideas but this should work.