| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.support.graphics.drawable; |
| |
| import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; |
| |
| import android.content.Context; |
| import android.content.res.Resources; |
| import android.content.res.Resources.NotFoundException; |
| import android.content.res.Resources.Theme; |
| import android.content.res.XmlResourceParser; |
| import android.os.Build; |
| import android.support.annotation.RestrictTo; |
| import android.support.v4.view.animation.FastOutLinearInInterpolator; |
| import android.support.v4.view.animation.FastOutSlowInInterpolator; |
| import android.support.v4.view.animation.LinearOutSlowInInterpolator; |
| import android.util.AttributeSet; |
| import android.util.Xml; |
| import android.view.animation.AccelerateDecelerateInterpolator; |
| import android.view.animation.AccelerateInterpolator; |
| import android.view.animation.AnimationUtils; |
| import android.view.animation.AnticipateInterpolator; |
| import android.view.animation.AnticipateOvershootInterpolator; |
| import android.view.animation.BounceInterpolator; |
| import android.view.animation.CycleInterpolator; |
| import android.view.animation.DecelerateInterpolator; |
| import android.view.animation.Interpolator; |
| import android.view.animation.LinearInterpolator; |
| import android.view.animation.OvershootInterpolator; |
| |
| import org.xmlpull.v1.XmlPullParser; |
| import org.xmlpull.v1.XmlPullParserException; |
| |
| import java.io.IOException; |
| |
| /** |
| * Defines common utilities for working with animations. |
| * @hide |
| */ |
| @RestrictTo(LIBRARY_GROUP) |
| public class AnimationUtilsCompat { |
| /** |
| * Loads an {@link Interpolator} object from a resource |
| * |
| * @param context Application context used to access resources |
| * @param id The resource id of the animation to load |
| * @return The animation object reference by the specified id |
| */ |
| public static Interpolator loadInterpolator(Context context, int id) |
| throws NotFoundException { |
| // From API 21, we added path Interpolator . |
| if (Build.VERSION.SDK_INT >= 21) { |
| return AnimationUtils.loadInterpolator(context, id); |
| } |
| |
| XmlResourceParser parser = null; |
| try { |
| // Special treatment for the interpolator introduced at API 21. |
| if (id == AndroidResources.FAST_OUT_LINEAR_IN) { |
| return new FastOutLinearInInterpolator(); |
| } else if (id == AndroidResources.FAST_OUT_SLOW_IN) { |
| return new FastOutSlowInInterpolator(); |
| } else if (id == AndroidResources.LINEAR_OUT_SLOW_IN) { |
| return new LinearOutSlowInInterpolator(); |
| } |
| parser = context.getResources().getAnimation(id); |
| return createInterpolatorFromXml(context, context.getResources(), context.getTheme(), |
| parser); |
| } catch (XmlPullParserException ex) { |
| NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" |
| + Integer.toHexString(id)); |
| rnf.initCause(ex); |
| throw rnf; |
| } catch (IOException ex) { |
| NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" |
| + Integer.toHexString(id)); |
| rnf.initCause(ex); |
| throw rnf; |
| } finally { |
| if (parser != null) parser.close(); |
| } |
| |
| } |
| |
| private static Interpolator createInterpolatorFromXml(Context context, Resources res, |
| Theme theme, |
| XmlPullParser parser) |
| throws XmlPullParserException, IOException { |
| |
| Interpolator interpolator = null; |
| |
| // Make sure we are on a start tag. |
| int type; |
| int depth = parser.getDepth(); |
| |
| while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) |
| && type != XmlPullParser.END_DOCUMENT) { |
| |
| if (type != XmlPullParser.START_TAG) { |
| continue; |
| } |
| |
| AttributeSet attrs = Xml.asAttributeSet(parser); |
| |
| String name = parser.getName(); |
| |
| if (name.equals("linearInterpolator")) { |
| interpolator = new LinearInterpolator(); |
| } else if (name.equals("accelerateInterpolator")) { |
| interpolator = new AccelerateInterpolator(context, attrs); |
| } else if (name.equals("decelerateInterpolator")) { |
| interpolator = new DecelerateInterpolator(context, attrs); |
| } else if (name.equals("accelerateDecelerateInterpolator")) { |
| interpolator = new AccelerateDecelerateInterpolator(); |
| } else if (name.equals("cycleInterpolator")) { |
| interpolator = new CycleInterpolator(context, attrs); |
| } else if (name.equals("anticipateInterpolator")) { |
| interpolator = new AnticipateInterpolator(context, attrs); |
| } else if (name.equals("overshootInterpolator")) { |
| interpolator = new OvershootInterpolator(context, attrs); |
| } else if (name.equals("anticipateOvershootInterpolator")) { |
| interpolator = new AnticipateOvershootInterpolator(context, attrs); |
| } else if (name.equals("bounceInterpolator")) { |
| interpolator = new BounceInterpolator(); |
| } else if (name.equals("pathInterpolator")) { |
| interpolator = new PathInterpolatorCompat(context, attrs, parser); |
| } else { |
| throw new RuntimeException("Unknown interpolator name: " + parser.getName()); |
| } |
| } |
| return interpolator; |
| } |
| } |