Reset Android DialogFragment - android

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
}

Related

Android Navigation Component not working with Dialog Fragments

Disclaimer: I've checked the documentation and since 2.1.0 the navigation components has supported Dialog Fragments. (https://developer.android.com/jetpack/androidx/releases/navigation#2.1.0)
Error That I'm Getting
I'm getting this error when trying to go from a DialogFragment to my Start Destination:
java.lang.IllegalStateException: Fragment PostDistressDialog{829f5d1} (bbbc4926-684b-491b-9772-e0f0ffebe0af)} not associated with a fragment manager.
PostDistressDialog is a DialogFragment called from JournalEntryFragment(can be seen in map below) using the navigation component. PostDistressDialog is not an inner class of JournalEntryFragment. It is in a class of its own extending DialogFragment
Picture of my Navigation Graph
Function Calling NavController
public class PostDistressDialog extends DialogFragment implements ISaveDatabase {
...
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
if (getArguments()!=null) {
...
// Set up the Alert Dialog
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
alertDialog.setTitle(R.string.distressed_levels);
alertDialog.setMessage(R.string.distressed_how_feel_post);
// Inflate and set the layout for the dialog
View layout = View.inflate(getActivity(), R.layout.dialog_seekbar, null);
alertDialog.setView(layout);
....
// Add okay button
alertDialog.setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Save post distress value in Journal Entry
mJournalEntry.setPostDistress(mTempDistressValue);
// Save to Journal Entry to database
// Check if journal entry empty
if(isJournalEntryEmpty(mJournalEntry)){
...
}
else{
// Give title if empty
if(mJournalEntry.getTitle().isEmpty()) {
....
// Save to database
new SaveDatabase(getContext(),PostDistressDialog.this).execute(mJournalEntry);
}
// Go to main menu
}
});
return alertDialog.create();
}
return null;
}
...
#Override
public void databaseSavingCompleted(){
NavHostFragment.findNavController(this).navigate(PostDistressDialogDirections.postDistressDialogToJournalListAction());
}
}
Where this is public class PostDistressDialog extends DialogFragment
Dialog in my Navigation XML File
<dialog
android:id="#+id/postDistressDialog"
android:name="com.dgrullon.cbtjourney.dialogs.PostDistressDialog"
android:label="PostDistressDialog" >
<argument
android:name="postDistressDialogArguments"
app:argType="com.dgrullon.cbtjourney.pojo.JournalEntries"/>
<action
android:id="#+id/postDistressDialog_to_journalListAction"
app:destination="#id/journalList"
app:popUpTo="#id/journalList"
app:popUpToInclusive="true" />
</dialog>
AlertDialog automatically dismisses the Dialog (and hence, removes your DialogFragment) when the callback you add to setPositiveButton is fired. Because you're doing work asynchronously, your databaseSavingCompleted method is called after the DialogFragment is destroyed, detached from the FragmentManager, and removed from the NavController - you're leaking a reference to your DialogFragment (as it would otherwise be garbage collected).
Therefore when NavHostFragment.findNavController(this) fires, all hooks that would let it access the NavController are already cleaned up.
If you don't want your button to immediately dismiss the dialog, you need to pass in null to setPositiveButton() and instead get a reference to the button after the dialog has been created by calling its getButton() API and manually setting an OnClickListener that would kick off your AsyncTask (and disable the button to prevent it from being clicked more than once).

Dismiss DialogFragment onClick not working properly

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.

Change textview after select an option in a RadioButtonGroup

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 !

what is correct approach to perform UI related task when a dialog gets dismissed

I have a dialog with onDismiss handler:
public class TextReaderDialog extends DialogFragment {
...
public void onDismiss() {
}
I show this dialog and add some styles to a part of text from the fragment:
TextReaderDialog d = new TextReaderDialog();
d.show(getFragmentManager(), "sample");
Spannable spannableText = new SpannableString(tv.getText());
spannableText.setSpan(new BackgroundColorSpan(Color.LTGRAY), startOffset, startOffset + w.word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(spannableText);
Whenever a dialog is dismissed, I want to remove styles from the text. How can I do that? What is the correct way to do that?
The simplest way to go about this would be to add a method to your fragment like so:
public void dismissStyles(){
//do your style dismissing here
}
Now, I assume in the dialog you are overriding DialogFragment.onDismiss(DialogInterface dialog). As long as that is the case, once you have completed that method, in your dialog's onDismiss function, you can do something to the effect of:
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
MyFragment fragment = (MyFragment) activity
.getFragmentManager()
.findFragmentByID(R.id.containerOfYourFragment);
if(fragment != null){
fragment.dismissStyles();
}
}
Here, activity should be the current activity that your fragment and dialog are hosted in. You can pass this to the dialog in a constructor, or depending on where the dialog is located. You could also just pass the current fragment to the dialog in the constructor as well, and then it would simply be called by myFragment.dismissStyles();.

Issue while displaying Dialog on Android Fragment

The following code displays date picker(as a popup dialog) when the user clicks on an EditText . showDialog() calls onCreateDialog(). The code works fine except when it is implemented in a Fragment. In Fragment , the dialog is not getting displayed.
edtTxtDateTime.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showDialog(DATE_DIALOG_ID);
}
});
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DATE_DIALOG_ID:
// Displaying Date & Time as a dialog
}
return null;
}
I have tried to implement the same behaviour using DialogFragment API , but am unable to get the dialog when EditText is clicked.
Any suggestions / hints will be helpful.
Make sure you're using the correct context to display the dialog within your Fragment code. You need to be using the parent Activity's context. Within your Fragment, you can get the Activity (and correct context) by calling:
getActivity();

Categories

Resources