在一个列表显示消息时,文本过多需要进行收缩显示,点击显示全部时在展开!先看下效果图
文本内容我是便输入的,当点击查看全部时会显示全部内容,这边我是设置做多显示三行!主要一个类,如下
```
importandroid.animation.Animator;
importandroid.animation.ValueAnimator;
importandroid.content.Context;
importandroid.content.res.TypedArray;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Paint;
importandroid.support.annotation.Nullable;
importandroid.text.Layout;
importandroid.text.SpannableString;
importandroid.text.Spanned;
importandroid.text.StaticLayout;
importandroid.text.TextPaint;
importandroid.text.method.LinkMovementMethod;
importandroid.text.style.ClickableSpan;
importandroid.text.style.ForegroundColorSpan;
importandroid.util.AttributeSet;
importandroid.util.TypedValue;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.RelativeLayout;
importandroid.widget.TextView;
importcom.mocoo.ezc.R;
importcom.mocoo.ezc.utils.DensityUtil;
/**
* Created by necer on 2017/4/10.
*/
public classExpandTextViewextendsRelativeLayoutimplementsView.OnClickListener {
privateTextViewmTextView;
privateTextPaintmTextPaint;//textView的画笔
private intmTextColor;//颜色
private floatmTextSize;//大小
private intmShowLineNum=3;//显示的最大行数
privateBitmapmUpBitmap,mDownBitmap;//指示箭头
private intbitmapTop;//bitmap距顶部的距离
private intbitmapWith;//bitmap宽
private intbitmaphith;//bitmap宽
privatePaintmPain;//画指示箭头
private intfoldHeight;//折叠后的高度
private inttrueHeight;//真实高度
private intlineHeight;//Textview行数行高
private intlineCount;//Textview行数
privateStringmText;//原始数据
privateStringmFoldText;//折叠的数据
private booleanisFoldEnable=false;//是否可以折叠
private booleanisFold=true;//是否折叠
private booleanisEnough=true;//最后一行是否能容纳箭头
private booleanisDown;//箭头指向
private floatbitmapRightOffset;//箭头距离view右边的距离
private intmDuration;//动画时间,默认300
publicExpandTextView(Context context) {
this(context, null);
}
publicExpandTextView(Context context,@NullableAttributeSet attrs) {
this(context,attrs,0);
}
publicExpandTextView(Context context,@NullableAttributeSet attrs, intdefStyleAttr) {
super(context,attrs,defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.ExpandTextview);
mDuration= ta.getInteger(R.styleable.ExpandTextview_duration,300);
bitmapRightOffset= ta.getDimension(R.styleable.ExpandTextview_bitmapRightOffet,DensityUtil.dip2px(getContext(),10));
mTextColor= ta.getColor(R.styleable.ExpandTextview_textColor,Color.parseColor("#000000"));
mTextSize= ta.getDimension(R.styleable.ExpandTextview_textSize,DensityUtil.dip2px(getContext(),14));
mShowLineNum= ta.getInteger(R.styleable.ExpandTextview_showLine,3);
ta.recycle();
mTextView=newTextView(getContext());
mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,mTextSize);
mTextView.setTextColor(mTextColor);
mTextPaint=mTextView.getPaint();
addView(mTextView);
mTextView.setOnClickListener(this);
mPain=newPaint();
mPain.setColor(getResources().getColor(R.color.theme_color));
mPain.setTextSize(40f);
mUpBitmap= BitmapFactory.decodeResource(getResources(),R.drawable.abc);
mDownBitmap= BitmapFactory.decodeResource(getResources(),R.drawable.abc);
bitmapWith=mUpBitmap.getWidth();
bitmaphith=mUpBitmap.getHeight();
}
public voidsetText(String text) {
this.mText= text;
post(newRunnable() {
@Override
public voidrun() {
dealText();
}
});
}
//要在post里面进行,不然getWidth()得不到view的宽,就无法正确得到字符串的行数
private voiddealText() {
StaticLayout staticLayout =newStaticLayout(mText,mTextPaint,getWidth() - getPaddingLeft() - getPaddingRight(),Layout.Alignment.ALIGN_NORMAL,1.0f,0f, true);
lineCount= staticLayout.getLineCount();
lineHeight= staticLayout.getHeight() /lineCount;
isFoldEnable=lineCount>mShowLineNum;
if(isFoldEnable) {
intstart = staticLayout.getLineStart(mShowLineNum-1);
intend = staticLayout.getLineEnd(mShowLineNum-1);
//获取最后一行的内容
String endText =mText.substring(start,end);
mFoldText=mText.substring(0,start) + endText.substring(0,endText.length() -5) +"···";
intlineWidth = (int) staticLayout.getLineWidth(lineCount-1);
isEnough= getWidth() - lineWidth - getPaddingLeft() - getPaddingRight() > (bitmapWith+bitmapRightOffset);
//能容纳真实高度为textview的高度,不能容纳,真实高度为textview高度+一个行高,放箭头
trueHeight=isEnough? staticLayout.getHeight() : staticLayout.getHeight() +lineHeight;
foldHeight=lineHeight*mShowLineNum;
if(isFold) {
bitmapTop=foldHeight-lineHeight/2;//bitmap开始的位置,让箭头在一行的中间
String str=mFoldText+"查看全部";
mTextView.setText(getClickableSpan(str,mFoldText));
//此行必须有
mTextView.setMovementMethod(LinkMovementMethod.getInstance());
}else{
bitmapTop=trueHeight-lineHeight/2;
mTextView.setText(mText);
}
}else{
mTextView.setText(mText);
}
}
@Override
protected voidonDraw(Canvas canvas) {
super.onDraw(canvas);
if(!isFoldEnable) {
return;
}
}
public voidstartAnim(intstarHeight, intendHeight,Animator.AnimatorListener animatorListener) {
finalViewGroup.LayoutParams layoutParams =mTextView.getLayoutParams();
ValueAnimator valueAnimator = ValueAnimator.ofInt(starHeight,endHeight);
valueAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
@Override
public voidonAnimationUpdate(ValueAnimator valueAnimator) {
layoutParams.height= (int) valueAnimator.getAnimatedValue();
mTextView.setLayoutParams(layoutParams);
bitmapTop= (int) valueAnimator.getAnimatedValue() -lineHeight/2;
}
});
valueAnimator.addListener(animatorListener);
valueAnimator.setDuration(mDuration);
valueAnimator.start();
}
privateSpannableStringgetClickableSpan(String str1,String str2) {
//监听器
View.OnClickListener listener =newView.OnClickListener() {
@Override
public voidonClick(View v) {
if(!isFoldEnable) {
return;
}
if(ButtonUtils.isFastClick(mDuration)) {
return;
}
if(isFold) {
isFold=false;
mTextView.setText(mText);
startAnim(foldHeight,trueHeight, newAnimator.AnimatorListener() {
@Override
public voidonAnimationStart(Animator animator) {
isDown=true;
}
@Override
public voidonAnimationEnd(Animator animator) {
}
@Override
public voidonAnimationCancel(Animator animator) {
}
@Override
public voidonAnimationRepeat(Animator animator) {
}
});
}
}
};
SpannableString spanableInfo =newSpannableString(str1);
intstart = str2.length();//超链接起始位置
intend = str1.length();//超链接结束位置
//可以为多部分设置超链接
spanableInfo.setSpan(newClickable(listener),start,end,Spanned.SPAN_MARK_MARK);
spanableInfo.setSpan(newForegroundColorSpan(getResources().getColor(R.color.theme_color)),start,end,Spanned.SPAN_MARK_MARK);
returnspanableInfo;
}
@Override
public voidonClick(View view) {
}
classClickableextendsClickableSpanimplementsView.OnClickListener {
private finalView.OnClickListenermListener;
publicClickable(View.OnClickListener listener) {
mListener= listener;
}
@Override
public voidonClick(View view) {
mListener.onClick(view);
}
@Override
public voidupdateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
}
实现方法主要用超链接的方法实现的,对“查看全部”这四个字进行监听点击时,展开全部内容
public classButtonUtils {
private static longlastClickTime;
public synchronized static booleanisFastClick(longduration) {
longtime = System.currentTimeMillis();
if(time -lastClickTime< duration) {
return true;
}
lastClickTime= time;
return false;
}
}
```