I have an Activity which shows a DialogFragment when an event occurs in the Activity. When my application is running the user can press home button to make the app run in background. When app is running in background, as soon as the event occurs, the activity should show the DialogFragment, so that when user resumes the app the dialog should be on top of the activity, however I am not getting the results I want. As soon as I resume the app from launcher icon or notification, the dialog does not appear on the activity.
Here is my DialogFragment class:
public static class MyDialog extends DialogFragment {
public static DialogInterface.OnClickListener mListener;
public static String mTitle, mBody;
public static boolean mConfirm;
public static MyDialog getInstance(String body, boolean confirm,
DialogInterface.OnClickListener listener) {
mListener = listener;
mTitle = "MyDialog";
mBody = body;
mConfirm = confirm;
MyDialog fragment = new MyDialog();
return fragment;
}
#Override
public Dialog onCreateDialog(Bundle savedIntanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(mTitle).setMessage(mBody)
.setPositiveButton("Ok", mListener);
if (mConfirm)
builder.setNegativeButton("Cancel", mListener);
return builder.create();
}
}
The dialog works fine when activity is in foreground.
Here is how I show the dialog:
MyDialog.getInstance("This is dialog body text", true,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
// positive button pressed
}else //negative button pressed
}
}).show(getSupportFragmentManager(), "dialog");
I want a dialog that remains on the activity even if the activity is in background, and as soon as I resume the activity, the dialog should be on top of the activity. How can I achieve this behavior?
You can declare a global boolean to determine if you should show the dialog or not. Then in your activity onResume() method you show the dialog depending on the boolean value.
If the user is finished interacting with the dialog you can set this boolean to false which will cause it not to show again when your activity is in the foreground (onResume).
Try using Fragment's or Activity's showDialog(int) methods and your dialog will be retained automatically.
Related
I have a MainActivity containing 5 fragments, 2 of which have a help icon on the toolbar on top right. I have hidden this icon on other 3 fragments. Upon clicking help icon, an alert dialog shows up with title, message and a positive button.
This is my Alert Dialog code:
public class HelpDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Help");
builder.setMessage("Placeholder");
builder.setPositiveButton("Got It", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {}
});
return builder.create();
}
}
and this is how I am showing it from MainActivity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_help:
DialogFragment helpDialog = new HelpDialogFragment();
helpDialog.show(getSupportFragmentManager(), "dialogHelp");
return true;
}
return super.onOptionsItemSelected(item);
}
The above code works but I would like to show different message based on the fragment selected so how to change the message? I tried this to change title
helpDialog.getDialog().setTitle("Some Text");
Please note I want to change Dialog message, i.e main content, I only got setTitle() method on getDialog() and not setMessage(), the above setTitle is just for example purpose but even it is throwing NullPointerException.
As you can see in the above screenshot, "Placeholder" text is the default text I added at the time of creating AlertDialog but now how to change it?
From reading your post and comments it looks like you need to set different titles depending on whatever fragment is visible. And the creation of dialogs happens from Activity so you are not sure what title to set.
The problem is essentially identifying the visible fragment and set message according to it.
You can pass the message with arguments like this.
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putString(message, "My title");
fragment.setArguments(bundle);
Then in your Fragment, get the data (e.g. in onCreate() method)
Bundle bundle = this.getArguments();
if (bundle != null) {
String message = bundle.getString(message, defaultValue);
}
How to identify the currently visible fragment? You can do this as suggested in these answers. Once you get the current fragment, just send the message in the arguments above according to it.
By combining the above 2 ideas you can do this.
Another way would be to start the dialog from the fragment and not from the Activity but that would involve more changes so the above approach is better.
First pass the required message over a bundle while calling HelpDialogFragment class
HelpDialogFragment helpDialog = new HelpDialogFragment();
Bundle bundle = new Bundle();
bundle.putString("placeholder", "Custom placeholder");
helpDialog.setArguments(bundle);
helpDialog.show(getSupportFragmentManager(), "dialogHelp");
Now modify your HelpDialogFragment class create the dialog like this
public class HelpDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Help");
if (getArguments() != null)
builder.setMessage(getArguments().getString("placeholder",""));
builder.setPositiveButton("Got It", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {}
});
return builder.create();
}
}
I have an dialogfragment and its view consists of a simple seekbar and positive and negative buttons. When I dismiss dialogfragment onclick, a new dialogfragment is created and showed. After second click on button, dialog is dismissed, but my desire is dismissing after first click. Also I should note that my activity hosts two fragments and I call dialog.show() from first fragment.
MyListFragment.java
FragmentManager manager = getFragmentManager();
fndSrchFragment dialog = new fndSrchFragment();
dialog.setTargetFragment(MyListFragment.this, REQUEST_COLOR);
dialog.show(manager, SRCH_FND);
fndSrchFragment.java
public class fndSrchFragment extends DialogFragment {
.
.
//variable definition
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.color_picker, null);
rSb=(SeekBar) view.findViewById(R.id.r_seek_bar);
.
.
//code for interacting with seekbar
.
.
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
int ccolor = android.graphics.Color.rgb(rComponent, gComponent, bComponent);
sendResult(Activity.RESULT_OK, ccolor);
// two click is needed for dismiss which I don't know why?
dismiss();
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// two click is needed for dismiss which I don't know why?
dismiss();
}
});
return builder.create();
}
Thank You in Advance.
Set up a log command inside your onMenuItemActionExpand(). I bet you'll see this method is called right after you dismissed the dialog. Most likely, this method is being called by the system once focus is returned from the dialog to the activity. You should but your call to dialog.show() inside a something like onOptionsItemSelected(MenuItem item) instead.
I have a Dialog prompt in mainActivity. If user close the Dialog, I need to show red dot to one of the ListView items inside fourthFragment(as per redbox in fourthFragment in image below).
The problem is the red dot only be updated after I close the app and reopened it, because fourthFragment already done created BEFORE user close the Dialog. How can I refresh/update the fourthFragment after Dialog closed so that red dot can be shown immediately?
short description:
mainActivity: on Dialog closed > store showRedDot="1" to local db
fourthFragment: onCreate > read showRedDot from local db, if "1", show red dot. ( problem here, when onCreate, showRedDot is still "0", so I need to update fourthFragment layout after dialog closed.)
Try Interface or Broadcast receivers as above. If else refresh the fragment as
// Reload current fragment
Fragment frg = null;
frg = getSupportFragmentManager().findFragmentByTag("Your_Fragment_TAG");
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.detach(frg);
ft.attach(frg);
ft.commit();
You have calling a interface to push event dismiss(button click) of dialog.
Like this:
public interface MyDialogListener {
void OnCloseDialog();
}
public class fourthFragment extend Fragment implements MyDialogListener {
public void SomeMethod() {
MyDialog myDialog = new MyDialog(this, this);
myDialog.show();
}
public void OnCloseDialog() {
// Do update your listview in here( maybe call method initialize data for listview)
}
}
public class MyDialog extends Dialog {
MyDialogListener mListener;
public MyDialog (Context context, MyDialogListener listener) {
super(context, R.style.Dialog);
mListener = listener;
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.CloseButton:
// Push event when Dialog close(or anything)
mListener.OnCloseDialog();
dismiss()
break;
default:
//...
}
}
}
I have toolbar where a have a menu. In that menu I have lots of options, one of them, when is pressed open an alertDialog with a RadioButtonGroup (with a setSingleChoiceItems) where the user can choose a property. After user choose the property and clicks on OK button of that AlertDialog I return to my Activity which was in background.
The problem is that after user choose the property in alertDialog and clicks in OK button (alertDialog disappears as normal) the textViews of my activity (that which is on the background) should change (according to the property chosen by user) and they are not changing.
All my activities (that can run in background while the user choose the property in alertdialog) extends an activity I have with the all events of Toolbar (including choose that property, share app, etc). I mean I have an activity for all things relate to toolbar menu. Every time user choose a different property I save it in database for then I could read it.
How can I do for when user choose a value of that property, the texviews of my background activity change? (I thought with the onResume it was easy to do, but it doesn't work.). Thanks
Please check if the screenshot helps you to understand my problem.In red what I want to change.
I don't think a dialog changes the activity stack, meaning onPause/onResume are not called.
As #sahu commented you can determine that your dialog closed in the positive/negative buttons:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Do it?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.dismiss();
// change your textviews
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.dismiss();
// cancel pressed, probably don't need to do anything
}
});
builder.create().show();
}
EDIT:
If your dialog code is in a different class you will need to add an interface to communicate from the toolbar back to your activity. This is not much different than fragment to activity communication:
http://developer.android.com/training/basics/fragments/communicating.html
In your toolbar you will need to define an interface that your activity can call.
public class MyToolbar extends Toolbar {
OnInfoChangedListener mCallback;
// Don't forget to call this from your activity to setup the listener
public setOnInfoChangedListener(OnInfoChangedListener callback) {
mCallback = callback;
}
// Container Activity must implement this interface
public interface OnInfoChangedListener {
// you can add arguments here as needed
public void onInfoChanged();
}
...
}
Then in your setPositive button tell your activity that the info changed:
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.dismiss();
if (mCallback != null) mCallback.onInfoChanged();
// change your textviews
}
})
Then in your activity:
public static class MainActivity extends Activity
implements OnInfoChangedListener {
...
#Override
public void onCreate(bundle) {
super.onCreate(bundle);
Toolbar toolbar = // get the toolbar;
toolbar.setOnInfoChangedListener(this); // set myself as listener
}
public void onInfoChanged() {
// The user selected something from your toolbar
// update your views
}
}
You can define your interface to pass whatever you want from your toolbar into your activity, this is just a simple 'hey something changed notification'.
try
radiogroup.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId)
{
switch(checkID)
case 0: textview.setText("your text");
break;
...
it may help !
I am using a custom DialogFragment to let a user change his login credentials. There are some text fields and two buttons (save/cancel). The layout is set in DialogFragment's onCreateView method.
If I open the dialog text fields are filled with default values. When the user changes text in a text field and clicks the cancel button the dialog is dismissed. Next time the dialog opens the text field changed before does not contain the default value as i expected but the text the user changed before. The text fields are not reset. This is almost the same problem mentioned here Reset an Android Dialog. The problem is that the solution provided refers to a Dialog which is deprecated in API level 11 and i cannot use onPrepareDialog with a DialogFragment.
Is there a similar way to reset the content of a DialogFragment?
You can override onResume() in your class, which extends DialogFragmet, as follows:
private static class MyDialogFragment extends DialogFragment {
public static MyDialogFragment newInstance() {
// ...
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// ...
}
#Override
public void onResume() {
super.onResume();
Dialog dialog = getDialog();
// reset code goes here - use dialog as you would have in onPrepareDialog()
}
}
You can also use .setText() method in Your activity as reaction after negative button click. Eg:
In DialogFragment.java, onCreateDialog(...)define AlertDialog.Builder
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
then
//this is better than creating button in layout
builder.setNegativeButton(R.string.button_cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
((MainAct) getActivity()).cancelDialog(DialogFragment.this);
}
}
);
In MainActivity.java create method cancelDialog(DialogFragment df) {
//here use df to reset text fields
}