Monday, October 15, 2018

DialogFragment with multiple fragments/views

Leave a Comment

How can I display a dialogfragment with multiple fragments one after the other with animation?

The use case I have is:

  1. DialogFragment is showing with fragment 1. It has a "next" button
  2. User clicks next
  3. The same dialogFragment displays fragment 2 with a slide in animation.

Any pointers would help.

Thank you in advance.

This is the base dialogfragment I am using

public class BaseDialogFragment extends DialogFragment {      public BaseDialogFragment () {      }      public static BaseDialogFragment newInstance(String title) {         BaseDialogFragment frag = new BaseDialogFragment ();         Bundle args = new Bundle();         args.putString("title", title);         frag.setArguments(args);         return frag;     }      @Override     public View onCreateView(LayoutInflater inflater, ViewGroup container,             Bundle savedInstanceState) {         return inflater.inflate(R.layout.fragment, container);     }      @Override     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {         super.onViewCreated(view, savedInstanceState);           getDialog().getWindow().setSoftInputMode(             WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);     } } 

Here is how the behaviour is. It is BottomNavigation activity that is displaying dialog with flow. The next/previous dialog comes in with slide in/out navigation.

enter image description here

I am open to other suggestions too such as dialog-Themed activity

4 Answers

Answers 1

As far as i understand, you would like to have one parent dialog fragment which is managing two child fragments. To do so, you have to follow those steps.

  1. Create parent dialog fragment
  2. Create two child fragment
  3. Add first fragment to parent fragment
  4. Add call back from first child fragment to parent to replace it with second child fragment
  5. Add functionality to parent fragment to replace child fragment

Lets start with first step. We are going to create a container dialog fragment:

class ContainerDialogFragment extends DialogFragment {     @Override     public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {         return inflater.inflate(R.layout.container_fragment, container, false);     } } 

Our container_fragment xml will look like:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"         android:id="@+id/fragment_container"         android:layout_width="match_parent"         android:layout_height="match_parent" /> 

Then we create two child fragment:

class ChildFragment1 extends Fragment {     //...the content is up to you... } 

and

class ChildFragment2 extends Fragment {     //...the content is up to you... } 

We add first fragment to our container dialog fragment:

class ContainerDialogFragment extends DialogFragment {     @Override     public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {         return inflater.inflate(R.layout.container_fragment, container, false);     }      @Override     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {         FragmentTransaction transaction = getChildFragmentManager().beginTransaction();         ChildFragment1 childFragment1 = new ChildFragment1();         transaction.replace(R.id.fragment_container, childFragment1);         transaction.commit();     } } 

Now we have to add an interface to communicate between parent and child fragment to replace it:

class ChildFragment1 extends Fragment {     interface ChildFragment1Listener {         void onButtonPressed();     }      //you have to call this method when user pressed to button     void onButtonPressed() {         ChildFragment1Listener listener = (ChildFragment1Listener) getParentFragment();         listener.onButtonPressed();     } } 

Finally, we have to implement this interface in our container dialog fragment and add replace functionality:

class ContainerDialogFragment extends DialogFragment implements ChildFragment1.ChildFragment1Listener {     @Override     public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {         return inflater.inflate(R.layout.container_fragment, container, false);     }      @Override     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {         FragmentTransaction transaction = getChildFragmentManager().beginTransaction();         ChildFragment1 childFragment1 = new ChildFragment1();         transaction.replace(R.id.fragment_container, childFragment1);         transaction.commit();     }      @Override     void onButtonPressed() {         FragmentTransaction transaction = getChildFragmentManager().beginTransaction();         //Out of simplicity, i am creating ChildFragment2 every time user presses the button.          //However, you should keep the instance somewhere to avoid creation.         ChildFragment2 childFragment2 = new ChildFragment2();         transaction.replace(R.id.fragment_container, childFragment2);         //You can add here as well your fragment in and out animation how you like.         transaction.addToBackStack("childFragment2");         transaction.commit();     } } 

Thats it.

Answers 2

What I would do:

1) Create parent dialog fragment without any content

2) Create 3 Fragments representing each of the state of the dialog

3) Show content fragments and implement navigation between them in the context of ParentDialogFragment::childFragmentManager

Answers 3

I managed to have custom dialog fragments with animations by using normal fragments in the following way.

Add the id to the root layout of your activity

<?xml version="1.0" encoding="utf-8"?> <FrameLayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     xmlns:app="http://schemas.android.com/apk/res-auto"     android:id="@+id/root_layout"     android:layout_width="match_parent"     android:layout_height="match_parent"> 

In your activity class retrieve root_layout with findViewById() and add the following method:

public void showFragment(BaseDialogFragment fragment, @AnimatorRes @AnimRes int enter,                              @AnimatorRes @AnimRes int exit) {         FragmentManager manager = getSupportFragmentManager();         String fragmentName = fragment.getClass().getName();         if (manager.findFragmentByTag(fragmentName) == null) {             FragmentTransaction transaction = manager.beginTransaction();             transaction.setCustomAnimations(enter, exit, enter, exit);             transaction.add(R.id.root_layout, fragment, fragmentName);             transaction.addToBackStack(fragmentName);             transaction.commit();         }     } 

Where enter and exit arguments accept xml anim files like anim/slide_in.xml:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"     android:shareInterpolator="false" >     <translate android:duration="300" android:fromXDelta="-100%" android:toXDelta="0%"/> </set> 

And anim/slide_out.xml:

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"     android:shareInterpolator="false" >     <translate android:duration="300" android:fromXDelta="0%" android:toXDelta="-100%"/> </set> 

Then create a base class for dialogs which allow to dismiss the dialog:

public abstract class BaseDialogFragment extends Fragment {      public void dismiss() {         getActivity().getSupportFragmentManager()                 .popBackStack(getClass().getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);     } } 

Back key is also working because the fragment is in the back stack. Now create your dialogs extending from the BaseDialogFragment class and show them calling showFragment(dialogFragment, R.anim.slide_in, R.anim.slide_out); from your activity.

If you have to start Dialog2 from Dialog1, simply use ((YourActivity)getActivity).showFragment(dialogFragment, R.anim.slide_in, R.anim.slide_out).

Answers 4

Search in Youtube "Fragment Tricks (Google I/O '17)" If you want to understand how it works.

Solution is simple addToBackStack

For animation: you can set your custom animation -> transaction.setCustomAnimations(R.anim.first, R.anim.second...);

I suggest to watch the google presentation, you will be amazed, hope so.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment