一、先看一下要实现的效果图
此处的实现与可展示的TextView实现不一样,这里的业务场景是点击“查看全部”后,跳转到其它界面展示全部内容,而不是在当前界面,所以此处的"查看全部"只是用于点击事件的安置功能。
当文本长度,在三行内能够完全展示出来,则隐藏“查看全部”。
二、实现解析
此处的功能点,是在怎么让文本只显示两行多一点,而不直接把三行充满,然后再显示三个点。其实Paint类里面,内置了计算文字显示长度的方法。我们只需要调用这个方法得到文本展示的总长度、然后再与控件长度、以及展示行数固定值,进行计算即可。直接看代码吧。
三、关键代码
package com.migu.recyclerviewtest;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class CustomContentShowTextView extends RelativeLayout {
private TextView mContentTextView;
private LinearLayout mAllContentLLT;
public CustomContentShowTextView(Context context) {
super(context);
init(context);
}
public CustomContentShowTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomContentShowTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.custom_textview_description, this);
mContentTextView = view.findViewById(R.id.description);
mAllContentLLT = view.findViewById(R.id.all_content_llt);
}
public void setText(String text) {
String content = getSubString(mContentTextView, text);
if (content != null) {
mContentTextView.setText(content);
}
}
private String getSubString(TextView tv, String content){
float width = tv.getPaint().measureText(content);
//这里只是为了方便,用屏幕宽度代替了textview控件宽度,如果需要精准控制,可以换成控件宽度
//这里测试时是将textview全屏的,如果有左右margin则从这里减去就行
float tvWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
//计算文字的长度,相对于控件长度而言,能显示多少行
float lines = width / tvWidth;
//这个>3是判断是否文字展示的行数超过3行了
if(lines > 3){
mAllContentLLT.setVisibility(VISIBLE);
//这里直接用长度/行数=每行显示多少个字,*2.7代表需要截取2.7行的字数
int index = (int)((content.length()/lines) * (2.7));
return content.substring(0, index) + "...";
} else {
mAllContentLLT.setVisibility(GONE);
}
return content;
}
public void setOnMoreClickListener(OnClickListener clickListener) {
mAllContentLLT.setOnClickListener(clickListener);
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="3"
android:ellipsize="end"
android:text="12121321321321312311212132132132131231121213213213213123112121321321321312311212132132132131231121213213213213123112121321321321312311212132132132131231"
android:textSize="14dp" />
<LinearLayout
android:id="@+id/all_content_llt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/description"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查看全部"
android:textColor="@android:color/holo_red_light"
android:textSize="14dp" />
<ImageView
android:layout_width="6dp"
android:layout_height="10dp"
android:src="@mipmap/right_arrow"
android:layout_marginLeft="4dp" />
</LinearLayout>
</RelativeLayout>
//使用就很简单了,直接设置内容即可,至于OnclickListener,根据业务需要设置即可。
CustomContentShowTextView testTextview = findViewById(R.id.testTextview);
testTextview.setText("不足三行代码的情况下,会怎么展示呢?不足三行代码的情况下,会怎么展示呢?不足三行代码的情况下,会怎么展示呢?" +
"不足三行代码的情况下,会怎么展示呢?不足三行代码的情况下,会怎么展示呢?不足三行代码的情况下,会怎么展示呢?" +
"不足三行代码的情况下,会怎么展示呢?不足三行代码的情况下,会怎么展示呢?不足三行代码的情况下,会怎么展示呢?");
四、加强版
上面的getSubString方法当中使用到的裁剪字符串,不够精确,毕竟是使用字符串的整体平均数来计算前三行的字数,这导致精确度很差。所以使用下面的加强版方法,可以大大减少差距。
private String getSubString(TextView tv, String content){
float width = tv.getPaint().measureText(content);
//这里只是为了方便,用屏幕宽度代替了textview控件宽度,如果需要精准控制,可以换成控件宽度
//这里测试时是将textview全屏的,如果有左右margin则从这里减去就行
float tvWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
//计算文字的长度,相对于控件长度而言,能显示多少行
float lines = width / tvWidth;
//这个>3是判断是否文字展示的行数超过3行了
if(lines > 3){
mAllContentLLT.setVisibility(VISIBLE);
//这里计算展示三行需要的字数
int index = (int)((content.length()/lines) * 3);
//使用控件的宽度来限制位置
float subTvWidth = (float) (tvWidth * 2.75);
String subString = "";
for (int i = index; i >= 0; i--) {
subString = content.substring(0, i) + "...";
float subWidth = tv.getPaint().measureText(subString);
if (subWidth <= subTvWidth) {
break;
}
}
//毕竟是展示内容,如果只有两三个字,肯定是不对的
if (!TextUtils.isEmpty(subString) && subString.length() > 3) {
return subString;
} else {
return content.substring(0, (int)((content.length()/lines) * (2.7))) + "...";
}
} else {
mAllContentLLT.setVisibility(GONE);
}
return content;
}
作者:沧水巫云
博客:http://blog.csdn.NET/amir_zt/
以上原创,转载请注明出处,谢谢。
https://blog.csdn.net/amir_zt/article/details/113343428