1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.android.setupdesign.transition.support; 18 19 import static com.google.android.setupdesign.transition.TransitionHelper.CONFIG_TRANSITION_SHARED_X_AXIS; 20 import static com.google.android.setupdesign.transition.TransitionHelper.getConfigTransitionType; 21 22 import android.annotation.TargetApi; 23 import android.app.Activity; 24 import android.os.Build; 25 import android.os.Build.VERSION_CODES; 26 import androidx.fragment.app.Fragment; 27 import android.util.Log; 28 import android.view.Window; 29 import androidx.annotation.Nullable; 30 import androidx.core.app.ActivityOptionsCompat; 31 import com.google.android.material.transition.platform.MaterialSharedAxis; 32 import com.google.android.setupcompat.partnerconfig.PartnerConfig; 33 34 /** Helper class for apply the transition to the pages which uses support library. */ 35 public class TransitionHelper { 36 37 private static final String TAG = "TransitionHelper"; 38 TransitionHelper()39 private TransitionHelper() {} 40 41 /** 42 * Apply the transition for going forward which is decided by partner resource {@link 43 * PartnerConfig#CONFIG_TRANSITION_TYPE} and system property {@code setupwizard.transition_type}. 44 * The default transition that will be applied is {@link 45 * com.google.android.setupdesign.transition.TransitionHelper#CONFIG_TRANSITION_NONE}. The timing 46 * to apply the transition is going forward from the previous {@link Fragment} to this, or going 47 * forward from this {@link Fragment} to the next. 48 */ 49 @TargetApi(VERSION_CODES.M) applyForwardTransition(Fragment fragment)50 public static void applyForwardTransition(Fragment fragment) { 51 if (Build.VERSION.SDK_INT >= VERSION_CODES.M) { 52 if (CONFIG_TRANSITION_SHARED_X_AXIS == getConfigTransitionType(fragment.getContext())) { 53 MaterialSharedAxis exitTransition = 54 new MaterialSharedAxis(MaterialSharedAxis.X, /* forward= */ true); 55 fragment.setExitTransition(exitTransition); 56 57 MaterialSharedAxis enterTransition = 58 new MaterialSharedAxis(MaterialSharedAxis.X, /* forward= */ true); 59 fragment.setEnterTransition(enterTransition); 60 } else { 61 Log.w(TAG, "Not apply the forward transition for support lib's fragment."); 62 } 63 } else { 64 Log.w( 65 TAG, 66 "Not apply the forward transition for support lib's fragment. The API is supported from" 67 + " Android Sdk " 68 + VERSION_CODES.M); 69 } 70 } 71 72 /** 73 * Apply the transition for going backward which is decided by partner resource {@link 74 * PartnerConfig#CONFIG_TRANSITION_TYPE} and system property {@code setupwizard.transition_type}. 75 * The default transition that will be applied is {@link 76 * com.google.android.setupdesign.transition.TransitionHelper#CONFIG_TRANSITION_NONE}. The timing 77 * to apply the transition is going backward from the next {@link Fragment} to this, or going 78 * backward from this {@link Fragment} to the previous. 79 */ 80 @TargetApi(VERSION_CODES.M) applyBackwardTransition(Fragment fragment)81 public static void applyBackwardTransition(Fragment fragment) { 82 if (Build.VERSION.SDK_INT >= VERSION_CODES.M) { 83 if (CONFIG_TRANSITION_SHARED_X_AXIS == getConfigTransitionType(fragment.getContext())) { 84 MaterialSharedAxis returnTransition = 85 new MaterialSharedAxis(MaterialSharedAxis.X, /* forward= */ false); 86 fragment.setReturnTransition(returnTransition); 87 88 MaterialSharedAxis reenterTransition = 89 new MaterialSharedAxis(MaterialSharedAxis.X, /* forward= */ false); 90 fragment.setReenterTransition(reenterTransition); 91 } else { 92 Log.w(TAG, "Not apply the backward transition for support lib's fragment."); 93 } 94 } else { 95 Log.w( 96 TAG, 97 "Not apply the backward transition for support lib's fragment. The API is supported from" 98 + " Android Sdk " 99 + VERSION_CODES.M); 100 } 101 } 102 103 /** 104 * A wrapper method, create an {@link ActivityOptionsCompat} to transition between activities as 105 * the {@link ActivityOptionsCompat} parameter of {@link 106 * androidx.activity.result.ActivityResultLauncher#launch(I, ActivityOptionsCompat)} method. 107 */ 108 @Nullable makeActivityOptionsCompat(Activity activity)109 public static ActivityOptionsCompat makeActivityOptionsCompat(Activity activity) { 110 ActivityOptionsCompat activityOptionsCompat = null; 111 if (activity == null) { 112 return activityOptionsCompat; 113 } 114 115 if (getConfigTransitionType(activity) == CONFIG_TRANSITION_SHARED_X_AXIS) { 116 if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { 117 if (activity.getWindow() != null 118 && !activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) { 119 Log.w( 120 TAG, 121 "The transition won't take effect due to NO FEATURE_ACTIVITY_TRANSITIONS feature"); 122 } 123 124 activityOptionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(activity); 125 } 126 } 127 128 return activityOptionsCompat; 129 } 130 } 131