首页 教你实现一个具备展开折叠功能TetView

教你实现一个具备展开折叠功能TetView

举报
开通vip

教你实现一个具备展开折叠功能TetView教你实现一个具备展开折叠功能的TextView可折叠的textview是一个很常见的功能,相信大家都在微信朋友圈体验过这种场景:朋友发的笑话都只有半截,下面是一片白色,你要展开全文之后才能知道最后结果。其实这也不是什么高大上的东西,网上也有现成的例子,但是使用起来还是得稍微调整一下,最牛逼的应该就是Manabu-GT勺ExpandableTextView。那么我们通过对它的学习,自己来擂一发项目已经发布在github上我们先实现一个基本功能,能点击收放就行了,其他效果先不管定义相关基本届性仔细看下上图,其实这个自定...

教你实现一个具备展开折叠功能TetView
教你实现一个具备展开折叠功能的TextView可折叠的textview是一个很常见的功能,相信大家都在微信朋友圈体验过这种场景:朋友发的笑话都只有半截,下面是一片白色,你要展开全文之后才能知道最后结果。其实这也不是什么高大上的东西,网上也有现成的例子,但是使用起来还是得稍微调整一下,最牛逼的应该就是Manabu-GT勺ExpandableTextView。那么我们通过对它的学习,自己来擂一发项目已经发布在github上我们先实现一个基本功能,能点击收放就行了,其他效果先不管定义相关基本届性仔细看下上图,其实这个自定义的控件也就由两部分组成,一个是正常的显示文本部分,另外一个是收放的按钮,因此我们可以通过组合布局的形式来实现首先写死id,这是因为我们要在组合布局里面操作这2个TextView,所以最简单的途径就是直接拿到这2个对象进行使用然后是自定义届性的设计剩下就是很传统的初始化publicclassExpandableTextViewextendsLinearLayout{TextViewid_source_textview;TextViewid_expand_textview;publicExpandableTextView(Contextcontext){this(context,null);}publicExpandableTextView(Contextcontext,AttributeSetattrs){super(context,attrs);init(context,attrs);}privatevoidinit(Contextcontext,AttributeSetattrs){setOrientation(VERTICAL);TypedArrayarray=context.obtainStyledAttributes(attrs,;maxExpandLines=array.getInteger(,3);array.recycle();}@OverrideprotectedvoidonFinishInflate(){super.onFinishInflate();id_source_textview=(TextView)findViewById(;id_expand_textview=(TextView)findViewById(;id_expand_textview.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){}});}@OverrideprotectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){super.onMeasure(widthMeasureSpec,heightMeasureSpec);}}OK大家都会的说完了,下面开始分逻辑一■一说明测量onMeasure想必不用多说了,他是负责对ViewGroup进行测量,用来把握整体ViewGroup的大小。那么我们这里就可以利用这个方法来对组合布局收放的大小进行控制publicvoidsetText(Stringtext){isChange=true;id_source_textview.setText(text);}首先,如果你在两次setText之间没有发生文本变化,或者这个组合布局本身都不显示,那么我们果断的终止计算操作,因为这个计算过程是没有意义的//如果隐藏控件或者textview的值没有发生改变,那么不进行测量if(getVisibility()==GONE||!isChange)(return;}isChange=false;完成上述的判断之后,我们就开始真正的去实现收起一个textview的功能了//初始化默认状态,即正常显示文本id_expand_textview.setVisibility(GONE);id_source_textview.setMaxLines(Integer.MAX_VALUE);super.onMeasure(widthMeasureSpec,heightMeasureSpec);如果文本行数不满足收起展开的最小行数,那么终止,而以初始的状态展现在我们的眼前//如果本身没有达到收起展开的限定要求,则不进行处理if(id_source_textview.getLineCount()<=maxExpandLines)(return;}默认我们是设置成收起状态的,在收起状态时,我们设置当前行数为最大可显示行数,并且按钮显示出来if(isCollapsed)(id_source_textview.setLines(maxExpandLines);}id_expand_textview.setVisibility(VISIBLE);super.onMeasure(widthMeasureSpec,heightMeasureSpec);测量部分就结束了。记住这里乂一个关键点,每次UI的变化,都需要我们去重新测量,不然最终获取出来的数据就会有问题点击效果无非就是收放的切换id_expand_textview.setOnClickListener(newOnClickListener()(@OverridepublicvoidonClick(Viewv)(isCollapsed=!isCollapsed;if(isCollapsed)(id_expand_textview.setText("展开");}else(id_expand_textview.setText("收起");}//不带动画的处理方式isChange=true;requestLayout();}});使用expandable_text=(ExpandableTextView)findViewById(;expandable_text.setText("挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的"+"挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的"+"挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的"+"挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的"+"挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的"+"挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的挨打的");】不带动画效果的收放功能动画效果基本功能我们是完成了,但是不能仅仅满足这一点点。通过点击进行过渡切换,这样的效果体验上肯定会更好一些继续添加我们的自定义届性,这里我们添加的是动画执行时间默认为500msduration=array.getInteger(,500);动画参数的初始化既然涉及到高度的变化,那么我们就必须要知道收起与展开2个不同状态下的高度值,因为动画变化区间就在这2个值范围内。展开状态下的高度就是设置maxLines为Integer.Max时候ViewGroup的高度,收起状态下的高度就是设置了maxExpandLines值之后的ViewGroup的高度获取文本的高度//初始化高度赋值,为后续动画事件准备数据realTextViewHeigt=getRealTextViewHeight(id_source_textview);privateintgetRealTextViewHeight(TextViewtextView){//getLineTop返回值是一个根据行数而形成等差序列,如果参数为行数,则值即为文本的高度inttextHeight=textView.getLayout().getLineTop(textView.getLineCount());returntextHeight+textView.getCompoundPaddingBottom()+textView.getCompoundPaddingTop();}收起之后的高度,这个需要等ViewGroup渲染完成之后才能真正获取到。这里lastHeight指的是总高度减去文本部分的高度,也就是收放按钮所占区域高度if(isCollapsed){id_source_textview.post(newRunnable(){@Overridepublicvoidrun(){lastHeight=getHeight()-id_source_textview.getHeight();collapsedHeight=getMeasuredHeight();}});}那么很明显,ViewGroup完全展开后的高度为realTextViewHeigt+lastHeight,完全收起时候的高度为collapsedHeight。整个收放的过程由于没有文字的变化,所以并没有进行相关计算,只是单纯的修改高度而已privateclassExpandCollapseAnimationextendsAnimation{intstartValue=0;intendValue=0;publicExpandCollapseAnimation(intstartValue,intendValue){setDuration(duration);this.startValue=startValue;this.endValue=endValue;}@OverrideprotectedvoidapplyTransformation(floatinterpolatedTime,Transformationt){super.applyTransformation(interpolatedTime,t);intheight=(int)((endValue-startValue)*interpolatedTime+startValue);id_source_textview.setMaxHeight(height-lastHeight);;;}@OverridepublicbooleanwillChangeBounds(){returntrue;}}点击切换点击切换部分主要是动画的操作id_expand_textview.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewv){ExpandCollapseAnimationanimation;isCollapsed=!isCollapsed;展开");if(isCollapsed){id_expand_textview.setText(animation=newExpandCollapseAnimation(getHeight(),collapsedHeight);}else{id_expand_textview.setText("收起");animation=newExpandCollapseAnimation(getHeight(),realTextViewHeigt+lastHeight);}animation.setFillAfter(true);animation.setAnimationListener(newAnimation.AnimationListener(){@OverridepublicvoidonAnimationStart(Animationanimation){isAnimate=true;}@OverridepublicvoidonAnimationEnd(Animationanimation){clearAnimation();isAnimate=false;}@OverridepublicvoidonAnimationRepeat(Animationanimation){}});clearAnimation();startAnimation(animation);}});}当然,为了在动画的执行过程中防止再次点击到切换按钮,可以这样直接拦截点击事件@OverridepublicbooleanonInterceptTouchEvent(MotionEventev)(//执行动画的过程中屏蔽事件returnisAnimate;}复用问题刚才看到的都是普通场景下的使用,这个一般不会有什么问题。但是一旦牵扯到列表复用,问题就乂乱七八糟的出现了,比如之前展开的收起来了,但是底部文字没有变化之类的。其实解决这个问题也很简单,只要我们每次 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 当前收放状态并且每次复用的时候重新去设置一遍就行了来看一些列表的实体bean,主要就是文字与状态2个变量publicclassDataBean(Stringtext;booleanisCollapsed=true;publicStringgetText()(returntext;}publicvoidsetText(Stringtext)(this.text=text;}publicbooleanisCollapsed()(returnisCollapsed;}publicvoidsetCollapsed(booleancollapsed)(isCollapsed=collapsed;}}对刚才的ViewGroup添加一个状态变化的回调接口,这样在点击部分可以通过回调传给adapter中的数据源,这里就不再对setOnClickListener进行赘述了publicinterfaceOnExpandStateChangeListener(voidonExpandStateChanged(booleanisExpanded);}最后是一个关键的地方,我们扩展一下之前的setText()方法。我们需要将收放状态再次带入,同时还有一个关键的地方,将高度重置publicvoidsetText(Stringtext,booleanisCollapsed)(this.isCollapsed=isCollapsed;if(isCollapsed)(id_expand_textview.setText("展开");}else(id_expand_textview.setText("收起");}clearAnimation();setText(text);getLayoutParams().height=;}来看看最终效果原文链接:/317b118dd2d7
本文档为【教你实现一个具备展开折叠功能TetView】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_597436
暂无简介~
格式:doc
大小:15KB
软件:Word
页数:0
分类:
上传时间:2019-09-18
浏览量:2