天天看點

TextView顯示不全問題分析

TextView的singleLine和lines方法分析

記錄問題歡迎指教。

我是用權重分割了TextView然後在TextView上做了單行的限制,可是在不同的資料上顯示出不一樣的效果:

下面是我的TextView,這裡除了使用權重外并沒有其他的特别之處。

<TextView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:ellipsize="end"
            android:gravity="center"
            android:singleLine="true"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:textSize="20sp" />
           

五羊(FIVERAMS)嬰兒洗發沐浴露二合一 哈哈哈哈哈哈 懷疑是這個名字中使用了中文括号導緻。

然後我嘗試修改文字長度都不能解決,但是去掉中文的括号後是可以解決的,非常奇怪。

上面并不能解決實際問題,是以要在繼續找問題,把TextView的屬性都去掉,最後發現問題在控制文字是不是單行的上面,我以前用的是android:maxLines=”1”,後來改成android:singleLine=”true”,居然就好了。

注意:在使用權重的時候盡量在裡面多一層view,并且設定單行盡量使用setSingleLine(雖然提示我們已經過時的方法,),這樣可以避免一些詭異的東西。

下面簡單看一下源碼

主要分析三個方法:setMaxLines() ; setLines();setSingleLine();(無參數預設是true)

第一個和第二個方法類似,主要是設定模式和重新布局和重新整理:

public void setLines(int lines) {
        mMaximum = mMinimum = lines;
        mMaxMode = mMinMode = LINES;

        requestLayout();
        invalidate();
    }


 @android.view.RemotableViewMethod
    public void setMaxLines(int maxlines) {
        mMaximum = maxlines;
        mMaxMode = LINES;

        requestLayout();
        invalidate();
    }
           

第三個方法就複雜很多,設定了除上面參數外的其他東西:

public void setSingleLine() {
        setSingleLine(true);
    }

    @android.view.RemotableViewMethod
    public void setSingleLine(boolean singleLine) {
        // Could be used, but may break backward compatibility.
        // if (mSingleLine == singleLine) return;
        //這裡調用了兩個方法,第一個可以看出,是設定輸入類型(edittext使用),第二個是應用單行模式
        setInputTypeSingleLine(singleLine);
        applySingleLine(singleLine, true, true);
    }


/**
     * Adds or remove the EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE on the mInputType.
     * @param singleLine
     */
    private void setInputTypeSingleLine(boolean singleLine) {
        if (mEditor != null &&
                (mEditor.mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
                //這設定mEditor的輸入方式
            if (singleLine) {
                mEditor.mInputType &= ~EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
            } else {
                mEditor.mInputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
            }
        }
    }
           

下面這個applySingleLine方法是重點了:

private void applySingleLine(boolean singleLine, boolean applyTransformation,
            boolean changeMaxLines) {
        mSingleLine = singleLine;
  //這裡調用了設定單行的方法,設定可以橫向滾動
        if (singleLine) {
            setLines();
            setHorizontallyScrolling(true);
            if (applyTransformation) {
             setTransformationMethod(SingleLineTransformationMethod.getInstance());
            }
        } else {
            if (changeMaxLines) {
                setMaxLines(Integer.MAX_VALUE);
            }
            setHorizontallyScrolling(false);
            if (applyTransformation) {
                setTransformationMethod(null);
            }
        }
    }
           

在下面是另外的主要方法setTransformationMethod,調用了setText()把文字設定進去了:

public final void setTransformationMethod(TransformationMethod method) {
        if (method == mTransformation) {
            // Avoid the setText() below if the transformation is
            // the same.
            return;
        }
  //對字元串進行了處理
        if (mTransformation != null) {
            if (mText instanceof Spannable) {
                ((Spannable) mText).removeSpan(mTransformation);
            }
        }

        mTransformation = method;

        if (method instanceof TransformationMethod2) {
            TransformationMethod2 method2 = (TransformationMethod2) method;
            mAllowTransformationLengthChange = !isTextSelectable() && !(mText instanceof Editable);
            method2.setLengthChangesAllowed(mAllowTransformationLengthChange);
        } else {
            mAllowTransformationLengthChange = false;
        }

        setText(mText);

        if (hasPasswordTransformationMethod()) {
            notifyViewAccessibilityStateChangedIfNeeded(
                    AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
        }

        // PasswordTransformationMethod always have LTR text direction heuristics returned by
        // getTextDirectionHeuristic, needs reset
        mTextDir = getTextDirectionHeuristic();
    }
           

上面可以看出setSingleLine()做了很多的工作,有一些并不是和TextView相關。對字元串進行了一些處理。

這也是三個方法中很重要的差別,猜想是這裡引起的。

繼續閱讀