After screen orientation change the dialogFragment appears apparently without any call - android

here there is part of the Activity where the screen orientation change:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.editText1);
et.setOnLongClickListener(new View.OnLongClickListener()
{
#Override
public boolean onLongClick(View v)
{
Fragment1 dialogFragment = new Fragment1();
dialogFragment.show(getFragmentManager(), null);
dialogFragment.setTextDialog(et.getText().toString());
return true;
}
});
}
Apparentely it seems that the dialog that will appear inside the DialogFragment should appear just after the onLongClick over the editText
(I know that when the screen orientation change the Activity is restarted, but it shouldn't start normally like the first time that is created?)
My problem:
when I open at least once the dialog and I close it, after the screen orientation change I have the dialog displayed again on the screen, like if I long-Clicked the editText.
I don't absolutely know why this happens.
I attach also the structure of dialog fragment:
public Dialog onCreateDialog(Bundle savedInstanceState)
{
final Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
LayoutInflater adbInflater = LayoutInflater.from(getActivity());
View eulaLayout = adbInflater.inflate(R.layout.dialog_crypt, null);
Button btn_OK = (Button) eulaLayout.findViewById(R.id.btnOK);
dialog.setContentView(eulaLayout);
final EditText et = (EditText)eulaLayout.findViewById(R.id.editText2);
et.setText(textDialog);
if(et.length()>0)
{
et.setText(et.getText().toString() + " ");
}
et.setSelection(et.length());
btn_OK.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
textDialog = et.getText().toString();
((Main)getActivity()).setTextOnEditText(textDialog);
dialog.dismiss();
}
});
return dialog;
}
Thanks so much for the help.

Try removing the dialog from stack using fragment manager instead of just dismissing it.
getFragmentManager().beginTransaction().remove(dialogFragment.this).commit();
By the way, instead of just using a Fragment for your dialog, you should use DialogFragment itself. Checkout: DialogFragment
Also, don't ever call your activity methods like this ( ((Main)getActivity()).setTextOnEditText(textDialog);
unless your fragment is a static inner class. Instead, create an interface to talk between fragments and activity.

When screen changes orientation, it calls onSaveInstanceState method, and it saves the state in the Bundle object including the stack. If you dismiss the dialog without clearing this stack, it will then show the dialog when you rotate the phone since this is in the saveInstanceState bundle.
You must clear dialog off the stack with:
getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
if you use support library for dialog fragment, or
getActivity().getFragmentManager().beginTransaction().remove(this).commit();

When a config change (like rotation) occurs the old Fragment isn't destroyed - it just adds itself back to the Activity when it's recreated (android retains fragments by default). So if you have your DialogFragment shown before rotation, it will instantly show up after rotation.

Related

Android custom Dialog not showing after FragmentActivity recreate

On my app i have a ViewPager inside FragmentActivity that contain a fragments. In one of that fragment (called FragOne) i have a button that on tap open a custom Dialog (a Class extends android.app.Dialog) on certain position of screen:
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MyCustomDialog = new MyCustomDialog(getContext());
dialog.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
dialog.getWindow().getDecorView().setSystemUiVisibility(
getActivity().getWindow().getDecorView().getSystemUiVisibility());
dialog.show();
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
dialog.getWindow().setLayout(myWidth, myHeight);
}
});
When user perform some action on dialog some tasks are executed, recreate() of FragmentActivity is called, then dialog dismiss itself.
Now happen that if try to open again the dialog by press the button, i can't see it anymore. For make dialog appear i need to go to change viewpager current visible fragment, then go back to FragOne.
How can i do for let open dialog again without change fragment and go back to FragOne?

DialogFragment dismiss() does not pop backstack

