不能用缠绕宽度独断专行计数块引用般的TextView [英] Cannot wrap blockquote-like TextView of arbitrary line count by width

查看:175
本文介绍了不能用缠绕宽度独断专行计数块引用般的TextView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要渲染任意长度的报价块。该文本必须靠左对齐,而块本身相一致的权利,与此类似:

I need to render a quote block of arbitrary length. The text must be aligned to the left, while the block itself aligned to the right, similar to this one:

有关,我试图在的TextView 的android:宽=WRAP_CONTENT安卓重力=开始的android:layout_gravity =结束。然而,这将按预期只有当文本适合单行 - 如果文本比长,的TextView 的行为是这样的:

For that I'm trying a TextView with android:width="wrap_content", android:gravity="start", and android:layout_gravity="end". However, this works as expected only when the text fits into single line — if text is longer than that, the TextView behaves like this:


  • 1日报价块是简单地用空格的句子 - 吞噬所有家长的宽度;

  • 2号地块 - 一些空间是不破: RAW&放大器;#160;持久性可能会&放大器;#160;是唯一和放大器;#160;选择其他&放大器;#160;不是让&安培;#160;向上和;#160;完全 - 仍然块的行为像 match_parent

  • 3号地块使用明确的换行符 - 看起来最接近的需要什么,但是这是最不灵活的选择,而且还是在右边有些微胖

  • 1st quote block is simply a sentence with spaces — devours all parent's width;
  • 2nd block — some spaces are non-breaking: Raw persistence may be the only option other than giving up entirely. — still the block behaves like match_parent.
  • 3rd block uses explicit line break — looks the closest to what's required, however that's the least flexible option, and there's still some extra padding on the right.

屏幕截图

这里的布局( paddingRight layout_marginRight 被替换为亮点的目的 - 的行为是相同的两种方式)

Here's the layout (paddingRight was replaced with layout_marginRight for highlight purpose — the behavior is the same either way):

<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>

有没有一种方法,以充分奠定了这一点,而不必诉诸于多个字符串为不同设备宽度等? = \\

Is there a way to lay this out adequately, without having to resort to multiple strings for different device width etc? =\

推荐答案

OK,的TextView 的code的一些检查后,我放在一起,做解决方案我需要什么:

OK, after some examination of TextView's code I put together the solution that does what I need:

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 不走线的默认实现宽度考虑,除非他们\\ n分解由 S(<一个href=\"http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/5.1.1_r1/android/widget/TextView.java#TextView.desired%28android.text.Layout%29\"相对=nofollow> code )。我用 getLineMax 而不是 getLineWidth ,因为后者测得的尾随空白 - 错位的块#3在原来的罪魁祸首帖子。

The default implementation of onMeasure does not take line widths into account unless they are broken down by \n's (code). I used getLineMax instead of getLineWidth because the latter measured trailing whitespace — the culprit of misalignment in block #3 in the original post.

这篇关于不能用缠绕宽度独断专行计数块引用般的TextView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