一个TextView实现文本展开功能

作者: 猪八戒表哥 | 来源:发表于2017-09-21 21:28 被阅读65次

    在一个列表显示消息时,文本过多需要进行收缩显示,点击显示全部时在展开!先看下效果图

    文本内容我是便输入的,当点击查看全部时会显示全部内容,这边我是设置做多显示三行!主要一个类,如下

    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;

    }

    }

    相关文章

      网友评论

        本文标题:一个TextView实现文本展开功能

        本文链接:https://www.haomeiwen.com/subject/vlgtextx.html