I have a simple DialogFragment that calls dismiss when exits, according to the documentation:
public void dismiss()
Dismiss the fragment and its dialog. If the fragment was added to the
back stack, all back stack state up to and including this entry will
be popped. Otherwise, a new transaction will be committed to remove
the fragment.
however, I found that the fragment is still on the backstack after calling dismiss() so I have to click back button to clear it. Does anyone know why ?
here's my code:
public void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.test_layout);
class MyDialogFragment extends DialogFragment implements OnClickListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.hello_world, container, false);
Button b = (Button)v.findViewById(R.id.btn);
b.setOnClickListener(this);
return v;
}
#Override
public void onClick(View v) {
dismiss();
}
}
getFragmentManager().beginTransaction().add(android.R.id.content, new MyDialogFragment(), "test").addToBackStack("b").commit();
}
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
}
I also found out that if I don't override onBackPressed(), the back button simple doesn't work, no matter how many fragments I add to the activity, the back button always exits the activity right away.
I can confirm what #Luksprog said in his comment: the dialog must be started through show(FragmentTransaction, String).
Note after looking the source: make sure to call addToBackStack(String) on the supplied transaction or else it still won't work.
That it's a wrong way to create a DialogFragment.
Never ever use the FragmentManager to show a DialogFragment. To be shown there are a method called show(FragmentTransacion, String).
In java:
MyDialogFragment mDialogFragment = new MyDialogFragment();
mDialogFragment.show(getFragmentManager(), "MyDialogFragment");
For another hand, to dismiss the dialog just do this:
mDialogFragment.dismiss()
Another think that I would like to highlight is that the MyDialogFragment class is defined inner onCreate method :'(
Please, define the class outside the method or in another file if you want :)
Good Look!
dismiss()
findNavController().navigate(FirstBottomSheetDialogDirections.actionFirstSheetToSecondSheet())
This code is always the wrong thing to do: dismiss() is an asynchronous operation that doesn't actually dismiss anything immediately. That is unlike the navigate() which does immediately update the NavController's state, stacking the new dialog destination on top of the previous one.
This means that when the asynchronous dismiss actually happens, it correctly removes the dialog and, because it is a navigation stack, removes everything on top of it - including your second dialog. However, due to a bug in the DialogFragmentNavigator, we don't actually dismiss that second dialog, which is why it appears to work, despite everything actually already being internally out of sync (thus causing the later crash).
The correct way to pop a destination and navigate to a new destination as an atomic, immediate operation is to use popUpTo and popUpToInclusive. Therefore you can fix the sample app by removing the call to dismiss() and updating the action to pop the first dialog as part of the navigate call:
<action
android:id="#+id/action_firstSheet_to_secondSheet"
app:destination="#id/secondSheet"
app:popUpTo="#id/firstSheet"
app:popUpToInclusive="true"/>
This correctly pops the first dialog off the back stack and then navigates to the new dialog destination.
please refer this link : https://issuetracker.google.com/issues/191073055

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();

Android: FragmentTransaction hide doesn't work for DialogFragment

I'm trying to add a
fragmentTransaction.hide(myDialogFragment);
fragmentTransaction.addToBackStack(null);
to a FragmentTransaction so that the dialog will re-appear when the user hits the back button, but it's not working. I originally overrode onCreateDialog in my DialogFragment, but I noticed that the documentation for the hide call on FragmentTransaction states:
This is only relevant for fragments whose views have been added to a
container.
So instead, now I'm overriding onCreateView. Now it sort of hides, but not really. The dialog merely shrivels, but the window still remains dark. I have to hit the back button to get rid of it, which is not the behavior I want, obviously. What am I missing here?
A DialogFragment maintains a dialog internally and calls show and hide methods on it according to its own lifecycle. Calling FragmentTransaction.hide() just tries to set the visibility of the fragment's view, as returned by Fragment.onCreateView(), to View.GONE. The view of the DialogFragment is coincidently the view used for its internal dialog, and so what you are doing is hiding the content on the dialog. Unfortunately, hiding the view does not 'dismiss' the dialog and so the screen will still be dimmed.
When you call DialogFragment.show(FragmentTransaction,String), a FragmentTransaction is created to add it to the FragmentManager. Ordinarily, showing the dialog is considered the 'active' transaction, and then dismissing it is just popping the back stack the appropriate number of times. If you did not add any other fragments in between, then a new FragmentTransaction is created with a remove operation. If we could access this, then we could just add a backstack entry and make this operation reversible. Unfortunately, this is not possible and so the best we can do is just to make our own dismiss method (and hope the internal state does not get too screwed up):
public class UndoDialogFragmentActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// show a dialog fragment in the normal way
new MyDialogFragment().show(getSupportFragmentManager(), "dialog");
}
});
}
private static class MyDialogFragment extends DialogFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(STYLE_NO_TITLE, getTheme());
// do not allow back button to dismiss dialog; confusing behaviour otherwise!
setCancelable(false);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Button button = new Button(getActivity());
button.setText("Dismiss");
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// pressing back after 'dismissing' the dialog will cause it to be added again
getFragmentManager().beginTransaction().remove(MyDialogFragment.this).addToBackStack(null).commit();
}
});
return button;
}
}
}
Clicking on the button in the fragment will cause a DialogFragment to be opened, with its own dismiss button. After pressing dismiss, you can show the dialog again by pressing the back key, undoing the remove operation. This produces somewhat questionable behaviour when you allow the back key to both show and hide the dialog, but the details can be decided by you according to your application.
I was able to hide a dialog of a DialogFragment by calling getDialog().hide() from within my DialogFragment.
If you're using API Level 11 or higher, you can simply call dismiss() on the DialogFragment, either from FragmentActivity or from DialogFragment itself.

Reset Android DialogFragment

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
}

Categories

Resources