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();
}
}
Related
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
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();
In my application i have a 45 "editText" . now, when the user rotate the device the dialog closed and all the data are gone. so i created a "public static boolean isShow = false" variable in the Dialogclass and it true is the dialog are "show" and on my MainActivity i saved to the bundle and it's work my dialog not closed beacuse i create a new dialog when "isShow" = false. but all the data cleared . My question is do i need to save all of the 45 editText one by one? if i need , there is a way to cancel the rotation only for this dialog?
public class DialogSetting extends Dialog {
public static boolean isShow = false;
public DialogSetting(Context context) {
super(context);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dialog_setting);
this.context = context;
this.show();
isShow = true;
this.setOnCancelListener(new DialogInterface.OnCancelListener()
{
#Override
public void onCancel(DialogInterface dialog)
{
isShow = false;
}
});
}
public void close(View v){
isShow = false;
this.dismiss();
}
MainActivity:
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putBoolean("dialogSetting", DialogSetting.isShow);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
DialogSetting.isShow = savedInstanceState.getBoolean("dialogSetting");
if(DialogSetting.isShow){
new DialogSetting(this);
}
First of all: You should inherit your dialog from DialogFragment. If you're doing this the FragmentManager will take care of recreating the Fragment after rotating the device.
So here's how your Dialog class should look like:
public class MyDialog extends DialogFragment {
public static MyDialog newInstance(){
MyDialog f = new MyDialog();
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_setting, container, false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
// Everything else that needs to be done to setup the dialog (findViewById, Listener etc.)
return view;
}
}
Here's how you need to call the Dialog (slightly more complex):
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
MyDialog dialogFragment = MyDialog.newInstance();
dialogFragment.show(ft, "dialog");
To prevent any loss of data because of the rotation, you need to save the data in a bundle inside the dialog (basically the same as you did in your Activity).
Here's a basic example of saving the entered text of an EditText:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null){
text = savedInstanceState.getString("et_text");
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("et_text", mEditText.getText().toString());
}
You can read more about DialogFragments in the docs(click).
Why do i always get error when i try to call AlertDialog from my fragment?
At first i try to put it in OnCreate but it also get the same error log...
MainFragment.java
public class MainFragment extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_fragment);
if (savedInstanceState == null) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
LoginFragment fragment = new LoginFragment();
ft.add(R.id.simple_fragment, fragment).commit();
}
}
}
LoginFragment.java
public class LoginFragment extends Fragment implements OnClickListener {
Helper application;
static LoginFragment newInstance() {
LoginFragment f = new LoginFragment();
Bundle args = new Bundle();
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(getActivity().getApplicationContext());
dlgAlert.setMessage("TEST");
dlgAlert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
dlgAlert.setCancelable(false);
dlgAlert.create().show();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_login, container, false);
Button inner = (Button) v.findViewById(R.id.btnSignUp);
inner.setOnClickListener(LoginFragment.this);
return v;
}
#Override
public void onClick(View v) {
}
}
and this is the error log
12-19 10:14:25.295: E/AndroidRuntime(1083): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myfirstapp/com.example.fragment.MainFragment}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
anyone has ever encountered this before?
Just try
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(getActivity());
If you are dealing with nested fragments. When a fragment has it's own child fragments you need to use getChildFragmentManager().
Iam new to android .I need to go back to the FragmentActivity from fragment page.
My work flow is:
MainActivity->ProfileActivity->ProfilePhotoEditFragment
I need to go back to
ProfilePhotoEditFragment -> ProfileActivity
manifest
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
ProfilePhotoEditFragment.java
public class ProfilePhotoEditFragment extends Fragment implements OnClickListener {
ViewUtils mViewUtils;
Bundle mSavedInstanceState;
private OnNavigateProfileListener mOnNavigateProfileListener;
private Button mCancelButton;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context mContext = getActivity().getApplicationContext();
mViewUtils = new ViewUtils(mContext);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mSavedInstanceState = savedInstanceState;
View view = inflater.inflate(R.layout.fragment_edit_profile_pic, container, false);
mCancelButton = (Button) view.findViewById(R.id.cancel);
mCancelButton.setOnClickListener(this);
return view;
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onClick(View view) {
if (view.getId() == mCancelButton.getId()){
onBackPressed();
}
}
public void onBackPressed() {
// do something on back.
return;
}
}
remove current fragment ProfilePhotoEditFragment in onBackPressed()
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
//( "stackzeo");
} else {
getSupportFragmentManager().popBackStack();
removeCurrentFragment();
//("stacknotzeo");
}
..
public void removeCurrentFragment() {
Fragment currentFrag = (Fragment) getFragmentManager()
.findFragmentById(R.id.content_frame);
if (currentFrag != null)
getFragmentManager().beginTransaction().remove(currentFrag);
getFragmentManager().beginTransaction().commit();
}
Call findFragmentById() on FragmentManager and determine which fragment is in your R.id.content_frame container.
Thank you All. this my working code
....
#Override
public void onClick(View view) {
if (view.getId() == mCancelButton.getId()){
getActivity().getSupportFragmentManager().popBackStack();
removeCurrentFragment();
}
}
public void removeCurrentFragment()
{
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
Fragment currentFrag = getActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_common_profile_layout);
String fragName = "NONE";
if (currentFrag!=null)
fragName = currentFrag.getClass().getSimpleName();
if (currentFrag != null)
transaction.remove(currentFrag);
transaction.commit();
}
getActivity().onBackPressed();
You should be able to call this code from every fragment.
Please check, if getActivity() returns null.
Hope this helps.
just write down
public void onBackPressed(){
super.onBackPressed();
}