1) In my application, the user may receive a lot of notifications from FCM
2) If the user has an application open, he needs to display the custom DialogFragment
3) If the DialogFragment is already displayed, then the next time the notification arrives, it is necessary to prohibit the repeated display of this DialogFragment
4) My dialogue code:
public final class NotificationEventDialog extends DialogFragment implements DialogInterface.OnKeyListener, View.OnClickListener {
private Activity mCurrentActivity;
private NotificationEventDialogListener mNotificationEventDialogListener;
public interface NotificationEventDialogListener {
void showEvent();
}
public NotificationEventDialog() {
}
public static NotificationEventDialog newInstance() {
NotificationEventDialog notificationEventDialog = new NotificationEventDialog();
notificationEventDialog.setCancelable(false);
return notificationEventDialog;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mCurrentActivity = (Activity)context;
try {
mNotificationEventDialogListener = (NotificationEventDialogListener) mCurrentActivity;
} catch (ClassCastException e) {
throw new ClassCastException(mCurrentActivity.toString() + " must implemented NotificationEventDialogListener");
}
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(mCurrentActivity);
#SuppressLint("InflateParams") View view = inflater.inflate(R.layout.dialog_notification_event, null);
Button btnNotificationEventYes = view.findViewById(R.id.notification_event_dialog_yes);
btnNotificationEventYes.setOnClickListener(this);
Button btnNotificationEventNo = view.findViewById(R.id.notification_event_dialog_no);
btnNotificationEventNo.setOnClickListener(this);
AlertDialog.Builder builder = new AlertDialog.Builder(mCurrentActivity);
builder.setView(view);
return builder.create();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
if (getDialog() != null && getDialog().getWindow() != null) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().setOnKeyListener(this);
}
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onDetach() {
super.onDetach();
mCurrentActivity = null;
mNotificationEventDialogListener = null;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.notification_event_dialog_yes:
dismiss();
mNotificationEventDialogListener.showEvent();
break;
case R.id.notification_event_dialog_no:
dismiss();
break;
}
}
#Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
dismiss();
return true;
} else return false;
}
}
5) Each time I receive a notification from FCM, I create a dialog box:
DialogFragment notificationEventDialog = NotificationEventDialog.newInstance();
notificationEventDialog.show(getSupportFragmentManager(), "");
6) How to check if DialogFragment is already displayed? Every time I create a new object of this window and I cannot make it as Singleton, because This leads to a memory leak.
Found an answer in which a person suggests using Weak links to solve this problem:
Also you can store a weak link to the shown dialog in that singletone
class. Using such method, you can detect is your dialog currently
shown or not.
There was also such an answer:
I suggest to save link to the dialog in single instance class. In that
instance create method ensureShowDialog(Context context). That method
would check is current shown dialog or not. If yes, you can show the
dialog. In another casr you can pass new data you to the dialog.
But, honestly, I can’t quite understand how to use these tips in practice. Please can help with this realization or suggest another way? Thanks in advance.
You can use:
val ft: FragmentTransaction = fragmentManager!!.beginTransaction()
val prev: Fragment? = fragmentManager!!.findFragmentByTag("typeDialog")
if (prev == null) {
val fm = fragmentManager
val courseTypeListDialogFragment =
CourseTypeListDialogFragment()
courseTypeListDialogFragment.isCancelable = false
courseTypeListDialogFragment.setStyle(
DialogFragment.STYLE_NO_TITLE,
0
)
courseTypeListDialogFragment.setTargetFragment(this, 1)
if (fm != null) {
courseTypeListDialogFragment.show(ft, "typeDialog")
}
}
You can check if dialog fragment is showing by calling isAdded () inside DialogFragment or by
DialogFragment notificationEventDialog = NotificationEventDialog.newInstance();
notificationEventDialog.isAdded()
from activity
It will return true if fragment is added to an Activity, in case of dialog fragment - is shown.
You can store last shown dialog fragment date via putting System.currentTimeMillis() in SharedPreferences
I think you'v got the idea.
Related
I have an AppCompatActivity that, at some point, display a DialogFragment. In this dialog, there are items for which I ask confirmation before deleting them. That confirmation is asked through another Yes/No DialogFragment. When the user clicks Yes in that second dialog, I want the first dialog to refresh its ListView (just need to update the adapter and call its notifyDataSetChanged method). The problem is that I don't know when to update the listview.
Because that delete functionality is called from various sources, I implement a listener Interface at the activity level and call an "onDeleteRequest" event from that interface whenever I need an item to be deleted, and that's the activity who opens up the confirmation dialog and perform the actual delete.
Since I don't care much about refreshing the ListView in unnecessary situations, I tried to update the list in the onResume event, but the event is not called when I come back to the first dialog after the confirmation one is dismissed.
So my question is: how can I know when a dialog B displayed on top of a dialog A has been dismissed so I can refresh dialog A accordingly?
EDIT : A bit of code to support my question:
My activity class:
public class MonthActivity
extends AppCompatActivity
implements OnEditCalendarsDialogListener
{
...
//That's where dialog A is shown
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
...
if (id == R.id.action_select_calendar) {
final CalendarSelection currentSelection = mCalendarSelectionAdapter.getCurrentCalendarSelection();
if (currentSelection != null) {
EditCalendarsDialogFragment dialogFragment = EditCalendarsDialogFragment.newInstance(currentSelection);
dialogFragment.show(getSupportFragmentManager());
}
return true;
}
return super.onOptionsItemSelected(item);
}
...
//OnEditCalendarsDialogListener interface implementation
//That's where Dialog B is shown over Dialog A
#Override
public void onEditCalendarsDialogDelete(long calendarID) {
final Repository repository = Repository.getInstance(this);
final Calendar calendar = repository.fetchOneByID(Calendar.class, calendarID);
if (calendar != null) {
YesNoDialog yesNoDialog = YesNoDialog.newInstance(this, R.string.yes_no_dialog_confirmation, R.string.yes_no_dialog_calendar_delete);
setCurrentOnDecisionClickListener(new OnPositiveClickListener() {
#Override
public boolean onPositiveClick(DialogInterface dialog) {
//Delete calendar
repository.delete(calendar);
//That's where I'd like to notify Dialog A that it needs to be refreshed
return true;
}
});
yesNoDialog.show(getSupportFragmentManager());
}
}
}
My dialog class
public class EditCalendarsDialogFragment
extends DialogFragment
{
private OnEditCalendarsDialogListener mDialogListener;
public static EditCalendarsDialogFragment newInstance(CalendarSelection calendarSelection) {
EditCalendarsDialogFragment dialog = new EditCalendarsDialogFragment();
Bundle arguments = new Bundle();
if (calendarSelection != null) {
arguments.putLong(KEY_ID, calendarSelection.getID());
}
else {
arguments.putLong(KEY_ID, 0L);
}
dialog.setArguments(arguments);
return dialog;
}
...
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mDialogListener = (OnEditCalendarsDialogListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnCalendarSelectionDialogListener");
}
}
...
private View getLayoutView() {
View rootView = getActivity().getLayoutInflater().inflate(R.layout.calendar_list, null, false);
if (rootView != null) {
mCalendars = (ListView) rootView.findViewById(R.id.calendars);
if (mCalendars != null) {
//Create adaptor
mCalendarAdapter = new ArrayAdapter<Calendar>(
getContext(),
android.R.layout.simple_list_item_2,
android.R.id.text1,
new ArrayList<Calendar>()
) {
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = super.getView(position, convertView, parent);
final Calendar calendar = getItem(position);
if (calendar != null && calendar.hasID()) {
...
view.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (mDialogListener != null) {
//That's where I request delete from calling activity
mDialogListener.onEditCalendarsDialogDelete(calendar.getID());
}
return true;
}
});
}
return view;
}
};
mCalendars.setAdapter(mCalendarAdapter);
refreshCalendarList();
}
}
return rootView;
}
}
Use EventBus.
Register your dialog A to listen to events. When you dismiss dialog B post an event and pass the listitem's adapter position or whatever data you want to use to identify which item is to be deleted. Inside your dialog A write a function to receive this event inside which you delete the item.
OK, so I finally used the "over-abusive-callback" method.
I created the following interface:
public interface OnDeletedListener {
void onDeleted();
}
Updated the OnEditCalendarsDialogListener interface so that the callback has a callback to this interface too:
public interface OnEditCalendarsDialogListener {
void onEditCalendarsDialogDelete(long calendarID, OnDeletedListener onDeletedListener);
}
Implemented the OnDeletedListener interface in "Dialog A" class:
public class EditCalendarsDialogFragment
extends DialogFragment
implements OnDeletedListener
{
...
//OnDeletedListener interface implementation
#Override
public void onDeleted() {
//That's where I'm called back after item is deleted
refreshCalendarList();
}
...
private View getLayoutView() {
...
view.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
if (mDialogListener != null) {
//That's where I request delete from calling activity, asking to call me back once deleted
mDialogListener.onEditCalendarsDialogDelete(calendar.getID(), EditCalendarsDialogFragment.this);
}
return true;
}
});
...
}
}
And finally, call the callback when delete is accepted and performed:
public class MonthActivity
extends AppCompatActivity
implements OnEditCalendarsDialogListener
{
//OnEditCalendarsDialogListener interface implementation
//That's where Dialog B is shown over Dialog A
#Override
public void onEditCalendarsDialogDelete(long calendarID, final OnDeletedListener onDeletedListener) {
final Repository repository = Repository.getInstance(this);
final Calendar calendar = repository.fetchOneByID(Calendar.class, calendarID);
if (calendar != null) {
YesNoDialog yesNoDialog = YesNoDialog.newInstance(this, R.string.yes_no_dialog_confirmation, R.string.yes_no_dialog_calendar_delete);
setCurrentOnDecisionClickListener(new OnPositiveClickListener() {
#Override
public boolean onPositiveClick(DialogInterface dialog) {
//Delete calendar
repository.delete(calendar);
//That's where I notify Dialog A that it needs to be refreshed
if (onDeletedListener != null) {
onDeletedListener.onDeleted();
}
return true;
}
});
yesNoDialog.show(getSupportFragmentManager());
}
}
}
Works smoothly!
I have a custom DialogFragment, which contains two DatePicker widgets (from and to, using layout/custom_date_picker).
I need change the layout of dialogFragment when the screen is rotated to landscape (using layout-land/custom_date_picker).
The configuration of the Activity is :
<activity
android:name=".activities.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTop"/>
The implemented DialogFragment source is:
public class DatePickerDialog extends DialogFragment
{
public static final String START_SEARCH_DATE = "startSearchDate";
public static final String END_SEARCH_DATE = "endSearchDate";
private CustomDatePicker dpStartDate;
private CustomDatePicker dpEndDate;
private AlertDialog d;
public interface DatePickerDialogListener
{
void onFinishDatePickDialog(String fromDate, String toDate);
}
public DatePickerDialog()
{
}
// Use this instance of the interface to deliver action events
DatePickerDialogListener mListener;
// Override the Fragment.onAttach() method to instantiate the DatePickerDialogListener
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
// Verify that the host activity implements the callback interface
try
{
// Instantiate the NoticeDialogListener so we can send events to the host
mListener = (DatePickerDialogListener) activity;
} catch (ClassCastException e)
{
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString() + " must implement DatePickerDialogListener");
}
}
public static DatePickerDialog newInstance(String startSearchDate, String endSearchDate)
{
DatePickerDialog frag = new DatePickerDialog();
Bundle args = new Bundle();
args.putString(START_SEARCH_DATE, startSearchDate);
args.putString(END_SEARCH_DATE, endSearchDate);
frag.setArguments(args);
return frag;
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
View customView = getActivity().getLayoutInflater().inflate(R.layout.custom_date_picker, null);
// Define your date pickers
dpStartDate = (CustomDatePicker) customView.findViewById(R.id.dpStartDate);
dpEndDate = (CustomDatePicker) customView.findViewById(R.id.dpEndDate);
String startSearchDate = getArguments().getString(START_SEARCH_DATE);
String endSearchDate = getArguments().getString(END_SEARCH_DATE);
dpStartDate.updateDate(startSearchDate);
dpEndDate.updateDate(endSearchDate);
d = new AlertDialog.Builder(getActivity())
.setView(customView)
.setTitle(getString(R.string.datepicker_hint))
.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which)
{
}
}) //Set to null. We override the onclick
.setNegativeButton(getString(R.string.cancel), null)
.create();
d.show();
d.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
boolean b = DateUtils.largerThanEndDate(dpStartDate, dpEndDate);
if (b)
{
ToastUtils.showShortText(getActivity(), getString(R.string.date_error));
} else
{
mListener.onFinishDatePickDialog(dpStartDate.getDate(), dpEndDate.getDate());
dismiss();
}
}
});
return d;
}
}
Can anyone please guide me as to how this can be done ? Thanks in advance.
Edit:
Here the code with which I invoke the DialogFragment:
public void showDatePicker()
{
startSearchDate = dateModel.getStartDate();
endSearchDate = dateModel.getEndDate();
datePickerDialog = (DatePickerDialog)fragmentManager.findFragmentByTag(DATE_PICKER_DIALOG);
if (alertDialog == null)
{
alertDialog = DatePickerDialog.newInstance(startSearchDate, endSearchDate);
alertDialog.show(fragmentManager, DATE_PICKER_DIALOG);
}
}
I suppose you could consider using an if clause in your onCreate() as follows:
int rotation = getWindowManager().getDefaultDisplay().getRotation();
and then do
switch(rotation){
case Surface.ROTATION_0:
case Surface.ROTATION_180:
// show portrait
case Surface.ROTATION_90:
case Surface.ROTATION_270:
// show landscape
}
For portrait mode, show the two dialogs stacked. And for landscape mode, show them side-by-side.
EDIT:
Answering point-wise:
When the phone is rotated, the Activity is necessarily re-created.
This means that onCreate() will be called on rotation. Hence, the rotation state can be determined in onCreate() as shown above. In this case, make rotation a class member field so that it can be accessed throughout the class.
Indeed, as you correctly point out, the dialog can be shown from either onConfigurationChanged() or in onCreate() itself. For this, and for how to save the instance state, please see the attached links.
References:
1. How to properly retain a DialogFragment through rotation?.
2. Why won't Fragment retain state when screen is rotated?.
I created a DialogFragment which should be shown after onActivityResult is called.
But right after dialog.show() is called, the Dialog dismissed automatically for no reason.
I am using the BarcodeScanner lib to scan a QR-Code, in onActivityResult I just save the Data (I also tried to show the Dialog at this point, but it didn't worked.)
if ((requestCode == REQUEST_BARCODESCANNER) && (resultCode == RESULT_OK)) {
mBarcodeScanned = true;
mBarcodeScanResult = getBarcodeScannerResult(data.getExtras());
}
in onResume I am checking now for this variables:
if(mBarcodeScanResult == null && mBarcodeScanned){
mBarcodeScanned = false;
showDialog(MyDialogFragment.getInvalidQrCodeDialog(this));
} else if(mBarcodeScanResult != null && mBarcodeScanned){
showDialog(MyDialogFragment.getSomeDialog(this, v1, v2));
}
in showDialog() I just call show:
dialog.show(getSupportFragmentManager(), MyDialogFragment.class.getSimpleName());
Now it should show the Dialog, if a QR-Code was scanned.
For some reason right after dialog.show() I checked onDismiss() inside of the MyDialogFragment class, and it was called as well, but I really don't know why?
The MyDialogFragment is using the onCreateDialog methode, which creates AlertDialogs to return. The methode getSomeDialog() and getInvalidQrCodeDialog() are just instanciate the Fragment.
EDIT: the MyDialogClass
public class MyDialogFragment extends DialogFragment {
private static final String BUNDLE_DIALOG_TYPE = "bundle_dialog_type";
private DialogType mDialogType;
public enum DialogType{
QR_CODE_INVALID, SOME_DIALOG
}
public static Fragment getInvalidQrCodeDialog(final Context context) {
Bundle args = new Bundle();
args.putString(BUNDLE_DIALOG_TYPE, DialogType.QR_CODE_INVALID.name());
return MyDialogFragment.instantiate(context, MyDialogFragment.class.getName(), args);
}
public static Fragment getSomeDialog(final Context context) {
Bundle args = new Bundle();
args.putString(BUNDLE_DIALOG_TYPE, DialogType.SOME_DIALOG.name());
return MyDialogFragment.instantiate(context, MyDialogFragment.class.getName(), args);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handleArguments();
}
private void handleArguments() {
final Bundle arguments = getArguments();
if(arguments != null) {
mDialogType = DialogType.valueOf(arguments.getString(BUNDLE_DIALOG_TYPE, DialogType.SOME_DIALOG.name()));
}
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
switch(mDialogType){
case QR_CODE_INVALID: return DialogHelper.showQRCodeInvalidDialog(getActivity());
case SOME_DIALOG: return DialogHelper.showSomeDialog(getActivity());
default: return null;
}
}
}
and the DialogHelper does something like this:
public static AlertDialog showQRCodeInvalidDialog(final Context context){
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(R.string.barcode_invalid);
builder.setTitle(R.string.barcode_invalid_title);
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}
The problem seems to be the support-package DialogFragment.
I just changed it from support to the original DialogFragment and everything worked like expected.
I have an activity and a fragment inside it.inside fragment, there is a button, and on click of button a dialog shows.
Everything works, until user do a orientation change and click button after it.
IllegalStateException(cannot perform this action after onsaveinstancestate) occurs when user clicks button after orientation change. I'm using android support framework.
Anybody have any idea regarfing this?
Activity Code
public void openMoreDialog(String shareData, String link) {
DialogFragment dialog = new MoreDialog(shareData, link);
dialog.show(getSupportFragmentManager(), "MoreDialog");
}
Fragment Code
public void onAttach(Activity activity) {
super.onAttach(activity);
mControl = (ActivityControl)activity;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
ImageButton moreButton = (ImageButton)v.findViewById(R.id.moreButton);
moreButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mControl.openMoreDialog(shareData, link);
}
});
return rootView;
}
FragmentDialog code
public class MoreDialog extends DialogFragment {
private String mShareData;
private String mLink;
public MoreDialog(String shareData, String link){
mShareData = shareData;
mLink = link;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
View dialogView = inflater.inflate(R.layout.more_dialog, null);
Button openBtn = (Button)dialogView.findViewById(R.id.openBtn);
openBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
openLink(mLink);
}
});
Button shareBtn = (Button)dialogView.findViewById(R.id.shareBtn);
shareBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
shareNews(mShareData);
}
});
builder.setView(dialogView);
return builder.create();
}
private void openLink(String link){
}
private void shareNews(String data){
}
}
Helpful link & solution how to:
https://stackoverflow.com/a/17413324/619673 and btw, constructor in fragment must be empty! Documentation:
http://developer.android.com/reference/android/app/Fragment.html
public Fragment ()
Added in API level 11
Default constructor.
Every fragment must have an empty constructor, so
it can be instantiated when restoring its activity's state. It is
strongly recommended that subclasses do not have other constructors
with parameters, since these constructors will not be called when the
fragment is re-instantiated; instead, arguments can be supplied by the
caller with setArguments(Bundle) and later retrieved by the Fragment
with getArguments().
Applications should generally not implement a constructor. The first
place application code an run where the fragment is ready to be used
is in onAttach(Activity), the point where the fragment is actually
associated with its activity. Some applications may also want to
implement onInflate(Activity, AttributeSet, Bundle) to retrieve
attributes from a layout resource, though should take care here
because this happens for the fragment is attached to its activity.
I have a DialogFragment that displays a list of options to the user, one of these options is "Delete" option, when the user presses the delete option I want to show another DialogFragment as a confirmation, unfortunately, the confirmation dialog doesn't show.
here is my code
First Fragment code
public class ContactDialogOption extends SherlockDialogFragment {
public static final String TAG = ContactDialogOption.class.getSimpleName();
public ContactDialogOption() {
super();
// TODO Auto-generated constructor stub
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIcon(R.drawable.ic_launcher);
builder.setTitle(R.string.options);
builder.setItems(new String[] {
getString(R.string.call), getString(R.string.send_message),
getString(R.string.copy), getString(R.string.edit),
getString(R.string.delete)
}, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if(which == 4) //delete
{
FragmentManager mgr = getActivity().getSupportFragmentManager();
FragmentTransaction ft = mgr.beginTransaction();
Fragment old = mgr.findFragmentByTag("SecondFragment");
if (old != null) {
ft.remove(old);
}
ft.addToBackStack(null);
fragment.show(ft, fragmentTag);
}
}
});
return builder.create();
}
}
I got the exact same problem, this situation does not happen when you try to open a DialogFragment from a Fragment.
The only solution I found was to modify the following call:
fragment.show(ft, fragmentTag);
To:
fragment.show(getFragmentManager(), fragmentTag);
The problem with this solution is that we cannot work on the FragmentTransition.
I don't understand why the behavior is different than with the fragments.
I came across the same problem of not being able to show another DialogFragment from within the positive and negative click listeners of the first DialogFragment. My solution was to immediately pop the first fragment, which allows the second DialogFragment to attach and display successfully.
// Call this before adding the second dialog fragment
activity.getSupportFragmentManager().popBackStackImmediate();
Please check this following code. Hope this will help many of you!
public class SubcategoryFragment extends DialogFragment {
public SubcategoryFragment() {
}
public static SubcategoryFragment newInstance(Integer code, String name) {
SubcategoryFragment fragment = new SubcategoryFragment();
mCode = code;
mTitle = name;
return fragment;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
liststring = new ArrayList<>();
getAdapter();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_subcategory, container, false);
gridView = (GridView) view.findViewById(R.id.sub_grid);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
closeDialog = (ImageView) getDialog().findViewById(R.id.closeDialog);
title = (TextView) getDialog().findViewById(R.id.dialogTitle);
gridView = (GridView) getDialog().findViewById(R.id.sub_grid);
title.setText(String.format("Choose %s", mTitle));
closeDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getDialog().dismiss();
}
});
}
#Override
public Dialog onCreateDialog(#NonNull Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
// request a window without the title
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
// closeDialog = (ImageView) dialog.findViewById(R.id.closeDialog);
return dialog;
}
public void getAdapter() {
gridAdapter = new HomeSubGridViewAdapter(getContext(), R.layout.gridview_custom_layout, liststring);
gridView.setAdapter(gridAdapter);
}
}
This is the method for calling dialog from fragment
fragmentManager = ((FragmentActivity) context).getSupportFragmentManager();
SubcategoryFragment postalFragment = SubcategoryFragment.newInstance(Integer.valueOf(item.getId()), item.getName());
postalFragment.show(fragmentManager, "SubcategoryFragment");
Feel Free to ask if you feel any problem is that
You can call a DialogFragment from Another DialogFragment.
NewDialogFragment newDialogFragment= new NewDialogFragment();
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
newDialogFragment.show(transaction, "New_Dialog_Fragment");
Very recently, I had this problem and none of the options above worked for me. I tried using the method below:
DialogFragment fragment = new MyFragment(); //where MyFragment is my fragment I want to show
fragment.setCancelable(true);
fragment.show(getSupportFragmentManager(), "timePicker");
This will ONLY work if you're using this in an activity (i.e to call a dialog fragment from an activity class).
I however fixed this by downcasting my activity instance to an AppCompat activity and using it to call getSupportFragment() as shown below:
DialogFragment timeFragment = new TimePicker();
timeFragment.setCancelable(true);
AppCompatActivity activity = (AppCompatActivity) getActivity();
timeFragment.show(activity.getSupportFragmentManager(), "timePicker");
I hope this helps.. Merry coding!!
This is the code that works for me:
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
if (getArguments() == null) {
throw new InvalidParameterException("The key types dialog needs the protocol id to be in the arguments");
}
if (mCallback == null) {
throw new InvalidParameterException("The key types dialog needs an callback to be set");
}
mProtocolId = getArguments().getInt(ApplicationConstants.FragmentsConstants.PROTOCOL_ID);
final List<KeyTypeEntity> allKeyTypes = BusinessFacade.getInstance(getActivity()).KeyTypeLogic.getAllKeyTypes();
ArrayAdapter<KeyTypeEntity> keyTypeAdapter = new ArrayAdapter<KeyTypeEntity>(getActivity(), android.R.layout.simple_list_item_1, allKeyTypes);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("").setAdapter(keyTypeAdapter, new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
final KeyTypeEntity keyTypeEntity = allKeyTypes.get(which);
AlertDialog.Builder number = new AlertDialog.Builder(getActivity());
List<String> keyNumbers = new ArrayList<String>();
for (int i = 0; i < 50; i++) {
keyNumbers.add("" + (i + 1));
}
ArrayAdapter<String> kAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, keyNumbers);
number.setTitle("").setAdapter(kAdapter, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
addNewKey(keyTypeEntity, which + 1);
}
});
number.show();
}
}).setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
mCallback.onDialogClosed();
}
});
mDialog = builder.create();
return mDialog;
}
In the first click handler I just create a new dialog and show it. This will close the first dialog, open the second one, and when the user clicks on an item in the list, the second click handler is called.
Hope this helps, and I am not too late :)
You can pass FragmentManage to newInstance() method of First DialogFragment then you can use it to show new dialogfragment
this is my code.
private static FragmentManager fragmentManager;
public static PlayListDialog newInstance(Context context, FragmentManager fragmentManager1) {
playListDialog = new PlayListDialog();
mContext = context;
fragmentManager = fragmentManager1;
return playListDialog;
}
#Override
public void createNewPlaylist() {
NewPlayListDialog newPlayListDialog = NewPlayListDialog.newInstance(mContext);
newPlayListDialog.showDialog(fragmentManager.beginTransaction(),fragmentManager.findFragmentByTag("newdialog"));
}
Use this:
getActivity().getSupportFragmentManager
instead of
getChildFragmentManager().
Hope this helps.
If you want the kotlin version use this:
val newDialogFragment = NewDialogFragment()
val transaction: FragmentTransaction =
requireActivity().supportFragmentManager.beginTransaction()
newDialogFragment.show(transaction, "New_Dialog_Fragment")