我想在三行文本之后添加“更多”功能。文本包含超过 10 行的描述。所以我们决定在三行文字后面加上“更多”。喜欢:
当文本显示完整的描述时,它应该在文本末尾显示“Less”按钮,再次压缩TextView
.
试试这个可以帮助你和我一起工作。
public class MainActivity extends Activity {
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
makeTextViewResizable(tv, 3, "View More", true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public static void makeTextViewResizable(final TextView tv, final int maxLine, final String expandText, final boolean viewMore) {
if (tv.getTag() == null) {
tv.setTag(tv.getText());
}
ViewTreeObserver vto = tv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
String text;
int lineEndIndex;
ViewTreeObserver obs = tv.getViewTreeObserver();
obs.removeOnGlobalLayoutListener(this);
if (maxLine == 0) {
lineEndIndex = tv.getLayout().getLineEnd(0);
text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + expandText;
} else if (maxLine > 0 && tv.getLineCount() >= maxLine) {
lineEndIndex = tv.getLayout().getLineEnd(maxLine - 1);
text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + expandText;
} else {
lineEndIndex = tv.getLayout().getLineEnd(tv.getLayout().getLineCount() - 1);
text = tv.getText().subSequence(0, lineEndIndex) + " " + expandText;
}
tv.setText(text);
tv.setMovementMethod(LinkMovementMethod.getInstance());
tv.setText(
addClickablePartTextViewResizable(SpannableString(tv.getText().toString()), tv, lineEndIndex, expandText,
viewMore), BufferType.SPANNABLE);
}
});
}
private static SpannableStringBuilder addClickablePartTextViewResizable(final Spanned strSpanned, final TextView tv,
final int maxLine, final String spanableText, final boolean viewMore) {
String str = strSpanned.toString();
SpannableStringBuilder ssb = new SpannableStringBuilder(strSpanned);
if (str.contains(spanableText)) {
ssb.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
tv.setLayoutParams(tv.getLayoutParams());
tv.setText(tv.getTag().toString(), BufferType.SPANNABLE);
tv.invalidate();
if (viewMore) {
makeTextViewResizable(tv, -1, "View Less", false);
} else {
makeTextViewResizable(tv, 3, "View More", true);
}
}
}, str.indexOf(spanableText), str.indexOf(spanableText) + spanableText.length(), 0);
}
return ssb;
}
}
更新:从 spaneble 文本中删除 UnderLine
public class MySpannable extends ClickableSpan {
private boolean isUnderline = false;
/**
* Constructor
*/
public MySpannable(boolean isUnderline) {
this.isUnderline = isUnderline;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(isUnderline);
ds.setColor(Color.parseColor("#343434"));
}
@Override
public void onClick(View widget) {
}
}
addClickablePartTextViewResizable()
方法的改变private static SpannableStringBuilder addClickablePartTextViewResizable(final Spanned strSpanned, final TextView tv,
final int maxLine, final String spanableText, final boolean viewMore) {
String str = strSpanned.toString();
SpannableStringBuilder ssb = new SpannableStringBuilder(strSpanned);
if (str.contains(spanableText)) {
ssb.setSpan(new MySpannable(false){
@Override
public void onClick(View widget) {
tv.setLayoutParams(tv.getLayoutParams());
tv.setText(tv.getTag().toString(), BufferType.SPANNABLE);
tv.invalidate();
if (viewMore) {
makeTextViewResizable(tv, -1, "View Less", false);
} else {
makeTextViewResizable(tv, 3, "View More", true);
}
}
}, str.indexOf(spanableText), str.indexOf(spanableText) + spanableText.length(), 0);
}
return ssb;
}
输出:
这是一个简单的自定义ExpandableTextView
。代替使用 See More 文本,它在底部使用 Compound Drawable:
public class ExpandableTextView extends TextView implements OnClickListener
{
private static final int MAX_LINES = 5;
private int currentMaxLines = Integer.MAX_VALUE;
public ExpandableTextView(Context context)
{
super(context);
setOnClickListener(this);
}
public ExpandableTextView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
setOnClickListener(this);
}
public ExpandableTextView(Context context, AttributeSet attrs)
{
super(context, attrs);
setOnClickListener(this);
}
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter)
{
/* If text longer than MAX_LINES set DrawableBottom - I'm using '...' icon */
post(new Runnable()
{
public void run()
{
if (getLineCount()>MAX_LINES)
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, R.drawable.icon_more_text);
else
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
setMaxLines(MAX_LINES);
}
});
}
@Override
public void setMaxLines(int maxLines)
{
currentMaxLines = maxLines;
super.setMaxLines(maxLines);
}
/* Custom method because standard getMaxLines() requires API > 16 */
public int getMyMaxLines()
{
return currentMaxLines;
}
@Override
public void onClick(View v)
{
/* Toggle between expanded collapsed states */
if (getMyMaxLines() == Integer.MAX_VALUE)
setMaxLines(MAX_LINES);
else
setMaxLines(Integer.MAX_VALUE);
}
}
如果字符串中有 \r\n 或 \n 这将换行
public static void makeTextViewResizable(final TextView tv,
final int maxLine, final String expandText, final boolean viewMore) {
if (tv.getTag() == null) {
tv.setTag(tv.getText());
}
ViewTreeObserver vto = tv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
ViewTreeObserver obs = tv.getViewTreeObserver();
obs.removeGlobalOnLayoutListener(this);
if (maxLine == 0) {
int lineEndIndex = tv.getLayout().getLineEnd(0);
String text = tv.getText().subSequence(0,
lineEndIndex - expandText.length() + 1)
+ " " + expandText;
tv.setText(text);
tv.setMovementMethod(LinkMovementMethod.getInstance());
tv.setText(
addClickablePartTextViewResizable(tv.getText()
.toString(), tv, maxLine, expandText,
viewMore), BufferType.SPANNABLE);
} else if (maxLine > 0 && tv.getLineCount() >= maxLine) {
int lineEndIndex = tv.getLayout().getLineEnd(maxLine - 1);
String text = tv.getText().subSequence(0,
lineEndIndex - expandText.length() + 1)
+ " " + expandText;
tv.setText(text);
tv.setMovementMethod(LinkMovementMethod.getInstance());
tv.setText(
addClickablePartTextViewResizable(tv.getText()
.toString(), tv, maxLine, expandText,
viewMore), BufferType.SPANNABLE);
} else {
int lineEndIndex = tv.getLayout().getLineEnd(
tv.getLayout().getLineCount() - 1);
String text = tv.getText().subSequence(0, lineEndIndex)
+ " " + expandText;
tv.setText(text);
tv.setMovementMethod(LinkMovementMethod.getInstance());
tv.setText(
addClickablePartTextViewResizable(tv.getText()
.toString(), tv, lineEndIndex, expandText,
viewMore), BufferType.SPANNABLE);
}
}
});
}
private static SpannableStringBuilder addClickablePartTextViewResizable(
final String strSpanned, final TextView tv, final int maxLine,
final String spanableText, final boolean viewMore) {
SpannableStringBuilder ssb = new SpannableStringBuilder(strSpanned);
if (strSpanned.contains(spanableText)) {
ssb.setSpan(
new ClickableSpan() {
@Override
public void onClick(View widget) {
if (viewMore) {
tv.setLayoutParams(tv.getLayoutParams());
tv.setText(tv.getTag().toString(),
BufferType.SPANNABLE);
tv.invalidate();
makeTextViewResizable(tv, -5, "...Read Less",
false);
tv.setTextColor(Color.BLACK);
} else {
tv.setLayoutParams(tv.getLayoutParams());
tv.setText(tv.getTag().toString(),
BufferType.SPANNABLE);
tv.invalidate();
makeTextViewResizable(tv, 5, "...Read More",
true);
tv.setTextColor(Color.BLACK);
}
}
}, strSpanned.indexOf(spanableText),
strSpanned.indexOf(spanableText) + spanableText.length(), 0);
}
return ssb;
}