Home | History | Annotate | Download | only in com.example.android.interpolator
      1 /*
      2 * Copyright 2014 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.example.android.interpolator;
     18 
     19 import android.animation.ObjectAnimator;
     20 import android.graphics.Path;
     21 import android.os.Bundle;
     22 import android.support.v4.app.Fragment;
     23 import android.view.LayoutInflater;
     24 import android.view.View;
     25 import android.view.ViewGroup;
     26 import android.view.animation.AnimationUtils;
     27 import android.view.animation.Interpolator;
     28 import android.widget.ArrayAdapter;
     29 import android.widget.Button;
     30 import android.widget.SeekBar;
     31 import android.widget.Spinner;
     32 import android.widget.TextView;
     33 
     34 import com.example.android.common.logger.Log;
     35 
     36 /**
     37  * This sample demonstrates the use of animation interpolators and path animations for
     38  * Material Design.
     39  * It shows how an {@link android.animation.ObjectAnimator} is used to animate two properties of a
     40  * view (scale X and Y) along a path.
     41  */
     42 public class InterpolatorFragment extends Fragment {
     43 
     44     /**
     45      * View that is animated.
     46      */
     47     private View mView;
     48     /**
     49      * Spinner for selection of interpolator.
     50      */
     51     private Spinner mInterpolatorSpinner;
     52     /**
     53      * SeekBar for selection of duration of animation.
     54      */
     55     private SeekBar mDurationSeekbar;
     56     /**
     57      * TextView that shows animation selected in SeekBar.
     58      */
     59     private TextView mDurationLabel;
     60 
     61     /**
     62      * Interpolators used for animation.
     63      */
     64     private Interpolator mInterpolators[];
     65     /**
     66      * Path for in (shrinking) animation, from 100% scale to 20%.
     67      */
     68     private Path mPathIn;
     69     /**
     70      * Path for out (growing) animation, from 20% to 100%.
     71      */
     72     private Path mPathOut;
     73 
     74     /**
     75      * Set to true if View is animated out (is shrunk).
     76      */
     77     private boolean mIsOut = false;
     78 
     79     /**
     80      * Default duration of animation in ms.
     81      */
     82     private static final int INITIAL_DURATION_MS = 750;
     83 
     84     /**
     85      * String used for logging.
     86      */
     87     public static final String TAG = "InterpolatorplaygroundFragment";
     88 
     89     public InterpolatorFragment() {
     90         // Required empty public constructor
     91     }
     92 
     93 
     94     @Override
     95     public View onCreateView(LayoutInflater inflater, ViewGroup container,
     96                              Bundle savedInstanceState) {
     97 
     98         // Inflate the fragment_animation layout
     99         View v = inflater.inflate(R.layout.interpolator_fragment, container, false);
    100 
    101         // Set up the 'animate' button, when it is clicked the view is animated with the options
    102         // selected: the Interpolator, duration and animation path
    103         Button button = (Button) v.findViewById(R.id.animateButton);
    104         button.setOnClickListener(new View.OnClickListener() {
    105             @Override
    106             public void onClick(View view) {
    107                 // Interpolator selected in the spinner
    108                 Interpolator interpolator = mInterpolators[mInterpolatorSpinner.getSelectedItemPosition()];
    109                 // Duration selected in SeekBar
    110                 long duration = mDurationSeekbar.getProgress();
    111                 // Animation path is based on whether animating in or out
    112                 Path path = mIsOut ? mPathIn : mPathOut;
    113 
    114                 // Log animation details
    115                 Log.i(TAG, String.format("Starting animation: [%d ms, %s, %s]",
    116                         duration, (String) mInterpolatorSpinner.getSelectedItem(),
    117                         ((mIsOut) ? "Out (growing)" : "In (shrinking)")));
    118 
    119                 // Start the animation with the selected options
    120                 startAnimation(interpolator, duration, path);
    121 
    122                 // Toggle direction of animation (path)
    123                 mIsOut = !mIsOut;
    124             }
    125         });
    126 
    127         // Get the label to display the selected duration
    128         mDurationLabel = (TextView) v.findViewById(R.id.durationLabel);
    129 
    130         // Initialize Interpolators programmatically by loading them from their XML definitions
    131         // provided by the framework.
    132         mInterpolators = new Interpolator[]{
    133                 new AnimationUtils().loadInterpolator(getActivity(),
    134                         android.R.interpolator.linear),
    135                 new AnimationUtils().loadInterpolator(getActivity(),
    136                         android.R.interpolator.fast_out_linear_in),
    137                 new AnimationUtils().loadInterpolator(getActivity(),
    138                         android.R.interpolator.fast_out_slow_in),
    139                 new AnimationUtils().loadInterpolator(getActivity(),
    140                         android.R.interpolator.linear_out_slow_in)
    141         };
    142 
    143         // Load names of interpolators from a resource
    144         String[] interpolatorNames = getResources().getStringArray(R.array.interpolator_names);
    145 
    146         // Set up the Spinner with the names of interpolators
    147         mInterpolatorSpinner = (Spinner) v.findViewById(R.id.interpolatorSpinner);
    148         ArrayAdapter<String> spinnerAdapter =
    149                 new ArrayAdapter<String>(getActivity(),
    150                         android.R.layout.simple_spinner_dropdown_item, interpolatorNames);
    151         mInterpolatorSpinner.setAdapter(spinnerAdapter);
    152 
    153         // Set up SeekBar that defines the duration of the animation
    154         mDurationSeekbar = (SeekBar) v.findViewById(R.id.durationSeek);
    155 
    156         // Register listener to update the text label when the SeekBar value is updated
    157         mDurationSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    158             @Override
    159             public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
    160                 mDurationLabel.setText(getResources().getString(R.string.animation_duration, i));
    161             }
    162 
    163             @Override
    164             public void onStartTrackingTouch(SeekBar seekBar) {
    165             }
    166 
    167             @Override
    168             public void onStopTrackingTouch(SeekBar seekBar) {
    169             }
    170         });
    171 
    172         // Set initial progress to trigger SeekBarChangeListener and update UI
    173         mDurationSeekbar.setProgress(INITIAL_DURATION_MS);
    174 
    175         // Get the view that will be animated
    176         mView = v.findViewById(R.id.square);
    177 
    178         // The following Path definitions are used by the ObjectAnimator to scale the view.
    179 
    180         // Path for 'in' animation: growing from 20% to 100%
    181         mPathIn = new Path();
    182         mPathIn.moveTo(0.2f, 0.2f);
    183         mPathIn.lineTo(1f, 1f);
    184 
    185         // Path for 'out' animation: shrinking from 100% to 20%
    186         mPathOut = new Path();
    187         mPathOut.moveTo(1f, 1f);
    188         mPathOut.lineTo(0.2f, 0.2f);
    189         return v;
    190     }
    191 
    192     /**
    193      * Start an animation on the sample view.
    194      * The view is animated using an {@link android.animation.ObjectAnimator} on the
    195      * {@link View#SCALE_X} and {@link View#SCALE_Y} properties, with its animation based on a path.
    196      * The only two paths defined here ({@link #mPathIn} and {@link #mPathOut}) scale the view
    197      * uniformly.
    198      *
    199      * @param interpolator The interpolator to use for the animation.
    200      * @param duration     Duration of the animation in ms.
    201      * @param path         Path of the animation
    202      * @return The ObjectAnimator used for this animation
    203      * @see android.animation.ObjectAnimator#ofFloat(Object, String, String, android.graphics.Path)
    204      */
    205     public ObjectAnimator startAnimation(Interpolator interpolator, long duration, Path path) {
    206         // This ObjectAnimator uses the path to change the x and y scale of the mView object.
    207         ObjectAnimator animator = ObjectAnimator.ofFloat(mView, View.SCALE_X, View.SCALE_Y, path);
    208 
    209         // Set the duration and interpolator for this animation
    210         animator.setDuration(duration);
    211         animator.setInterpolator(interpolator);
    212 
    213         animator.start();
    214 
    215         return animator;
    216     }
    217 
    218     /**
    219      * Return the array of loaded Interpolators available in this Fragment.
    220      *
    221      * @return Interpolators
    222      */
    223     public Interpolator[] getInterpolators() {
    224         return mInterpolators;
    225     }
    226 
    227     /**
    228      * Return the animation path for the 'in' (shrinking) animation.
    229      *
    230      * @return
    231      */
    232     public Path getPathIn() {
    233         return mPathIn;
    234     }
    235 
    236     /**
    237      * Return the animation path for the 'out' (growing) animation.
    238      *
    239      * @return
    240      */
    241     public Path getPathOut() {
    242         return mPathOut;
    243     }
    244 }