如何在Android中设计段落样式标题?

时间:2016-06-19 09:32:16

标签: android textview paragraph

我需要使用来自服务器的动态标题来获得以下结果:

enter image description here

我尝试使用以下问题的答案达到此结果:

How to make the first character much larger than other in a TextView

但我达到的结果对于设计团队来说还不够好。 设计要求有几个要求:

  1. Big first laterv(B)。
  2. 文字继续在大字母的中间位置上方(较小的红色字母)。
  3. 第二行文字继续与大字母的基础对齐("以及电影中的明星")。
  4. 最后如果还有更多的文字,它会继续在大写字母下面继续。
  5. 在Android中获得此结果的最佳方式是什么?

3 个答案:

答案 0 :(得分:2)

解决方案是拥有3个视图,一个用于第一个字母,另一个用于(最多)两个行,另一个用于文本的其余部分。 在测量视图时,您可以确定是否已经超过了要强加的2行限制,如果是,则中断文本并在第3个视图中设置文本的其余部分。 您还需要克服第一个字母的内部字体填充以获得所需的结果,因此可以使用BottomAlignedTextView视图。

以下是代码:

BottomAlignedTextView.java

public class BottomAlignedTextView extends TextView {

 public BottomAlignedTextView(Context context) {
     super(context);
 }

 @Override
 protected void onDraw(Canvas canvas) {
     float offset = getTextSize() - getLineHeight();
     canvas.translate(0, -offset);
     super.onDraw(canvas);
 }

}

view_reader_title.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.shellanoo.newsbot.ui.views.BottomAlignedTextView
            android:id="@+id/first_letter_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fontFamily="serif"
            android:background="@null"
            android:gravity="bottom"
            android:includeFontPadding="false"
            android:textSize="92dp"
            tools:text="B"/>

        <TextView
            android:id="@+id/two_lines_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/first_letter_tv"
            android:layout_toEndOf="@+id/first_letter_tv"
            android:layout_toRightOf="@+id/first_letter_tv"
            android:gravity="bottom"
            android:includeFontPadding="false"
            android:lineSpacingMultiplier="0.9"
            android:textColor="@color/black"
            android:textSize="30dp"
            tools:text="eyonce to write and star in a film"/>
    </RelativeLayout>

    <TextView
        android:id="@+id/remainder_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="2dp"
        android:layout_marginStart="2dp"
        android:includeFontPadding="false"
        android:textColor="@color/black"
        android:textSize="30dp"
        tools:text="about Saartjie Baartman"/>
</LinearLayout>

ReaderTitleView.java

public class ReaderTitleView extends FrameLayout {

    @BindView(R.id.first_letter_tv)
    TextView firstLetterTv;

    @BindView(R.id.two_lines_tv)
    TextView twoLinesTv;

    @BindView(R.id.remainder_tv)
    TextView remainderTv;

    @ColorInt
    private int mFirstWordColor;
    private String mText;

    public ReaderTitleView(Context context) {
        this(context, null);
    }

    public ReaderTitleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    private void init(AttributeSet attrs) {
        View view = inflate(getContext(), R.layout.view_reader_title, this);
        ButterKnife.bind(this, view);
        TypedArray a = getContext().getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.ReaderTitleView,
                0, 0);
        mText = a.getString(R.styleable.ReaderTitleView_rtv_text);
        if (mText == null) {
            mText = "";
        }
        mFirstWordColor = a.getColor(R.styleable.ReaderTitleView_rtv_first_word_color, -1);

        updateTextViews();
    }

    private void updateTextViews() {
        if (!TextUtils.isEmpty(mText)) {
            String firstLetter = mText.substring(0, 1);
            firstLetter = firstLetter.toUpperCase();
            String restText = mText.substring(1, mText.length());

            firstLetterTv.setText(firstLetter);
            twoLinesTv.setText(restText);
            colorifyFirstWord();
        } else {
            firstLetterTv.setText("");
            twoLinesTv.setText("");
            remainderTv.setText("");
        }
    }

    private void colorifyFirstWord() {
        if (mFirstWordColor != -1) {
            CharSequence text = twoLinesTv.getText();
            Spannable s;
            if (text instanceof Spannable) {
                s = (Spannable) text;
            } else {
                s = new SpannableString(text);
            }
            String[] split = s.toString().split(" ", 2);
            int start = 0;
            int end = start + split[0].length();
            s.setSpan(new ForegroundColorSpan(mFirstWordColor), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            twoLinesTv.setText(s, TextView.BufferType.SPANNABLE);
            firstLetterTv.setTextColor(mFirstWordColor);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (twoLinesTv.getLineCount() > 2) {
            String text = twoLinesTv.getText().toString();

            int secondLineEnd = twoLinesTv.getLayout().getLineEnd(1);
            String twoLines = text.substring(0, secondLineEnd);
            String remainder = text.substring(secondLineEnd, text.length());

            twoLinesTv.setText(twoLines);
            remainderTv.setText(remainder);
            colorifyFirstWord();
        }
    }

    public void setText(String text) {
        mText = text;
        updateTextViews();
    }

    public String getText() {
        return mText;
    }
    }

答案 1 :(得分:1)

我建议您使用Letterine库。

在您的gradle中添加以下行:

compile 'com.github.rpradal.lettrine:lettrine:1.0.0'

以下是如何在项目中添加LettrineTextView的示例:

  <com.github.rpradal.lettrine.LettrineTextView
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              app:lettrine_textColor="@android:color/holo_red_dark"
              app:lettrine_text="Lorem ipsum"
              app:lettrine_lettrineSize="3"
              app:lettrine_textSize="14sp" />

然后,您可以像我在下面找到视图。

LettrineTextView letterineTextView = (LettrineTextView) findViewById(R.id.letterineTextView);
letterineTextView.setBodyText(getString(R.string.body));

享受,快乐的编码。

答案 2 :(得分:0)

看看http://uncodin.github.io/bypass/https://github.com/Uncodin/bypass。例如:

Bypass markdown = new Bypass(context, new Bypass.Options());

                    CharSequence about0 = markdown.markdownToSpannable(parent.getResources()
                            .getString(R.string.string_0), yourTextView, null);
                    SpannableString about1 = new SpannableString(
                            parent.getResources().getString(R.string.string_1));
                    about1.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER),
                            0, about1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    SpannableString about2 = new SpannableString(markdown.markdownToSpannable
                            (parent.getResources().getString(R.string.string2),
                                    plaidDescription, null));
                    about2.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER),
                            0, about2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    SpannableString about3 = new SpannableString(markdown.markdownToSpannable
                            (parent.getResources().getString(R.string.string_3),
                                    yourTextView, null));
                    about3.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER),
                            0, about3.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    CharSequence desc = TextUtils.concat(about0, "\n\n", about1, "\n", about2,
                            "\n\n", about3);
                    HtmlUtils.setTextWithNiceLinks(yourTextView, desc);