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 com.android.systemui.statusbar.notification; 18 19 import android.text.Layout; 20 import android.text.Spanned; 21 import android.text.TextUtils; 22 import android.util.Pools; 23 import android.view.View; 24 import android.widget.TextView; 25 26 /** 27 * A transform state of a mText view. 28 */ 29 public class TextViewTransformState extends TransformState { 30 31 private static Pools.SimplePool<TextViewTransformState> sInstancePool 32 = new Pools.SimplePool<>(40); 33 private TextView mText; 34 35 @Override initFrom(View view, TransformInfo transformInfo)36 public void initFrom(View view, TransformInfo transformInfo) { 37 super.initFrom(view, transformInfo); 38 mText = (TextView) view; 39 } 40 41 @Override sameAs(TransformState otherState)42 protected boolean sameAs(TransformState otherState) { 43 if (super.sameAs(otherState)) { 44 return true; 45 } 46 if (otherState instanceof TextViewTransformState) { 47 TextViewTransformState otherTvs = (TextViewTransformState) otherState; 48 if(TextUtils.equals(otherTvs.mText.getText(), mText.getText())) { 49 int ownEllipsized = getEllipsisCount(); 50 int otherEllipsized = otherTvs.getEllipsisCount(); 51 return ownEllipsized == otherEllipsized 52 && mText.getLineCount() == otherTvs.mText.getLineCount() 53 && hasSameSpans(otherTvs); 54 } 55 } 56 return false; 57 } 58 hasSameSpans(TextViewTransformState otherTvs)59 private boolean hasSameSpans(TextViewTransformState otherTvs) { 60 boolean hasSpans = mText instanceof Spanned; 61 boolean otherHasSpans = otherTvs.mText instanceof Spanned; 62 if (hasSpans != otherHasSpans) { 63 return false; 64 } else if (!hasSpans) { 65 return true; 66 } 67 // Actually both have spans, let's try to compare them 68 Spanned ownSpanned = (Spanned) mText; 69 Object[] spans = ownSpanned.getSpans(0, ownSpanned.length(), Object.class); 70 Spanned otherSpanned = (Spanned) otherTvs.mText; 71 Object[] otherSpans = otherSpanned.getSpans(0, otherSpanned.length(), Object.class); 72 if (spans.length != otherSpans.length) { 73 return false; 74 } 75 for (int i = 0; i < spans.length; i++) { 76 Object span = spans[i]; 77 Object otherSpan = otherSpans[i]; 78 if (!span.getClass().equals(otherSpan.getClass())) { 79 return false; 80 } 81 if (ownSpanned.getSpanStart(span) != otherSpanned.getSpanStart(otherSpan) 82 || ownSpanned.getSpanEnd(span) != otherSpanned.getSpanEnd(otherSpan)) { 83 return false; 84 } 85 } 86 return true; 87 } 88 89 @Override transformScale(TransformState otherState)90 protected boolean transformScale(TransformState otherState) { 91 if (!(otherState instanceof TextViewTransformState)) { 92 return false; 93 } 94 TextViewTransformState otherTvs = (TextViewTransformState) otherState; 95 if (!TextUtils.equals(mText.getText(), otherTvs.mText.getText())) { 96 return false; 97 } 98 int lineCount = mText.getLineCount(); 99 return lineCount == 1 && lineCount == otherTvs.mText.getLineCount() 100 && getEllipsisCount() == otherTvs.getEllipsisCount() 101 && getViewHeight() != otherTvs.getViewHeight(); 102 } 103 104 @Override getViewWidth()105 protected int getViewWidth() { 106 Layout l = mText.getLayout(); 107 if (l != null) { 108 return (int) l.getLineWidth(0); 109 } 110 return super.getViewWidth(); 111 } 112 113 @Override getViewHeight()114 protected int getViewHeight() { 115 return mText.getLineHeight(); 116 } 117 getInnerHeight(TextView text)118 private int getInnerHeight(TextView text) { 119 return text.getHeight() - text.getPaddingTop() - text.getPaddingBottom(); 120 } 121 getEllipsisCount()122 private int getEllipsisCount() { 123 Layout l = mText.getLayout(); 124 if (l != null) { 125 int lines = l.getLineCount(); 126 if (lines > 0) { 127 // we only care about the first line 128 return l.getEllipsisCount(0); 129 } 130 } 131 return 0; 132 } 133 obtain()134 public static TextViewTransformState obtain() { 135 TextViewTransformState instance = sInstancePool.acquire(); 136 if (instance != null) { 137 return instance; 138 } 139 return new TextViewTransformState(); 140 } 141 142 @Override recycle()143 public void recycle() { 144 super.recycle(); 145 sInstancePool.release(this); 146 } 147 148 @Override reset()149 protected void reset() { 150 super.reset(); 151 mText = null; 152 } 153 } 154