Textview自带展开和收起功能

来源:互联网 发布:偶像活动真食玩淘宝店 编辑:程序博客网 时间:2024/05/27 14:13

效果图:
这里写图片描述
这里写图片描述

思路:
1.继承TextView,定义ExpandTextView
2.添加两个自定义属性:用于获取展开和收起时的提示语
3.TextView初始状态是不限制行数,默认全部显示
4.定义一个最大行数,注意这个不要和Textview成员看成是一个,初始状态不能调协Textview最大行数
5.在onlayout方法中,初始化展开和收起的信息,得到两个SpanableStringbuilder对象,一个是在展开状态时显示的内容,一个是收起状态显示的内容
6.定义控制变更,控制是否是展开状态

代码具体实现:
1.类定义ExpandTextView, 重点是重写这个构造方法:

public ExpandTextView(Contextcontext,@NullableAttributeSet attrs){    super(context,attrs);}
2.定义两个自定义属性:
<declare-styleablename="ExpandTextview">    <attrname="expand_text"format="reference"/>    <attrname="unexpand_text"format="reference"/></declare-styleable>
3.在xml中使用:
<com.example.learn.view.ExpandTextView    android:id="@+id/expand_textview"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="@string/service_textview_expand_desc"    myapp:expand_text="@string/service_textview_expand_name"    myapp:unexpand_text="@string/service_textview_unexpand_name"/>
4.在ExpandTextView构造中获取展开和收起提示语,也可以通过接口外部设置
TypedArray array=context.obtainStyledAttributes(attrs,R.styleable.ExpandTextview);if(array!=null){    mExpandName=array.getString(R.styleable.ExpandTextview_expand_text);    mUnExpandName=array.getString(R.styleable.ExpandTextview_unexpand_text);}
5.设置控制变更
privateintmOriLines=0;//初始数据行数privateintmMaxLines=0;//默认显示的最大的行数,默认是0,表明不做展开处理privatebooleanmbExpandable=false;//是否有展开收起功能,只有超过最大行数才会显示privatebooleanmbExpand=false;//默认不展开
6.onlayout中初始化
protectedvoidonLayout(booleanchanged,intleft,inttop,intright,intbottom){    super.onLayout(changed,left,top,right,bottom);    LogUtils.printFunLog(TAG);    if(mOriLines==0){        mOriLines=getLineCount();        if(mOriLines>mMaxLines){            initExpandInfo(getText());            setText(!mbExpand?mExpandDesc:mUnExpandDesc);            mbExpandable=true;        }else{            mbExpandable=false;            }        }    }
7.initExpandInfo中获取展开和收起内容:
/***原理:*onlayout中调用,根据内容得出展示和收起的内容,主要是后面追加展开收起提示语并高亮*@paramtext*/private void initExpandInfo(CharSequencetext){    //LogUtils.printFunLog(TAG);    int lineEndIndex=getLayout().getLineEnd(mMaxLines-1);    String shortText=text.subSequence(0,lineEndIndex-5)+"...";    //初始化展开状态时的内容,这个是指限定了行数的显示的内容    SpannableStringBuilder ssb_expand=new SpannableStringBuilder();    ssb_expand.append(shortText);    int start=ssb_expand.length();    ssb_expand.append(mExpandName);    int end=ssb_expand.length();    mExpandDesc=ssb_expand;    ssb_expand.setSpan(new ForegroundColorSpan(mExpandColor),start,end,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);    //初始化收起状态时的内容,这个是指全部内容    SpannableStringBuilder ssb_unexpand=new SpannableStringBuilder();    ssb_unexpand.append(text);    start=ssb_unexpand.length();    ssb_unexpand.append(mUnExpandName);    end=ssb_unexpand.length();    ssb_unexpand.setSpan(new ForegroundColorSpan(mExpandColor),start,end,Spanned.SPAN_INCLUSIVE_EXCLUSIVE);    mUnExpandDesc=ssb_unexpand;}
8.如果setText被触发,即若是新的内容被设置,需要重置
@Overrideprotected void onTextChanged(CharSequencetext,intstart,intlengthBefore,intlengthAfter){    super.onTextChanged(text,start,lengthBefore,lengthAfter);    //LogUtils.printFunLog(TAG,"start="+start+",before="+lengthBefore+",after="+lengthAfter+",lines="+getLineCount());    //内容发生改变重新赋值    if(!TextUtils.equals(text,mUnExpandDesc)&&!TextUtils.equals(text,mExpandDesc)){        //LogUtils.printFunLog(TAG,"resetorilines");        mOriLines=0;        mbExpand=false;        setMaxLines(Integer.MAX_VALUE);        setEllipsize(null);    }}
9.外部Acitvity调用:
mExpTextView=(ExpandTextView)findViewById(R.id.expand_textview);mExpTextView.setmMaxExpandLines(2);mExpTextView.setExpandInfo("展开","收起",Color.RED);//如上图所示的效果mExpTextView.setText(getString(R.string.service_textview_expand_desc));
原创粉丝点击