Android TextView:填充设置为0时的幻像填充

时间:2016-05-19 01:18:24

标签: android textview

我有 text.setTypeface(font); text.setWidth((int)width); text.setGravity(Gravity.CENTER); text.setHeight((int)height); text.setIncludeFontPadding(false); text.setPadding(0,0,0,0);

0

然而,即使将填充设置为setIncludeFontPaddingfalse设置为TextView,我将字体大小设置为text.setPadding(0,-30,0,-30);的高度,我仍然可以得到:< / p>

enter image description here

如果我将填充设置为-30之类的负值,则修复它:

import android.annotation.TargetApi; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; import android.text.Layout; import android.text.Layout.Alignment; import android.text.StaticLayout; import android.text.TextPaint; import android.util.AttributeSet; import android.util.Log; import android.util.SparseIntArray; import android.util.TypedValue; import android.widget.TextView; /** * Special textview which gracefully handles resizing. */ public class iTextView extends TextView { // Set true to remove phantom padding public boolean trimPadding = false; //region Interfaces private interface SizeTester { /** * Interface for scaling text to fit. * @param suggestedSize Size of text to be tested. * @param availableSpace Available space in which text must fit. * @return An integer < 0 if after applying {@code suggestedSize} to * text, it takes less space than {@code availableSpace}, > 0 * otherwise. */ int onTestSize(int suggestedSize, RectF availableSpace); } //endregion //region Variables private static final int NO_LINE_LIMIT = -1; private RectF _textRect = new RectF(); private RectF _availableSpaceRect; private SparseIntArray _textCachedSizes; private TextPaint _paint; private float _maxTextSize; private float _spacingMult; private float _spacingAdd; private float _minTextSize; private int _widthLimit; private int _maxLines; private boolean _enableSizeCache; private boolean _initialized; //endregion //region Constructors public iTextView(Context context) { super(context); initialize(); } public iTextView(Context context, AttributeSet attrs) { super(context, attrs); initialize(); } public iTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initialize(); } //endregion //region Initialization private void initialize() { _spacingMult = 1.0f; _spacingAdd = 0.0f; _minTextSize = 20; _enableSizeCache = true; _paint = new TextPaint(getPaint()); _maxTextSize = getTextSize(); _availableSpaceRect = new RectF(); _textCachedSizes = new SparseIntArray(); if (_maxLines == 0) { // No value was assigned during construction _maxLines = NO_LINE_LIMIT; } _initialized = true; } //endregion //region Text Value @Override public void setText(final CharSequence text, BufferType type) { super.setText(text, type); adjustTextSize(text.toString()); } @Override protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { super.onTextChanged(text, start, before, after); reAdjust(); } //endregion //region Text Sizing @Override public void setTextSize(float size) { _maxTextSize = size; _textCachedSizes.clear(); adjustTextSize(getText().toString()); } /** * Ensures the text is as big as possible for the text area. */ public void setTextSizeToMaxFit() { _maxTextSize = 999; _textCachedSizes.clear(); adjustTextSize(getText().toString()); } @Override public void setTextSize(int unit, float size) { Context context = getContext(); Resources resources; if (context == null) { resources = Resources.getSystem(); } else { resources = context.getResources(); } _maxTextSize = TypedValue.applyDimension(unit, size, resources.getDisplayMetrics()); _textCachedSizes.clear(); adjustTextSize(getText().toString()); } /** * Set the lower text size limit and invalidate the view * * @param minTextSize */ public void setMinTextSize(float minTextSize) { _minTextSize = minTextSize; reAdjust(); } private void reAdjust() { adjustTextSize(getText().toString()); } private void adjustTextSize(String string) { if (!_initialized) { return; } int startSize = (int) _minTextSize; int heightLimit = getMeasuredHeight() - getCompoundPaddingBottom() - getCompoundPaddingTop(); _widthLimit = getMeasuredWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight(); _availableSpaceRect.right = _widthLimit; _availableSpaceRect.bottom = heightLimit; super.setTextSize ( TypedValue.COMPLEX_UNIT_PX, efficientTextSizeSearch(startSize, (int)_maxTextSize, mSizeTester, _availableSpaceRect) ); } private final SizeTester mSizeTester = new SizeTester() { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public int onTestSize(int suggestedSize, RectF availableSPace) { _paint.setTextSize(suggestedSize); String text = getText().toString(); boolean singleLine = getMaxLines() == 1; if (singleLine) { _textRect.bottom = _paint.getFontSpacing(); _textRect.right = _paint.measureText(text); } else { StaticLayout layout = new StaticLayout ( text, _paint, _widthLimit, Alignment.ALIGN_NORMAL, _spacingMult, _spacingAdd, true ); // Return early if no more lines if (getMaxLines() != NO_LINE_LIMIT && layout.getLineCount() > getMaxLines()) { return 1; } _textRect.bottom = layout.getHeight(); int maxWidth = -1; for (int i = 0; i < layout.getLineCount(); i++) { if (maxWidth < layout.getLineWidth(i)) { maxWidth = (int)layout.getLineWidth(i); } } _textRect.right = maxWidth; } _textRect.offsetTo(0, 0); if (availableSPace.contains(_textRect)) { // May be too small, Will find the best match later return -1; } else { // Too big return 1; } } }; /** * Enables or disables size caching, enabling it will improve performance * where its animating a value inside TextView. This stores the font * size against getText().length() Enabling it as 0 * takes more space than 1 on some fonts and so on. * @param enable Enable font size caching */ public void enableSizeCache(boolean enable) { _enableSizeCache = enable; _textCachedSizes.clear(); adjustTextSize(getText().toString()); } private int efficientTextSizeSearch(int start, int end, SizeTester sizeTester, RectF availableSpace) { if (!_enableSizeCache) { return binarySearch(start, end, sizeTester, availableSpace); } String text = getText().toString(); int key = text == null ? 0 : text.length(); int size = _textCachedSizes.get(key); if (size != 0) { return size; } size = binarySearch(start, end, sizeTester, availableSpace); _textCachedSizes.put(key, size); return size; } @Override protected void onSizeChanged(int width, int height, int oldwidth,int oldheight) { _textCachedSizes.clear(); super.onSizeChanged(width, height, oldwidth, oldheight); if (width != oldwidth || height != oldheight) { reAdjust(); } } private static int binarySearch(int start, int end, SizeTester sizeTester,RectF availableSpace) { int lastBest = start; int low = start; int high = end - 1; int mid = 0; while (low <= high) { mid = (low + high) >>> 1; int midValCmp = sizeTester.onTestSize(mid, availableSpace); if (midValCmp < 0) { lastBest = low; low = mid + 1; } else if (midValCmp > 0) { high = mid - 1; lastBest = high; } else { return mid; } } // Make sure to return last best // This is what should always be returned return lastBest; } //endregion //region Text Lines @Override public void setMaxLines(int maxlines) { super.setMaxLines(maxlines); _maxLines = maxlines; reAdjust(); } public int getMaxLines() { return _maxLines; } @Override public void setSingleLine() { super.setSingleLine(); _maxLines = 1; reAdjust(); } @Override public void setSingleLine(boolean singleLine) { super.setSingleLine(singleLine); if (singleLine) { _maxLines = 1; } else { _maxLines = NO_LINE_LIMIT; } reAdjust(); } @Override public void setLines(int lines) { super.setLines(lines); _maxLines = lines; reAdjust(); } @Override public void setLineSpacing(float add, float mult) { super.setLineSpacing(add, mult); _spacingMult = mult; _spacingAdd = add; } //endregion //region Padding Fix @Override protected void onDraw(Canvas canvas) { if (trimPadding) { trimVertical(); } super.onDraw(canvas); } private void trimVertical() { final Layout layout = getLayout(); final Rect textBounds = new Rect(); if (layout == null) { Log.d("Layout is null","" + layout); return; } int baseline = layout.getLineBaseline(0); getTextBounds(0, textBounds); final int pTop = baseline + textBounds.top; final int lastLine = getLineCount() - 1; baseline = layout.getLineBaseline(lastLine); getTextBounds(lastLine, textBounds); final int pBottom = layout.getHeight() - baseline - textBounds.bottom + 1; setPadding(getPaddingLeft(), -pTop, getPaddingRight(), -pBottom); } private void getTextBounds(int line, Rect bounds) { final String s = getText().toString(); final int start = getLayout().getLineStart(line); final int end = getLayout().getLineEnd(line); getPaint().getTextBounds(s, start, end, bounds); } //endregion }

enter image description here

我的问题是为什么我必须这样做?这个幻影填充来自哪里?我在哪里找到这个任意值(在这个特定情况下为-30)值我需要将其设置为,以便文本填充高度?

更新

尝试@Mike M.的解决方案我得到了这些结果。当它是正数时,它的尺寸小于负数时的尺寸。他们两个仍然有填充: enter image description here enter image description here

更新2 这里是完整的自定义类:

{{1}}

0 个答案:

没有答案