3

I have a DialogFragment whose only child is a StackView. The dialog is launched when a button is clicked in the parent fragment.

I tried to add animations to the fragment via getWindow().setWindowAnimations() but for some reason it was not working.

The approach that I took is to animate the Window's decorView:

public class TrailerDialogFragment extends DialogFragment {

    private static final String VIDEOS_EXTRA = "videos extra";

    private List<Video> mVideos = new ArrayList<>();

    @BindView(R.id.stack_view)
    StackView mStackView;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        List<Video> videos = getArguments().getParcelableArrayList(VIDEOS_EXTRA);
        if (videos != null) {mVideos.addAll(videos);}
    }

    public static TrailerDialogFragment newInstance(List<Video> videos) {
        Bundle bundle = new Bundle();
        ArrayList<Video> arrayList = new ArrayList<>();
        arrayList.addAll(videos);
        bundle.putParcelableArrayList(VIDEOS_EXTRA, arrayList);
        TrailerDialogFragment fragment = new TrailerDialogFragment();
        fragment.setArguments(bundle);
        return fragment;
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.dialog_stackview, container, false);

        ButterKnife.bind(this, rootView);
        mStackView.setAdapter(new VideoAdapter(mVideos));

        return rootView;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        return dialog;
    }

    @Override
    public void onStart() {
        super.onStart();
        final View decorView = getDialog()
                .getWindow()
                .getDecorView();

        ObjectAnimator scaleDown = ObjectAnimator.ofPropertyValuesHolder(decorView,
                PropertyValuesHolder.ofFloat("scaleX", 0.0f, 1.0f),
                PropertyValuesHolder.ofFloat("scaleY", 0.0f, 1.0f),
                PropertyValuesHolder.ofFloat("alpha", 0.0f, 1.0f));
        scaleDown.setDuration(500);
        scaleDown.start();
    }

    @Override
    public void onCancel(DialogInterface dialog) {
        final View decorView = getDialog()
                .getWindow()
                .getDecorView();

        ObjectAnimator scaleDown = ObjectAnimator.ofPropertyValuesHolder(decorView,
                PropertyValuesHolder.ofFloat("scaleX", 1.0f, 0.0f),
                PropertyValuesHolder.ofFloat("scaleY", 1.0f, 0.0f),
                PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.0f));
        scaleDown.setDuration(500);
        scaleDown.start();
        super.onCancel(dialog);
    }

    private static class VideoAdapter extends BaseAdapter {

        List<Video> mVideos = new ArrayList<>();

        public VideoAdapter(List<Video> videos) {
            mVideos.addAll(videos);
        }

        @Override
        public int getCount() {
            return mVideos.size();
        }

        @Override
        public Object getItem(int i) {
            return mVideos.get(i);
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            View resultView;
            if (view == null) {
                resultView = LayoutInflater.from(viewGroup.getContext()).inflate(
                        R.layout.dummy_view, viewGroup, false);
            } else  {
                resultView = view;
            }
            TextView tv = (TextView) resultView.findViewById(R.id.trailer_title);
            ImageView image = (ImageView) resultView.findViewById(R.id.trailer_image);

            tv.setText(mVideos.get(i).name());
            ViewUtil.loadThumbnail(mVideos.get(i).key(), resultView.getContext(), image);
            return resultView;
        }
    }
}

When I click outside of dialog fragment, the onCancel callback is triggered, but for some reason the animation doesn't play. The DialogFragment simply dissappears.

Do you know why this could happen?

  • I am not terribly surprised that your animations on `decorView` do not work, as most of Android will have no idea that those are requested. I would expect that you need to do something that tells Android at a higher level that you want a custom transition. Have you tried `setExitTransition()` on the `DialogFragment` itself? – CommonsWare Aug 22 '16 at 16:34
  • I tried to do that, but I support back to version 16 and to use transitions I think that I need api level 21 – Javier Ventajas Hernández Aug 22 '16 at 18:12
  • Also, I tried to wrap setExitTransition() in an if block to check if the device is running lollipop or above. My phone runs on api 23 and I still can't see the transition when I cancel the dialog. Any ideas :( ? – Javier Ventajas Hernández Aug 22 '16 at 18:20
  • Yes, `setExitTransition()` requires API Level 21+. I do not know if it works for a `DialogFragment` anyway. Window animations is then probably your best bet, such as via [a theme](http://stackoverflow.com/a/15816189/115145). I am assuming that your existing code is based off of [this](http://stackoverflow.com/a/33333038/115145), but, again, that approach worries me from a compatibility standpoint. – CommonsWare Aug 22 '16 at 18:21
  • I tried to follow the approach that you suggested: create the animation resources, create a theme with the resources and then setting getDialog().getWindow().getAttributes().windowAnimations = R.style.mytheme. However, for some reason the animations are not being applied. I can see that the theme is applied correctly because the size of the dialog has been modified as a side-effect. I just don't know why the animations don't apply – Javier Ventajas Hernández Aug 22 '16 at 18:46
  • I haven't used any of this personally, as I am very happy to leave dialog animations alone. :-) However, that recipe seems to be reasonably popular, so I do not know why it would not work for you. – CommonsWare Aug 22 '16 at 18:50

0 Answers0