1faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/* 2faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Copyright (C) 2013 The Android Open Source Project 3faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 4faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Licensed under the Apache License, Version 2.0 (the "License"); 5faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * you may not use this file except in compliance with the License. 6faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * You may obtain a copy of the License at 7faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 8faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * http://www.apache.org/licenses/LICENSE-2.0 9faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 10faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Unless required by applicable law or agreed to in writing, software 11faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * distributed under the License is distributed on an "AS IS" BASIS, 12faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * See the License for the specific language governing permissions and 14faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * limitations under the License. 15faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 166ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 17d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haasepackage android.transition; 18faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 19faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.Animator; 20faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.AnimatorListenerAdapter; 21c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haaseimport android.animation.AnimatorSet; 22faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.ValueAnimator; 23c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haaseimport android.graphics.Color; 249b985721dafaa28d1aa34499d23a83afc6d0a2faChet Haaseimport android.util.Log; 25faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewGroup; 26d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haaseimport android.widget.EditText; 27faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.widget.TextView; 28faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2908735185f8105710e18ad02297461bec9268e514Chet Haaseimport java.util.Map; 30faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 31faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/** 32faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This transition tracks changes to the text in TextView targets. If the text 33faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes between the start and end scenes, the transition ensures that the 34faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * starting text stays until the transition ends, at which point it changes 35faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * to the end text. This is useful in situations where you want to resize a 36faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * text view to its new size before displaying the text that goes there. 37d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 38d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @hide 39faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 40b7a7fc9d233bad507ce893882352618b13647058Chet Haasepublic class ChangeText extends Transition { 419b985721dafaa28d1aa34499d23a83afc6d0a2faChet Haase 429b985721dafaa28d1aa34499d23a83afc6d0a2faChet Haase private static final String LOG_TAG = "TextChange"; 439b985721dafaa28d1aa34499d23a83afc6d0a2faChet Haase 44faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private static final String PROPNAME_TEXT = "android:textchange:text"; 45d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase private static final String PROPNAME_TEXT_SELECTION_START = 46d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase "android:textchange:textSelectionStart"; 47d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase private static final String PROPNAME_TEXT_SELECTION_END = 48d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase "android:textchange:textSelectionEnd"; 49c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase private static final String PROPNAME_TEXT_COLOR = "android:textchange:textColor"; 50faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 51c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase private int mChangeBehavior = CHANGE_BEHAVIOR_KEEP; 52c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase 53c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase /** 54c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * Flag specifying that the text in affected/changing TextView targets will keep 55c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * their original text during the transition, setting it to the final text when 56c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * the transition ends. This is the default behavior. 57c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * 58c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * @see #setChangeBehavior(int) 59c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase */ 60c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase public static final int CHANGE_BEHAVIOR_KEEP = 0; 61c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase /** 62c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * Flag specifying that the text changing animation should first fade 63c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * out the original text completely. The new text is set on the target 64c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * view at the end of the fade-out animation. This transition is typically 65c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * used with a later {@link #CHANGE_BEHAVIOR_IN} transition, allowing more 66c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * flexibility than the {@link #CHANGE_BEHAVIOR_OUT_IN} by allowing other 67c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * transitions to be run sequentially or in parallel with these fades. 68c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * 69c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * @see #setChangeBehavior(int) 70c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase */ 71c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase public static final int CHANGE_BEHAVIOR_OUT = 1; 72c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase /** 73c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * Flag specifying that the text changing animation should fade in the 74c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * end text into the affected target view(s). This transition is typically 75c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * used in conjunction with an earlier {@link #CHANGE_BEHAVIOR_OUT} 76c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * transition, possibly with other transitions running as well, such as 77c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * a sequence to fade out, then resize the view, then fade in. 78c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * 79c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * @see #setChangeBehavior(int) 80c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase */ 81c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase public static final int CHANGE_BEHAVIOR_IN = 2; 82c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase /** 83c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * Flag specifying that the text changing animation should first fade 84c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * out the original text completely and then fade in the 85c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * new text. 86c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * 87c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * @see #setChangeBehavior(int) 88c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase */ 89c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase public static final int CHANGE_BEHAVIOR_OUT_IN = 3; 90c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase 91af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase private static final String[] sTransitionProperties = { 92d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase PROPNAME_TEXT, 93d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase PROPNAME_TEXT_SELECTION_START, 94d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase PROPNAME_TEXT_SELECTION_END 95af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase }; 96af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase 97c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase /** 98c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * Sets the type of changing animation that will be run, one of 99d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #CHANGE_BEHAVIOR_KEEP}, {@link #CHANGE_BEHAVIOR_OUT}, 100d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #CHANGE_BEHAVIOR_IN}, and {@link #CHANGE_BEHAVIOR_OUT_IN}. 101c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * 102c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * @param changeBehavior The type of fading animation to use when this 103c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase * transition is run. 104d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return this textChange object. 105c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase */ 106b7a7fc9d233bad507ce893882352618b13647058Chet Haase public ChangeText setChangeBehavior(int changeBehavior) { 107c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase if (changeBehavior >= CHANGE_BEHAVIOR_KEEP && changeBehavior <= CHANGE_BEHAVIOR_OUT_IN) { 108c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase mChangeBehavior = changeBehavior; 109c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 110d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 111c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 112faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 113faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 114af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase public String[] getTransitionProperties() { 115af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase return sTransitionProperties; 116af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase } 117af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase 118d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 119d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Returns the type of changing animation that will be run. 120d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 121d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return either {@link #CHANGE_BEHAVIOR_KEEP}, {@link #CHANGE_BEHAVIOR_OUT}, 122d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #CHANGE_BEHAVIOR_IN}, or {@link #CHANGE_BEHAVIOR_OUT_IN}. 123d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 124d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public int getChangeBehavior() { 125d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return mChangeBehavior; 126d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 127d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 128d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase private void captureValues(TransitionValues transitionValues) { 129d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (transitionValues.view instanceof TextView) { 130d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase TextView textview = (TextView) transitionValues.view; 131d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase transitionValues.values.put(PROPNAME_TEXT, textview.getText()); 132d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase if (textview instanceof EditText) { 133d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase transitionValues.values.put(PROPNAME_TEXT_SELECTION_START, 134d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase textview.getSelectionStart()); 135d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase transitionValues.values.put(PROPNAME_TEXT_SELECTION_END, 136d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase textview.getSelectionEnd()); 137d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 138c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase if (mChangeBehavior > CHANGE_BEHAVIOR_KEEP) { 139d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase transitionValues.values.put(PROPNAME_TEXT_COLOR, textview.getCurrentTextColor()); 140c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 141faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 142faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 143faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 144faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 145d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public void captureStartValues(TransitionValues transitionValues) { 146d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureValues(transitionValues); 147d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 148d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 149d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase @Override 150d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public void captureEndValues(TransitionValues transitionValues) { 151d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureValues(transitionValues); 152d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 153d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 154d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase @Override 155d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, 156faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues endValues) { 1578529b30b91a3af235cda52ea0889ae9af7590129Chet Haase if (startValues == null || endValues == null || 1588529b30b91a3af235cda52ea0889ae9af7590129Chet Haase !(startValues.view instanceof TextView) || !(endValues.view instanceof TextView)) { 159faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return null; 160faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 161faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase final TextView view = (TextView) endValues.view; 16208735185f8105710e18ad02297461bec9268e514Chet Haase Map<String, Object> startVals = startValues.values; 16308735185f8105710e18ad02297461bec9268e514Chet Haase Map<String, Object> endVals = endValues.values; 1648529b30b91a3af235cda52ea0889ae9af7590129Chet Haase final CharSequence startText = startVals.get(PROPNAME_TEXT) != null ? 1658529b30b91a3af235cda52ea0889ae9af7590129Chet Haase (CharSequence) startVals.get(PROPNAME_TEXT) : ""; 1668529b30b91a3af235cda52ea0889ae9af7590129Chet Haase final CharSequence endText = endVals.get(PROPNAME_TEXT) != null ? 1678529b30b91a3af235cda52ea0889ae9af7590129Chet Haase (CharSequence) endVals.get(PROPNAME_TEXT) : ""; 168d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase final int startSelectionStart, startSelectionEnd, endSelectionStart, endSelectionEnd; 169d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase if (view instanceof EditText) { 170d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase startSelectionStart = startVals.get(PROPNAME_TEXT_SELECTION_START) != null ? 171d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase (Integer) startVals.get(PROPNAME_TEXT_SELECTION_START) : -1; 172d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase startSelectionEnd = startVals.get(PROPNAME_TEXT_SELECTION_END) != null ? 173d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase (Integer) startVals.get(PROPNAME_TEXT_SELECTION_END) : startSelectionStart; 174d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase endSelectionStart = endVals.get(PROPNAME_TEXT_SELECTION_START) != null ? 175d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase (Integer) endVals.get(PROPNAME_TEXT_SELECTION_START) : -1; 176d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase endSelectionEnd = endVals.get(PROPNAME_TEXT_SELECTION_END) != null ? 177d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase (Integer) endVals.get(PROPNAME_TEXT_SELECTION_END) : endSelectionStart; 178d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } else { 179d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase startSelectionStart = startSelectionEnd = endSelectionStart = endSelectionEnd = -1; 180d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 181faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (!startText.equals(endText)) { 182aa006133228facf2f9b61e0492fd8f724fac472fChet Haase final int startColor; 183aa006133228facf2f9b61e0492fd8f724fac472fChet Haase final int endColor; 184b7a7fc9d233bad507ce893882352618b13647058Chet Haase if (mChangeBehavior != CHANGE_BEHAVIOR_IN) { 185b7a7fc9d233bad507ce893882352618b13647058Chet Haase view.setText(startText); 186b7a7fc9d233bad507ce893882352618b13647058Chet Haase if (view instanceof EditText) { 187b7a7fc9d233bad507ce893882352618b13647058Chet Haase setSelection(((EditText) view), startSelectionStart, startSelectionEnd); 188b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 189d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 190c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase Animator anim; 191c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase if (mChangeBehavior == CHANGE_BEHAVIOR_KEEP) { 192aa006133228facf2f9b61e0492fd8f724fac472fChet Haase startColor = endColor = 0; 193c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase anim = ValueAnimator.ofFloat(0, 1); 194c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase anim.addListener(new AnimatorListenerAdapter() { 195c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase @Override 196c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase public void onAnimationEnd(Animator animation) { 197af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (startText.equals(view.getText())) { 198af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase // Only set if it hasn't been changed since anim started 199af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase view.setText(endText); 200d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase if (view instanceof EditText) { 201d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase setSelection(((EditText) view), endSelectionStart, endSelectionEnd); 202d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 203af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase } 204c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 205c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase }); 206c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } else { 207aa006133228facf2f9b61e0492fd8f724fac472fChet Haase startColor = (Integer) startVals.get(PROPNAME_TEXT_COLOR); 208aa006133228facf2f9b61e0492fd8f724fac472fChet Haase endColor = (Integer) endVals.get(PROPNAME_TEXT_COLOR); 209c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase // Fade out start text 210c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase ValueAnimator outAnim = null, inAnim = null; 211c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase if (mChangeBehavior == CHANGE_BEHAVIOR_OUT_IN || 212c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase mChangeBehavior == CHANGE_BEHAVIOR_OUT) { 213bbeafd1199fc12b57b32b2e86820e227b3efd149Doris Liu outAnim = ValueAnimator.ofInt(Color.alpha(startColor), 0); 214c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase outAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 215c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase @Override 216c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase public void onAnimationUpdate(ValueAnimator animation) { 217c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase int currAlpha = (Integer) animation.getAnimatedValue(); 218bbeafd1199fc12b57b32b2e86820e227b3efd149Doris Liu view.setTextColor(currAlpha << 24 | startColor & 0xffffff); 219c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 220c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase }); 221c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase outAnim.addListener(new AnimatorListenerAdapter() { 222c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase @Override 223c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase public void onAnimationEnd(Animator animation) { 224af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (startText.equals(view.getText())) { 225af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase // Only set if it hasn't been changed since anim started 226af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase view.setText(endText); 227d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase if (view instanceof EditText) { 228d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase setSelection(((EditText) view), endSelectionStart, 229d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase endSelectionEnd); 230d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 231af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase } 232b7a7fc9d233bad507ce893882352618b13647058Chet Haase // restore opaque alpha and correct end color 233b7a7fc9d233bad507ce893882352618b13647058Chet Haase view.setTextColor(endColor); 234c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 235c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase }); 236c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 237c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase if (mChangeBehavior == CHANGE_BEHAVIOR_OUT_IN || 238c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase mChangeBehavior == CHANGE_BEHAVIOR_IN) { 239bbeafd1199fc12b57b32b2e86820e227b3efd149Doris Liu inAnim = ValueAnimator.ofInt(0, Color.alpha(endColor)); 240c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase inAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 241c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase @Override 242c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase public void onAnimationUpdate(ValueAnimator animation) { 243c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase int currAlpha = (Integer) animation.getAnimatedValue(); 244bbeafd1199fc12b57b32b2e86820e227b3efd149Doris Liu view.setTextColor(currAlpha << 24 | endColor & 0xffffff); 245c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 246c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase }); 247b7a7fc9d233bad507ce893882352618b13647058Chet Haase inAnim.addListener(new AnimatorListenerAdapter() { 248b7a7fc9d233bad507ce893882352618b13647058Chet Haase @Override 249b7a7fc9d233bad507ce893882352618b13647058Chet Haase public void onAnimationCancel(Animator animation) { 250b7a7fc9d233bad507ce893882352618b13647058Chet Haase // restore opaque alpha and correct end color 251b7a7fc9d233bad507ce893882352618b13647058Chet Haase view.setTextColor(endColor); 252b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 253b7a7fc9d233bad507ce893882352618b13647058Chet Haase }); 254c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 255c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase if (outAnim != null && inAnim != null) { 256c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase anim = new AnimatorSet(); 257c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase ((AnimatorSet) anim).playSequentially(outAnim, inAnim); 258c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } else if (outAnim != null) { 259c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase anim = outAnim; 260c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } else { 261c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase // Must be an in-only animation 262c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase anim = inAnim; 263faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 264c81a8493884c7f432d6bd5b98aca3fbdc93b355bChet Haase } 265af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase TransitionListener transitionListener = new TransitionListenerAdapter() { 266b7a7fc9d233bad507ce893882352618b13647058Chet Haase int mPausedColor = 0; 267af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase 268af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase @Override 269af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase public void onTransitionPause(Transition transition) { 270b7a7fc9d233bad507ce893882352618b13647058Chet Haase if (mChangeBehavior != CHANGE_BEHAVIOR_IN) { 271b7a7fc9d233bad507ce893882352618b13647058Chet Haase view.setText(endText); 272b7a7fc9d233bad507ce893882352618b13647058Chet Haase if (view instanceof EditText) { 273b7a7fc9d233bad507ce893882352618b13647058Chet Haase setSelection(((EditText) view), endSelectionStart, endSelectionEnd); 274b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 275b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 276b7a7fc9d233bad507ce893882352618b13647058Chet Haase if (mChangeBehavior > CHANGE_BEHAVIOR_KEEP) { 277b7a7fc9d233bad507ce893882352618b13647058Chet Haase mPausedColor = view.getCurrentTextColor(); 278b7a7fc9d233bad507ce893882352618b13647058Chet Haase view.setTextColor(endColor); 279d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 280af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase } 281af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase 282af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase @Override 283af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase public void onTransitionResume(Transition transition) { 284b7a7fc9d233bad507ce893882352618b13647058Chet Haase if (mChangeBehavior != CHANGE_BEHAVIOR_IN) { 285b7a7fc9d233bad507ce893882352618b13647058Chet Haase view.setText(startText); 286b7a7fc9d233bad507ce893882352618b13647058Chet Haase if (view instanceof EditText) { 287b7a7fc9d233bad507ce893882352618b13647058Chet Haase setSelection(((EditText) view), startSelectionStart, startSelectionEnd); 288b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 289b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 290b7a7fc9d233bad507ce893882352618b13647058Chet Haase if (mChangeBehavior > CHANGE_BEHAVIOR_KEEP) { 291b7a7fc9d233bad507ce893882352618b13647058Chet Haase view.setTextColor(mPausedColor); 292d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 293af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase } 29425f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount 29525f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount @Override 29625f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount public void onTransitionEnd(Transition transition) { 29725f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount transition.removeListener(this); 29825f98a4c0156ec40d1d92cfe5a24459d9ffa6f91George Mount } 299af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase }; 300af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase addListener(transitionListener); 3019b985721dafaa28d1aa34499d23a83afc6d0a2faChet Haase if (DBG) { 3029b985721dafaa28d1aa34499d23a83afc6d0a2faChet Haase Log.d(LOG_TAG, "createAnimator returning " + anim); 3039b985721dafaa28d1aa34499d23a83afc6d0a2faChet Haase } 304faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return anim; 305faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 306faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return null; 307faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 308d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase 309d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase private void setSelection(EditText editText, int start, int end) { 310d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase if (start >= 0 && end >= 0) { 311d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase editText.setSelection(start, end); 312d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 313d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 314faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase} 315