I am building an application in xamarin, where I am trying to pop up AleartDialog from another dialog and it happenes successfully but the problem here is :
when second dialog opens up previous one goes invisible and when I go back it pops up automatically.
Below image would make the requirement more clear
image 1 is what I want but it is coming like image 2 and image 3
below is my DialogInterface class
public class DialogBuilder : DialogFragment {
public static DialogBuilder NewInstance(bool showPrimary) {
DialogBuilder fragment = new DialogBuilder { Arguments = new Bundle() };
fragment.Arguments.PutBoolean("boolean", showPrimary);
return fragment;
}
public override void OnCreate(Bundle savedInstanceState) {
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Use this to return your custom view for this Fragment
// bool showPrimaryLayout = Arguments.GetBoolean("boolean");
View view = null;
bool showPrimaryLayout = Arguments.GetBoolean("boolean");
InputMethodManager inputManager = (InputMethodManager)Activity.GetSystemService(Context.InputMethodService);
var currentFocus = Activity.CurrentFocus;
if (currentFocus != null) {
inputManager.HideSoftInputFromWindow(currentFocus.WindowToken, HideSoftInputFlags.none);
}
if (showPrimaryLayout) {
view = inflater.Inflate(Resource.Layout.dialog_edit_schedule_party, container, false);
var button_add_hostess = view.FindViewById<Button>(Resource.Id.btn_add_hostess);
button_add_hostess.Click += (s, e) => ShowDialog(false);
}
else {
view = inflater.Inflate(Resource.Layout.fragment_add_hostess_dialog, container, false);
}
return view;
}
public void ShowDialog(bool isPrimary) {
FragmentTransaction transction = FragmentManager.BeginTransaction();
//Remove fragment else it will crash as it is already added to backstack
Fragment prev = FragmentManager.FindFragmentByTag("dialog");
if (prev != null) {
transction.Remove(prev);
}
transction.AddToBackStack(null);
DialogBuilder builder = NewInstance(isPrimary);
builder.Show(transction, "dialog");
}
}
}
implementation in my activity class
private void popUpDialog() {
FragmentTransaction ft = FragmentManager.BeginTransaction();
//Remove fragment else it will crash as it is already added to backstack
Fragment prev = FragmentManager.FindFragmentByTag("dialog");
if (prev != null) {
ft.Remove(prev);
}
ft.AddToBackStack(null);
// Create and show the dialog.
DialogBuilder dialog = DialogBuilder.NewInstance(true);
dialog.Cancelable = false;
//Add fragment
dialog.Show(ft, "dialog");
}
Any help is appreciated.
The problem lies in this below code
private void popUpDialog() {
FragmentTransaction ft = FragmentManager.BeginTransaction();
//Remove fragment else it will crash as it is already added to backstack
Fragment prev = FragmentManager.FindFragmentByTag("dialog");
if (prev != null) {
ft.Remove(prev);
}
ft.AddToBackStack(null);
// Create and show the dialog.
DialogBuilder dialog = DialogBuilder.NewInstance(true);
dialog.Cancelable = false;
//Add fragment
dialog.Show(ft, "dialog");
}
For both the dialogs the string tag sent was the same which resulted in hiding the dialog opened before.
Solution:
dialog.Show(ft, "dialog_one"); // for first dialog.
dialog.Show(ft, "dialog_two"); // for second one
Related
I have created one dialog fragment in app. Following is the code for it.
public class AlertLoader extends DialogFragment {
Typeface fontRegular;
Bundle bundle;
String displayText = "";
public static AlertLoader newInstance(#NonNull String displayText) {
AlertLoader alertPopUpMenu = new AlertLoader();
Bundle args = new Bundle();
args.putString("displayText", displayText);
alertPopUpMenu.setArguments(args);
return alertPopUpMenu;
}
#Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null && dialog.getWindow() != null) {
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bundle = getArguments();
setStyle(STYLE_NO_TITLE, R.style.LoaderDialogTheme);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getDialog().setCanceledOnTouchOutside(false);
return inflater.inflate(R.layout.alert_dialog_loader, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
init(view);
}
private void init(View mainView) {
displayText = bundle.getString("displayText");
TextView mLoadingText = (TextView) mainView.findViewById(R.id.loadertext);
mLoadingText.setTextColor(Color.WHITE);
mLoadingText.setTypeface(fontRegular);
if (displayText == null || displayText.length() == 0) {
mLoadingText.setVisibility(View.GONE);
} else {
mLoadingText.setText(displayText);
mLoadingText.setVisibility(View.VISIBLE);
}
}
public void dismissCurrentView() {
getDialog().dismiss();
}
}
I am using following code to show dialog.
private void showLoader(String displayText) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
AlertLoader newFragment = AlertLoader.newInstance(displayText);
newFragment.show(ft, "dialog");
}
It is working fine. I am trying to dismiss it by following code.
private void dismissLoader() {
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
DialogFragment df = (DialogFragment) prev;
df.dismiss();
}
}
I am dismissing my loader before navigating to next activity. Following is my code where i am dismissing loader.
dismissLoader();
Intent intent = new Intent(getActivity(), ShareMediaActivity.class);
intent.putExtra(UserDefault.bundlePath, file.getAbsolutePath());
startActivity(intent);
But when i come back to previous activity , dialog still displays. This code for showing and dismissing is working fine in other cases.
I have tried several ways to dismiss it but not working. Anyone could help me with this?
Thanks.
Create a field for DialogFragment as below
private AlertLoader newFragment;
private void showLoader(String displayText) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
newFragment = AlertLoader.newInstance(displayText);
newFragment.show(ft, "dialog");
}
Then use that field to dismiss the DialogFragment
private void dismissLoader() {
if (newFragment != null) {
newFragment.dismiss();
}
}
This question already has answers here:
Start a fragment via Intent within a Fragment
(5 answers)
Closed 6 years ago.
i want to replace activity to a fragment, this code is not working.
Intent intent = new Intent(Activity.this, Fragment.class);
startActivity(intent);
finish();
You cannot switch from an Activity to Fragment, because a Fragment does not have its own existence without an Activity. i.e. a Fragment works inside an Activity.
Basically, Fragments are mainly used to create multi-pane screens.
Inside an Activity if you can replace Fragments (associated with the Activity) as mentioned in the above code examples to change the UI.
Try like this in your activity
#Override
public void replaceFragment(Fragment fragment, boolean addToBackStack) {
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
if (addToBackStack) {
transaction.addToBackStack(null);
} else {
getSupportFragmentManager().popBackStack(null,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
transaction.replace(R.id.flContent, fragment);
transaction.commitAllowingStateLoss();
getSupportFragmentManager().executePendingTransactions();
}
and use like this
YourFragment mYourFrag = new YourFragment ();
replaceFragment(mYourFrag , false);
Create a Fragmen class like
public class FragmentName extends android.support.v4.app.Fragment {}
And then you are able to cast a activity to view like:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View returner = null;
Intent intent = new Intent([CONTEXT],[CLASSNAME.class]);
Bundle args = this.getArguments();
final Window w = [LocalActivityManager].startActivity("Title", intent);
final View wd = w != null ? w.getDecorView() : null;
if (wd != null) {
ViewParent parent = wd.getParent();
if(parent != null) {
ViewGroup v = (ViewGroup)parent;
v.removeView(wd);
}
wd.setVisibility(View.VISIBLE);
wd.setFocusableInTouchMode(true);
if(wd instanceof ViewGroup) {
((ViewGroup) wd).setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
}
}
returner = wd;
return returner;
}
I tried to create a ProgressFragment to be used in the whole application:
public class ProgressFragment extends Fragment {
private static final String KEY = "info";
private CustomProgressView mProgress;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(...);
mProgress = (CustomProgressView) root.findViewById(...);
mProgress.start();
if (getArguments() != null) {
mProgress.setText(getArguments().getString(KEY, ""));
}
return root;
}
public void setInformation(String text) {
if (mProgress != null) {
if (this.isHidden()) {
show(getActivity().getSupportFragmentManager());
}
mProgress.setText(text);
} else {
Bundle b = new Bundle();
b.putString(KEY, text);
setArguments(b);
}
}
public void hide(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction();
ft.hide(this);
ft.commit();
}
private void show(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction();
ft.show(this);
ft.commit();
}
}
The ProgressFragment is expected to attached(added) to the activity once, and there should be only one instance, then the client should only update its' information or hide it.
Usage in client(activity):
class MainActivity...{
ProgressFragment mFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFragment = ProgressFragment.newInstance(null);
FragmentTransaction fs = getSupportFragmentManager().beginTransaction();
fs.add(id, mFragment);
fs.commit();
}
//close the progress
mFragment.hide()
//show the progress
mFragment.setInformation("..")
}
However it does not worked as expected, sometime the progress view will show only at the first call or it does not even show.
Did I miss anything?
Don't set your onCreateView as #Nullable;
Use commitAllowingStateLoss();
Instead of just add(), use addToBackStack(). When you want to close it, just use the FragmentManager popBackStack():
getActivity().getSupportFragmentManager().popBackStack();
I had created DialogFragment in my application. Here is the code:
public static class SkipDialogFragment extends DialogFragment implements
OnClickListener {
private Button btnYes;
private Button btnCancel;
//private PerformActionListener mListener;
private AlertDialog ad;
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//mListener = (PerformActionListener) getActivity();
LayoutInflater li = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View customDialogView = li.inflate(R.layout.dialog_alert_yes_no,
null);
TextView txtMessage = (TextView) customDialogView
.findViewById(R.id.txtMessage);
txtMessage.setText(getResources().getString(
R.string.disagreement_stmt));
btnYes = (Button) customDialogView.findViewById(R.id.btnOk);
btnYes.setOnClickListener(this);
btnCancel = (Button) customDialogView.findViewById(R.id.btnCancel);
btnCancel.setOnClickListener(this);
ad = new AlertDialog.Builder(getActivity()).setView(
customDialogView).create();
return ad;
}
#Override
public void onClick(View v) {
if (v.equals(btnYes)) {
new CreateProfileFragment().gotoHome();
//mListener.onActionPerformed();
ad.dismiss();
}
if (v.equals(btnCancel)) {
ad.dismiss();
}
}
}
When the user clicks on Positive button in the dialog, it should navigate to another fragment. Here is the code for fragment to be displayed:
private void gotoHome() {
HomeFragment homeFragment = (HomeFragment) getFragmentManager()
.findFragmentById(R.id.home_fragment);
if (homeFragment != null) {
homeFragment.initializeView();
} else {
homeFragment = new HomeFragment();
FragmentTransaction transaction = getFragmentManager()
.beginTransaction();
transaction
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.replace(R.id.linFragmentContainer, homeFragment,
AppUtils.HOME_FRAGMENT);
transaction.addToBackStack(null);
transaction.commit();
}
}
But, whenever I click on Yes button in the dialog, getFragmentManager() in the gotoHome() returns null. I am not getting why is this happening.
I have a fully working app which contains a fragment declared as follows:
public class SearchableListFragment extends Fragment implements TabListener
At one point during the work of the fragment, we execute a rather slow loop. Imagine something like:
for(int i = 0;i < large_number;i++)
{
// do complex maths
}
but this loop takes rather a long time and I'd like to have a progress bar appear during the loop. I have seen a variety of examples of adding dialogs, but they all seem to fail because one part or another appears not to apply to fragments.... or they are not applicable because they assume one thing or another that simply does not apply in my case. How can I wrap my loop in some code that will display a progress bar (either a linear bar or a swirling circle - whatever's easiest).
EDIT: The fragment is deployed within a SherlockFragmentActivity. Also the fragments are being implemented via android.support.v4.app.*
You might want to take a look at this question: addView not visible in custom FrameLayout but clickable
Especially its "SOLUTION" ( http://pastebin.com/2xjnCDLS ), which is a viewgroup which switches between the progressbar and the contentview(s), and is easily usable in your layout-xml, was very helpful for me in various occasions. Just call showProgressbar() before and showNext() after you've loaded your content/made your computations.
I have this ModalProgress class that I use every where to show modal progress, I guess you can use it as it is:
public class ModalProgress extends DialogFragment {
public static void show(Activity activity, String title,
String message) {
if (activity == null) {
return;
}
FragmentManager fm = activity.getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
hideInternal(ft, fm);
// Create and show the dialog.
DialogFragment newFragment = new ModalProgress();
Bundle args = new Bundle();
args.putString("title", title);
args.putString("message", message);
newFragment.setArguments(args);
newFragment.show(ft, "dialog");
}
private static void hideInternal(FragmentTransaction ft, FragmentManager fm) {
Fragment prev = fm.findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
}
public static void hide(FragmentActivity activity) {
if (activity == null) {
return;
}
FragmentManager fm = activity.getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
hideInternal(ft, fm);
ft.commit();
}
public ModalProgress() {
setCancelable(false);
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle args = getArguments();
ProgressDialog dialog = new ProgressDialog(getActivity());
String title = args.getString("title");
String msg = args.getString("message");
if (!TextUtils.isEmpty(title)) {
dialog.setTitle(title);
}
if (!TextUtils.isEmpty(msg)) {
dialog.setMessage(msg);
}
return dialog;
}
}
Now move your loop code inside AsyncTask:
private class LongTask extends AsyncTask<Void, Void, Void> {
protected void onPreExecute (){
ModalProgress.show(getActivity(), "Working", "Please wait...");
}
protected Void doInBackground(Void... voids) {
for (int i = 0; i < count; i++) {
// your loop here
}
return null;
}
protected void onPostExecute(Void result) {
ModalProgress.hide(getActivity());
}
}
and then just execute AsyncTask.