无法按宽度包装任意行数的blockquote-like TextView

时间:2015-08-19 15:39:43

标签: android android-layout textview

我需要渲染一个任意长度的引用块。文本必须与左边对齐,而块本身与右边对齐,类似于这个: example

为此,我正在尝试TextView android:width="wrap_content"android:gravity="start"android:layout_gravity="end"。但是,只有当文本符合单行时,这才能正常工作 - 如果文本比这长,TextView的行为如下:

  • 第一个引用块只是一个带空格的句子 - 吞噬所有父级的宽度;
  • 第二个区块 - 某些区域没有中断:Raw persistence may be the only option other than giving up entirely. - 区块的行为仍然像match_parent
  • 第3块使用显式换行符 - 看起来最接近需要的换行符,但这是最不灵活的选项,并且右侧还有一些额外的填充。

screenshot

这是布局(paddingRight替换为layout_marginRight以突出显示目的 - 行为是相同的两种方式):

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:lineSpacingExtra="3.5dp"
            android:paddingLeft="24dp"
            android:layout_marginRight="24dp"
            android:text="Raw persistence may be the only option other than giving up entirely."
            />

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:lineSpacingExtra="3.5dp"
            android:paddingLeft="24dp"
            android:layout_marginRight="24dp"
            android:text="Raw&#160;persistence may&#160;be the only&#160;option other&#160;than giving&#160;up&#160;entirely."
            />

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:lineSpacingExtra="3.5dp"
            android:paddingLeft="24dp"
            android:layout_marginRight="24dp"
            android:text="@string/Raw persistence may be the only option\nother than giving up entirely."
            />

</LinearLayout>

有没有办法充分解决这个问题,而不必为不同的设备宽度等使用多个字符串? = \

2 个答案:

答案 0 :(得分:5)

好的,经过对TextView代码的一些检查,我把解决方案整合到了我需要的地方:

package com.actinarium.persistence.common;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.text.Layout;
import android.util.AttributeSet;
import android.widget.TextView;

public class BlockquoteTextView extends TextView {
    public BlockquoteTextView(Context context) {
        super(context);
    }

    public BlockquoteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public BlockquoteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public BlockquoteTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // Now fix width
        float max = 0;
        Layout layout = getLayout();
        for (int i = 0, size = layout.getLineCount(); i < size; i++) {
            final float lineWidth = layout.getLineMax(i);
            if (lineWidth > max) {
                max = lineWidth;
            }
        }

        final int height = getMeasuredHeight();
        final int width = (int) Math.ceil(max) + getCompoundPaddingLeft() + getCompoundPaddingRight();

        setMeasuredDimension(width, height);
    }
}

onMeasure的默认实施不会考虑行宽,除非它们按\ncode)细分。我使用getLineMax而不是getLineWidth,因为后者测量了尾随空格 - 原始帖子中块#3中未对齐的罪魁祸首。

答案 1 :(得分:0)

我不确定这一点,但可以尝试添加像这样的重量的虚拟视图

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="100"
        android:orientation="horizontal">
    <View
    android:layout_height="wrap_content"       
    android:layout_weight="50"
    android:layout_width="0dp"/>
    <TextView
            android:layout_width="0dp"
            android:layout_weight="50"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:lineSpacingExtra="3.5dp"
            android:paddingLeft="24dp"
            android:layout_marginRight="24dp"
            android:text="Raw persistence may be the only option other than giving up entirely."
            />
</LinearLayout>

我从来没有测试过这个试试看......