EllipsizedMultilineTextView.java revision 20347e439dc5e2c86bc105d432c64f6e7f69c7cc
1c046e4a310462aa6998a34ff50439eb5e2508d85mindyp/* 2c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * Copyright (C) 2013 Google Inc. 3c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * Licensed to The Android Open Source Project. 4c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * 5c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * Licensed under the Apache License, Version 2.0 (the "License"); 6c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * you may not use this file except in compliance with the License. 7c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * You may obtain a copy of the License at 8c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * 9c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * http://www.apache.org/licenses/LICENSE-2.0 10c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * 11c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * Unless required by applicable law or agreed to in writing, software 12c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * distributed under the License is distributed on an "AS IS" BASIS, 13c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * See the License for the specific language governing permissions and 15c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * limitations under the License. 16c046e4a310462aa6998a34ff50439eb5e2508d85mindyp */ 17c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 18c046e4a310462aa6998a34ff50439eb5e2508d85mindyppackage com.android.mail.ui; 19c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 20c046e4a310462aa6998a34ff50439eb5e2508d85mindypimport android.content.Context; 21c046e4a310462aa6998a34ff50439eb5e2508d85mindypimport android.text.Layout; 22c046e4a310462aa6998a34ff50439eb5e2508d85mindypimport android.text.SpannableStringBuilder; 23c046e4a310462aa6998a34ff50439eb5e2508d85mindypimport android.text.TextUtils; 24c046e4a310462aa6998a34ff50439eb5e2508d85mindypimport android.util.AttributeSet; 25c046e4a310462aa6998a34ff50439eb5e2508d85mindypimport android.widget.TextView; 26c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 27c046e4a310462aa6998a34ff50439eb5e2508d85mindyp/** 28c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * A special MultiLine TextView that will apply ellipsize logic to only the last 29c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * line of text, such that the last line may be shorter than any previous lines. 30c046e4a310462aa6998a34ff50439eb5e2508d85mindyp */ 31c046e4a310462aa6998a34ff50439eb5e2508d85mindyppublic class EllipsizedMultilineTextView extends TextView { 32c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 33c046e4a310462aa6998a34ff50439eb5e2508d85mindyp public static final int ALL_AVAILABLE = -1; 34c046e4a310462aa6998a34ff50439eb5e2508d85mindyp private int mMaxLines; 35c046e4a310462aa6998a34ff50439eb5e2508d85mindyp private int mLastWSpec; 36c046e4a310462aa6998a34ff50439eb5e2508d85mindyp private int mLastHSpec; 37c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 38c046e4a310462aa6998a34ff50439eb5e2508d85mindyp public EllipsizedMultilineTextView(Context context) { 39c046e4a310462aa6998a34ff50439eb5e2508d85mindyp this(context, null); 40c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 41c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 42c046e4a310462aa6998a34ff50439eb5e2508d85mindyp public EllipsizedMultilineTextView(Context context, AttributeSet attrs) { 43c046e4a310462aa6998a34ff50439eb5e2508d85mindyp super(context, attrs); 44c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 45c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 46c046e4a310462aa6998a34ff50439eb5e2508d85mindyp @Override 47c046e4a310462aa6998a34ff50439eb5e2508d85mindyp public void setMaxLines(int maxlines) { 48c046e4a310462aa6998a34ff50439eb5e2508d85mindyp super.setMaxLines(maxlines); 49c046e4a310462aa6998a34ff50439eb5e2508d85mindyp mMaxLines = maxlines; 50c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 51c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 52c046e4a310462aa6998a34ff50439eb5e2508d85mindyp @Override 53c046e4a310462aa6998a34ff50439eb5e2508d85mindyp protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 54c046e4a310462aa6998a34ff50439eb5e2508d85mindyp super.onMeasure(widthMeasureSpec, heightMeasureSpec); 55c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 56c046e4a310462aa6998a34ff50439eb5e2508d85mindyp mLastWSpec = widthMeasureSpec; 57c046e4a310462aa6998a34ff50439eb5e2508d85mindyp mLastHSpec = heightMeasureSpec; 58c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 59c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 60c046e4a310462aa6998a34ff50439eb5e2508d85mindyp /** 61c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * Ellipsize just the last line of text in this view and set the text to the 62c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * new ellipsized value. 63c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * @param text Text to set and ellipsize 64c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * @param avail available width in pixels for the last line 65c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * @param paint Paint that has the proper properties set to measure the text 66c046e4a310462aa6998a34ff50439eb5e2508d85mindyp * for this view 67c046e4a310462aa6998a34ff50439eb5e2508d85mindyp */ 68c046e4a310462aa6998a34ff50439eb5e2508d85mindyp public void setText(final CharSequence text, int avail) { 69c046e4a310462aa6998a34ff50439eb5e2508d85mindyp if (text == null || text.length() == 0) { 70c046e4a310462aa6998a34ff50439eb5e2508d85mindyp return; 71c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 72c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 73c046e4a310462aa6998a34ff50439eb5e2508d85mindyp setEllipsize(null); 74c046e4a310462aa6998a34ff50439eb5e2508d85mindyp setText(text, TextView.BufferType.SPANNABLE); 75c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 76c046e4a310462aa6998a34ff50439eb5e2508d85mindyp if (avail == ALL_AVAILABLE) { 77c046e4a310462aa6998a34ff50439eb5e2508d85mindyp return; 78c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 79c046e4a310462aa6998a34ff50439eb5e2508d85mindyp Layout layout = getLayout(); 80c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 81c046e4a310462aa6998a34ff50439eb5e2508d85mindyp if (layout == null) { 82c046e4a310462aa6998a34ff50439eb5e2508d85mindyp measure(mLastWSpec, mLastHSpec); 83c046e4a310462aa6998a34ff50439eb5e2508d85mindyp layout = getLayout(); 84c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 85c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 86c046e4a310462aa6998a34ff50439eb5e2508d85mindyp if (layout == null) { 87c046e4a310462aa6998a34ff50439eb5e2508d85mindyp // Bail 88c046e4a310462aa6998a34ff50439eb5e2508d85mindyp return; 89c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 90c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 91c046e4a310462aa6998a34ff50439eb5e2508d85mindyp CharSequence remainder; 92c046e4a310462aa6998a34ff50439eb5e2508d85mindyp SpannableStringBuilder builder = new SpannableStringBuilder(); 93c046e4a310462aa6998a34ff50439eb5e2508d85mindyp int lineCount = layout.getLineCount(); 94c046e4a310462aa6998a34ff50439eb5e2508d85mindyp if (lineCount <= mMaxLines) { 95c046e4a310462aa6998a34ff50439eb5e2508d85mindyp remainder = null; 96c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } else { 97c046e4a310462aa6998a34ff50439eb5e2508d85mindyp remainder = TextUtils.ellipsize( 98c046e4a310462aa6998a34ff50439eb5e2508d85mindyp text.subSequence(layout.getLineStart(mMaxLines - 1), text.length()), 99c046e4a310462aa6998a34ff50439eb5e2508d85mindyp getPaint(), avail, TextUtils.TruncateAt.END); 100c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 101c046e4a310462aa6998a34ff50439eb5e2508d85mindyp 102c046e4a310462aa6998a34ff50439eb5e2508d85mindyp builder.append(text, 0, layout.getLineStart(mMaxLines - 1)); 10320347e439dc5e2c86bc105d432c64f6e7f69c7ccAndy Huang if (!TextUtils.isEmpty(remainder)) { 10420347e439dc5e2c86bc105d432c64f6e7f69c7ccAndy Huang builder.append(remainder); 105c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 106c046e4a310462aa6998a34ff50439eb5e2508d85mindyp setText(builder, TextView.BufferType.SPANNABLE); 107c046e4a310462aa6998a34ff50439eb5e2508d85mindyp } 108c046e4a310462aa6998a34ff50439eb5e2508d85mindyp}