I have an application that is using fragments. The set up is like so:
Main Activity loads, loads fragment activity into right portion of parent activity
-From the Fragment, I launch a DialogFragment which displays a list of users
-From the DialogFragment, if you click on one of the users in the list, it hides the list of users DialogFragment .hide() and shows a new DialogFragment containing the details about the user
This all works great. However, when I click the Close button on the Details DialogFragment, I'd like to dismiss() that dialog, and re-show the List of Users dialog.
I realize this is somewhat difficult to follow.
Does anyone have any insight that may help me?
UPDATE
The code I use to display the DialogFragment is the following:
MyDialogFragment dialog = new MyDialogFragment();
dialog.show(getFragmentManager(), "MyDialogFragment");
Then once in the dialog fragment, if I wanted to hide it and show the details fragment I call
dialog.hide();
MyDetailsFragment details = new MyDetailsFragment();
details.show(getFragmentManager(), "MyDetailsFragment");
Basically I need to be able to re-show the dialog above when I dismiss the details.
When a fragment transaction is performed, you can add it to the back stack which can be reversed on dismissing the dialog.
Begin a fragment transaction and use the DialogFragment.show(FragmentTransaction transaction, String tag) variant which takes the FragmentTransaction as parameter. It will take care of showing the Dialog, adding the fragment to the passed transaction and then committing the transaction. Later when the Dialog is dismissed, DialogFragment will itself take care of popping the transaction.
You can follow the first sample posted in the DialogFragment docs.
Here is the working code:
public void launchMyDialog(View v) {
// DialogFragment.show() will take care of adding the fragment
// in a transaction. We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("mydialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
MyDialogFragment dialog = new MyDialogFragment();
dialog.show(ft, "mydialog");
}
public static class MyDialogFragment extends DialogFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main, container, false);
Button b = (Button) v.findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("mydialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
MyDetailsFragment dialog = new MyDetailsFragment();
dialog.show(ft, "mydialog");
}
});
return v;
}
}
Related
I'm trying to update a DialogFragment display at runtime, setting the visibility of a view to VISIBLE or GONE depending on some conditions.
Basically, I inflate my layout in the DialogFragment, show a progress bar while I do some background request, and update the DialogFragment layout depending of the result of my request.
Sometimes it works, sometimes it doesn't update my UI accordingly, even if the logs show that the method is invoked and the thread is the Main thread.
Any idea why ?
In DialogFragment
#Override
public void showData(List<MyDataViewModel> data) {
Timber.d("Fragment Show data " + (Looper.myLooper() == Looper.getMainLooper()));
Timber.d("Fragment Show data " + this);
Timber.d("Fragment Show data " + data.size());
if (mConnectedContainer.getVisibility() != View.VISIBLE) {
mConnectedContainer.setVisibility(View.VISIBLE);
}
}
In Activity
#Override
public void showDialog() {
// DialogFragment.show() will take care of adding the fragment
// in a transaction. We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
// Create and show the dialog.
DialogFragment newFragment = MyDialogFragment.newInstance();
newFragment.show(ft, "dialog");
}
Also tried this way
#Override
public void showDialog() {
// Create and show the dialog.
DialogFragment newFragment = MyDialogFragment.newInstance();
newFragment.show(getSupportFragmentManager(), "dialog");
}
After some investigation, the issue was linked to my use of RxJava.
I was executing a first UseCase, and in the onNext, executing another one.
I split my code in two different dialogs to make it simpler, and have only one use case updating the UI, and no more issue.
I want to know how to show and hide a fragment on a button click in Android. When button is in clicked state then fragment should appear, and when the button is clicked again then the fragment should disappear.
I tried this and it worked for me. First I added the fragment when button is clicked for first time and then on subsequent clicks I attached and detached it. So it created the fragment and then without destroying it only showed and hid it.
this is the code.... Initially count is 0 when the MainActivity is first created
public void Settings(View view){
if(count==0){
count++;
// add a fragment for the first time
MyFragment frag=new MyFragment();
FragmentTransaction ft=manager.beginTransaction();
ft.add(R.id.group,frag,"A");
ft.commit();
}else{
//check if fragment is visible, if no, then attach a fragment
//else if its already visible,detach it
Fragment frag=manager.findFragmentByTag("A");
if(frag.isVisible() && frag!=null){
FragmentTransaction ft=manager.beginTransaction();
ft.detach(frag);
ft.commit();
}else{
FragmentTransaction ft=manager.beginTransaction();
ft.attach(frag);
ft.commit();
}
}
You should use Dialog fragment for this purpose. Dialog Fragment has all life cycle as fragment has and has behavior like dialog.
For example to show, simply call dialogFragment.show() method, and to hide, call dialogFragment.dismiss() method.
Here is an example how to make a dialog fragment.
public class DialogFragmentExample extends DialogFragment{
#Override
public void onStart() {
super.onStart();
// To make dialog fragment full screen.
Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
//
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
return inflater.inflate(R.layout.your_xml_layout, container, false);
}
// initialize your views here
}
And to show this dialog fragment;
DialogFragmentExample fragment = new DialogFragmentExample();
fragment.show();
similarly to dismiss,
fragment.dismiss();
Hope this will help you!
Fragment Transaction's internal show/hide flag will help.
FragmentManager fm = getFragmentManager();
fm.beginTransaction()
.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
.show(somefrag) //or hide(somefrag)
.commit();
This question already has answers here:
How to open a Fragment on button click from a fragment in Android
(3 answers)
Closed 6 years ago.
I tried the following code:
Intent in= new Intent(Activity1.this,Fragment.class);
startactivity(in);
This is not how fragments work, fragments must be attached to an Activity. To get your desired effect you must either start a new Activity that contains the fragment you wish to show, or display the new fragment in the current Activity.
In order to decide between which approach to take, I would consider how you want the Fragment to affect the navigation of your interface. If you want the user to be able to get back to the previous view by using the Back button, you should start a new Activity. Otherwise you should replace a view in your current Activity with the new Fragment.
Though, it is possible to add a Fragment to the back stack, I would only attempt to do so if you are confident with the structure of your user interface.
To show a new fragment in the current Activity you can use a FragmentTransaction:
Fragment fragment = CustomFragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container_layout, fragment).commit();
write this code in your onCreate or in your intent:
FragmentManager fm = getSupportFragmentManager();
YourFragment fragment = new YourFragment();
fm.beginTransaction().add(R.id.main_contenier,fragment).commit();
Fragments not Open through Intent.
You should use Fragment manager.
Fragment fragment= new YourFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, fragment); // fragment container id in first parameter is the container(Main layout id) of Activity
transaction.addToBackStack(null); // this will manage backstack
transaction.commit();
Sample Example of Fragment
public class MyFragment extends Fragment implements View.OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.fragment_my, container, false);
Button button1= (Button) view.findViewById(R.id.button1_Id);
Button button2= (Button) view.findViewById(R.id.button2_Id);
return view;
}
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragment= new YourFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, fragment); // fragmen container id in first parameter is the container(Main layout id) of Activity
transaction.addToBackStack(null); // this will manage backstack
transaction.commit();
}
});
}
I have a dialog extended class. I want to call a fragment to be displayed on a click of a button. I am using this method:
public void onClick(View v) {
dismiss();
SearchingFragment mySearchengine = new SearchingFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_frame, mySearchengine);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
// Perform button logic
});
But, my application crashes.
what I want my application to do is to dismiss the dialog and then call the fragment.
What you should do is to pass back the button event of your dialog fragment to the host activity, check the Passing Events Back to the Dialog's Host chapter in the Android dialog documentation. This is not only a good practice, but saves you alot of trouble, when you want to reuse the dialog.
I have a few Actiobar with 5 tabs each with a fragment. In 3 of this fragments I want to show a Dialog so I've created a new class:
public static class MyDialogFragment extends DialogFragment {
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
static MyDialogFragment newInstance() {
return new MyDialogFragment();
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int style = DialogFragment.STYLE_NORMAL;
int theme = android.R.style.Theme_Holo_Dialog;
setStyle(style, theme);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_dialog, container, false);
View tv = v.findViewById(R.id.textV);
((TextView)tv).setText("Dialog using style Normal - Theme AlertDialog - NoActionBar");
return v;
}
}
In every onCreate method of this 3 fragments I'm trying to show the Dialog by using this method:
private void showPopup()
{
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
DialogFragment newFragment = MyDialogFragment.newInstance();
newFragment.show(ft, "dialog");
}
Now the problem is that this dialog is displayed on tabs that should not.
For example I want tabs 1 3 and 5 to display the Dialog - and sometimes it displays it - but sometimes when I tap the tab 2 this dialog appears and if I tap 3 the Dialog is not showed.
What could be the problem and how should I fix it? Thanks
Have you try to move your showPopup() call in onCreateView() or in onActivityCreated() methods, instead of in onCreate() one ?
EDIT: According to comments below, the problem is linked to the use of a ViewPager, which prepare some next Fragments to be viewed, and then call onCreate() methods.
So I've found a solution - in every fragment I override a method called setMenuVisibility - and test if the the fragment is visible. If it is - I call my method.