1608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount/* 2608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * Copyright (C) 2014 The Android Open Source Project 3608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * 4608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * Licensed under the Apache License, Version 2.0 (the "License"); 5608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * you may not use this file except in compliance with the License. 6608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * You may obtain a copy of the License at 7608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * 8608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * http://www.apache.org/licenses/LICENSE-2.0 9608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * 10608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * Unless required by applicable law or agreed to in writing, software 11608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * distributed under the License is distributed on an "AS IS" BASIS, 12608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * See the License for the specific language governing permissions and 14608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * limitations under the License. 15608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount */ 16608b87d9e57b71a86374a439bf5c3febd1e142f2George Mountpackage android.transition; 17608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 18608b87d9e57b71a86374a439bf5c3febd1e142f2George Mountimport android.animation.Animator; 19608b87d9e57b71a86374a439bf5c3febd1e142f2George Mountimport android.animation.ObjectAnimator; 20608b87d9e57b71a86374a439bf5c3febd1e142f2George Mountimport android.animation.RectEvaluator; 21ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.content.Context; 22608b87d9e57b71a86374a439bf5c3febd1e142f2George Mountimport android.graphics.Rect; 23ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.util.AttributeSet; 24608b87d9e57b71a86374a439bf5c3febd1e142f2George Mountimport android.view.View; 25608b87d9e57b71a86374a439bf5c3febd1e142f2George Mountimport android.view.ViewGroup; 26608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 27608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount/** 28608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * ChangeClipBounds captures the {@link android.view.View#getClipBounds()} before and after the 29608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * scene change and animates those changes during the transition. 30608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount */ 31608b87d9e57b71a86374a439bf5c3febd1e142f2George Mountpublic class ChangeClipBounds extends Transition { 32608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 33608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount private static final String TAG = "ChangeTransform"; 34608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 35608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount private static final String PROPNAME_CLIP = "android:clipBounds:clip"; 36608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount private static final String PROPNAME_BOUNDS = "android:clipBounds:bounds"; 37608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 38608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount private static final String[] sTransitionProperties = { 39608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount PROPNAME_CLIP, 40608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount }; 41608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 42ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount public ChangeClipBounds() {} 43ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 44ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount public ChangeClipBounds(Context context, AttributeSet attrs) { 45ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount super(context, attrs); 46ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 47ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 48608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount @Override 49608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount public String[] getTransitionProperties() { 50608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount return sTransitionProperties; 51608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 52608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 53608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount private void captureValues(TransitionValues values) { 54608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount View view = values.view; 55608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount if (view.getVisibility() == View.GONE) { 56608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount return; 57608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 58608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 59608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount Rect clip = view.getClipBounds(); 60608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount values.values.put(PROPNAME_CLIP, clip); 61608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount if (clip == null) { 62608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount Rect bounds = new Rect(0, 0, view.getWidth(), view.getHeight()); 63608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount values.values.put(PROPNAME_BOUNDS, bounds); 64608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 65608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 66608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 67608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount @Override 68608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount public void captureStartValues(TransitionValues transitionValues) { 69608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount captureValues(transitionValues); 70608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 71608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 72608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount @Override 73608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount public void captureEndValues(TransitionValues transitionValues) { 74608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount captureValues(transitionValues); 75608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 76608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 77608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount @Override 78608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount public Animator createAnimator(final ViewGroup sceneRoot, TransitionValues startValues, 79608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount TransitionValues endValues) { 80608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount if (startValues == null || endValues == null 81608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount || !startValues.values.containsKey(PROPNAME_CLIP) 82608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount || !endValues.values.containsKey(PROPNAME_CLIP)) { 83608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount return null; 84608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 85608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount Rect start = (Rect) startValues.values.get(PROPNAME_CLIP); 86608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount Rect end = (Rect) endValues.values.get(PROPNAME_CLIP); 87608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount if (start == null && end == null) { 88608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount return null; // No animation required since there is no clip. 89608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 90608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 91608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount if (start == null) { 92608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount start = (Rect) startValues.values.get(PROPNAME_BOUNDS); 93608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } else if (end == null) { 94608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount end = (Rect) endValues.values.get(PROPNAME_BOUNDS); 95608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 96608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount if (start.equals(end)) { 97608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount return null; 98608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 99608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount 100608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount endValues.view.setClipBounds(start); 101608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount RectEvaluator evaluator = new RectEvaluator(new Rect()); 102608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount return ObjectAnimator.ofObject(endValues.view, "clipBounds", evaluator, start, end); 103608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount } 104608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount} 105