Home | History | Annotate | Download | only in transition
      1 /*
      2  * Copyright (C) 2016 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 androidx.transition;
     18 
     19 import static org.hamcrest.core.Is.is;
     20 import static org.hamcrest.core.IsEqual.equalTo;
     21 import static org.junit.Assert.assertNotNull;
     22 import static org.junit.Assert.assertThat;
     23 
     24 import android.animation.Animator;
     25 import android.animation.ObjectAnimator;
     26 import android.support.test.annotation.UiThreadTest;
     27 import android.support.test.filters.MediumTest;
     28 import android.view.View;
     29 import android.view.ViewGroup;
     30 
     31 import androidx.annotation.NonNull;
     32 import androidx.annotation.Nullable;
     33 
     34 import org.junit.Before;
     35 import org.junit.Test;
     36 
     37 import java.util.Arrays;
     38 
     39 @MediumTest
     40 public class VisibilityTest extends BaseTest {
     41 
     42     private View mView;
     43     private ViewGroup mRoot;
     44 
     45     @UiThreadTest
     46     @Before
     47     public void setUp() {
     48         mRoot = rule.getActivity().getRoot();
     49         mView = new View(rule.getActivity());
     50         mRoot.addView(mView, new ViewGroup.LayoutParams(100, 100));
     51     }
     52 
     53     @Test
     54     public void testMode() {
     55         final CustomVisibility visibility = new CustomVisibility();
     56         assertThat(visibility.getMode(), is(Visibility.MODE_IN | Visibility.MODE_OUT));
     57         visibility.setMode(Visibility.MODE_IN);
     58         assertThat(visibility.getMode(), is(Visibility.MODE_IN));
     59     }
     60 
     61     @Test
     62     @UiThreadTest
     63     public void testCustomVisibility() {
     64         final CustomVisibility visibility = new CustomVisibility();
     65         assertThat(visibility.getName(), is(equalTo(CustomVisibility.class.getName())));
     66         assertNotNull(visibility.getTransitionProperties());
     67 
     68         // Capture start values
     69         mView.setScaleX(0.5f);
     70         final TransitionValues startValues = new TransitionValues();
     71         startValues.view = mView;
     72         visibility.captureStartValues(startValues);
     73         assertThat((float) startValues.values.get(CustomVisibility.PROPNAME_SCALE_X), is(0.5f));
     74 
     75         // Hide the view and capture end values
     76         mView.setVisibility(View.GONE);
     77         final TransitionValues endValues = new TransitionValues();
     78         endValues.view = mView;
     79         visibility.captureEndValues(endValues);
     80 
     81         // This should invoke onDisappear, not onAppear
     82         ObjectAnimator animator = (ObjectAnimator) visibility
     83                 .createAnimator(mRoot, startValues, endValues);
     84         assertNotNull(animator);
     85         assertThat(animator.getPropertyName(), is(equalTo("scaleX")));
     86 
     87         // Jump to the end of the animation
     88         animator.end();
     89 
     90         // This value confirms that onDisappear, not onAppear, was called
     91         assertThat((float) animator.getAnimatedValue(), is(0.25f));
     92     }
     93 
     94     @Test
     95     @UiThreadTest
     96     public void testCustomVisibility2() {
     97         final CustomVisibility2 visibility = new CustomVisibility2();
     98         final TransitionValues startValues = new TransitionValues();
     99         startValues.view = mView;
    100         visibility.captureStartValues(startValues);
    101         mView.setVisibility(View.GONE);
    102         final TransitionValues endValues = new TransitionValues();
    103         endValues.view = mView;
    104         visibility.captureEndValues(endValues);
    105         ObjectAnimator animator = (ObjectAnimator) visibility
    106                 .createAnimator(mRoot, startValues, endValues);
    107         assertNotNull(animator);
    108 
    109         // Jump to the end of the animation
    110         animator.end();
    111 
    112         // This value confirms that onDisappear, not onAppear, was called
    113         assertThat((float) animator.getAnimatedValue(), is(0.25f));
    114     }
    115 
    116     /**
    117      * A custom {@link Visibility} with 5-arg onAppear/Disappear
    118      */
    119     public static class CustomVisibility extends Visibility {
    120 
    121         static final String PROPNAME_SCALE_X = "customVisibility:scaleX";
    122 
    123         private static String[] sTransitionProperties;
    124 
    125         @Nullable
    126         @Override
    127         public String[] getTransitionProperties() {
    128             if (sTransitionProperties == null) {
    129                 String[] properties = super.getTransitionProperties();
    130                 if (properties != null) {
    131                     sTransitionProperties = Arrays.copyOf(properties, properties.length + 1);
    132                 } else {
    133                     sTransitionProperties = new String[1];
    134                 }
    135                 sTransitionProperties[sTransitionProperties.length - 1] = PROPNAME_SCALE_X;
    136             }
    137             return sTransitionProperties;
    138         }
    139 
    140         @Override
    141         public void captureStartValues(@NonNull TransitionValues transitionValues) {
    142             super.captureStartValues(transitionValues);
    143             transitionValues.values.put(PROPNAME_SCALE_X, transitionValues.view.getScaleX());
    144         }
    145 
    146         @Override
    147         public Animator onAppear(ViewGroup sceneRoot, TransitionValues startValues,
    148                 int startVisibility, TransitionValues endValues, int endVisibility) {
    149             if (startValues == null) {
    150                 return null;
    151             }
    152             float startScaleX = (float) startValues.values.get(PROPNAME_SCALE_X);
    153             return ObjectAnimator.ofFloat(startValues.view, "scaleX", startScaleX, 0.75f);
    154         }
    155 
    156         @Override
    157         public Animator onDisappear(ViewGroup sceneRoot, TransitionValues startValues,
    158                 int startVisibility, TransitionValues endValues, int endVisibility) {
    159             if (startValues == null) {
    160                 return null;
    161             }
    162             float startScaleX = (float) startValues.values.get(PROPNAME_SCALE_X);
    163             return ObjectAnimator.ofFloat(startValues.view, "scaleX", startScaleX, 0.25f);
    164         }
    165 
    166     }
    167 
    168     /**
    169      * A custom {@link Visibility} with 4-arg onAppear/Disappear
    170      */
    171     public static class CustomVisibility2 extends Visibility {
    172 
    173         static final String PROPNAME_SCALE_X = "customVisibility:scaleX";
    174 
    175         @Override
    176         public void captureStartValues(@NonNull TransitionValues transitionValues) {
    177             super.captureStartValues(transitionValues);
    178             transitionValues.values.put(PROPNAME_SCALE_X, transitionValues.view.getScaleX());
    179         }
    180 
    181         @Override
    182         public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
    183                 TransitionValues endValues) {
    184             float startScaleX = startValues == null ? 0.25f :
    185                     (float) startValues.values.get(PROPNAME_SCALE_X);
    186             return ObjectAnimator.ofFloat(view, "scaleX", startScaleX, 0.75f);
    187         }
    188 
    189         @Override
    190         public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
    191                 TransitionValues endValues) {
    192             if (startValues == null) {
    193                 return null;
    194             }
    195             float startScaleX = (float) startValues.values.get(PROPNAME_SCALE_X);
    196             return ObjectAnimator.ofFloat(view, "scaleX", startScaleX, 0.25f);
    197         }
    198 
    199     }
    200 
    201 }
    202