我需要使用来自服务器的动态标题来获得以下结果:
我尝试使用以下问题的答案达到此结果:
How to make the first character much larger than other in a TextView
但我达到的结果对于设计团队来说还不够好。 设计要求有几个要求:
在Android中获得此结果的最佳方式是什么?
答案 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);