一、简单介绍

本文是在GitHub上找的一个库

ExpandableTextView is an Android library that allows developers to easily create an TextView which can expand/collapse just like the Google Play's app description. Feel free to use it all you want in your Android apps provided that you cite this project.

ExpandableTextView 是一个提供给android开发者的安卓库,它能让你很容易实现textview的拓展折叠像Google Play’s app那样。在你的app项目中用它你会感觉到自由定制你想要的一切。

二、具体使用

Requirements(要求)

 API Level 8 (Froyo) and above.

导包

The library is pushed to Maven Central as an AAR, so you just need to add the followings to your build.gradle file:

dependencies {compile 'com.ms-square:expandableTextView:0.1.4'
}

Usage

Using the library is really simple, just look at the source code of the provided sample. (Look at the SampleTextListAdapter.java for the use within a ListView)The important thing to note is that the view Ids for TextView and ImageButton must be set to "@id/expandable_text" and "@id/expand_collapse" respectively for this library to work.Also, you can optionally set the following attributes in your layout xml file to customize the behavior of the ExpandableTextView.maxCollapsedLines (defaults to 8) The maximum number of text lines allowed to be shown when the TextView gets collapsedanimDuration (defaults to 300ms) Duration of the Animation for the expansion/collapseanimAlphaStart (defaults to 0.7f) Alpha value of the TextView when the animation starts (NOTE) Set this value to 1 if you want to disable the alpha animation.expandDrawable Customize a drawable set to ImageButton to expand the TextViewcollapseDrawable Customize a drawable set to ImageButton to collapse the TextView

使用本库很简单,看例子就行。
重要的是:

1、TextView 和ImageButton 的id必须按照库要求的设置,分别设置为”@id/expandable_text” 和”@id/expand_collapse” ,只有这样才能生效。

2、当然,你也可以设置以下属性满足你项目的需要。

maxCollapsedLines 折叠的时候允许显示的最大行,默认为8

animDuration 折叠展开时动画所用的时间,默认300ms

animAlphaStart 动画执行的时候,渐变动画,背景虚化。默认为0.7f,设置为1,则不会有虚化。

expandDrawable 你自定义展开动画。

collapseDrawable 你自定义折叠动画。

三、小例子。

 <!-- sample xml --><com.ms.square.android.expandabletextview.ExpandableTextViewxmlns:android="http://schemas.android.com/apk/res/android"xmlns:expandableTextView="http://schemas.android.com/apk/res-auto"android:id="@+id/expand_text_view"android:layout_width="match_parent"android:layout_height="wrap_content"expandableTextView:maxCollapsedLines="4"expandableTextView:animDuration="200"><TextViewandroid:id="@id/expandable_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:textSize="16sp"android:textColor="#666666" /><ImageButtonandroid:id="@id/expand_collapse"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="16dp"android:layout_gravity="right|bottom"android:background="@android:color/transparent"/></com.ms.square.android.expandabletextview.ExpandableTextView>// sample code snippet to set the text content on the ExpandableTextView
ExpandableTextView expTv1 = (ExpandableTextView) rootView.findViewById(R.id.sample1).findViewById(R.id.expand_text_view);// IMPORTANT - call setText on the ExpandableTextView to set the text content to display
expTv1.setText(getString(R.string.dummy_text1));

需要注意的是,设置文本内容时候我们用的是ExpandableTextView 而不是Textview。

看效果
**展开前:**

展开后

。。。。。。。。。。。。。。

后续,老板觉得不好看,就自定义了个。

attrs里面

 <declare-styleable name="ExpandTextView"><!-- 文本颜色 --><attr name="textColor" format="color|reference"/><!-- 最大显示文本行数 --><attr name="My_maxLines" format="integer|reference"/><!-- 文本字体大小 --><attr name="textSize" format="dimension|reference"/><!-- 动画显示时间--><attr name="animDuration" format="integer|reference"/><!-- 提示图标的宽度 --><attr name="drawableWidth" format="dimension|reference"/><!-- 提示图标的高度 --><attr name="drawableHeight" format="dimension|reference"/><!-- 展开时候的提示图标 --><attr name="expandDrawable" format="color|reference"/><!-- 收缩收起时候的提示图标 --><attr name="shrinkDrawable" format="color|reference"/></declare-styleable>

自定义:

package com.toolbar;import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;import java.util.ArrayList;
import java.util.List;/*** 缩放展开的动画简单Textview** Created by igeek on 2016/9/1.* @author igeek2014@hotmail.com*/
public class ExpandTextView extends View implements View.OnClickListener {//行文本记录集private List<LineText> lineTexts = new ArrayList<LineText>();//最大显示文本行数private int My_maxLines;//目标文本行private int targetLine;//收缩收起时候的提示图标private Drawable expandDrawable;//展开时候的提示图标private Drawable shrinkDrawable;//提示图标的宽度private int drawableWidth;//提示图标的高度private int drawableHeight;//最大显示文本行对应的本视图高度private int maxLinesHeight;//展开时候的视图高度private int expandHeight;//当前视图的高度private int viewHeight;//收缩行结尾提示语文本宽度private float ellipsizWidth;//收缩行结尾提示语文本绘制水平起点private float ellipsizStartX;//文本字体大小private int textSize;//文本颜色private int textColor;//当前文本private String text;private String ellipsizText = "...";//收缩行文本private String shrinkLineText;//动画显示时间private int animDuration;//是否能够显示 ellipsizText 【需要收缩行当前文本的宽度】private boolean showEllipsizText = false;private boolean showTipDrawalbe = false;private boolean needMeasure = true;private StaticLayout layout;private TextPaint textPaint;public ExpandTextView(Context context) {this(context, null);}public ExpandTextView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ExpandTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ExpandTextView);My_maxLines = ta.getInt(R.styleable.ExpandTextView_My_maxLines, -1);animDuration = ta.getInt(R.styleable.ExpandTextView_animDuration, 300);textSize = ta.getDimensionPixelSize(R.styleable.ExpandTextView_textSize, 14);textColor = ta.getColor(R.styleable.ExpandTextView_textColor, 14);drawableWidth = ta.getDimensionPixelSize(R.styleable.ExpandTextView_drawableWidth, 14);drawableHeight = ta.getDimensionPixelSize(R.styleable.ExpandTextView_drawableHeight, 14);expandDrawable = ta.getDrawable(R.styleable.ExpandTextView_expandDrawable);shrinkDrawable = ta.getDrawable(R.styleable.ExpandTextView_shrinkDrawable);ta.recycle();textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);textPaint.density = context.getResources().getDisplayMetrics().density;textPaint.setColor(textColor);textPaint.setStyle(Paint.Style.FILL_AND_STROKE);textPaint.setTextSize(textSize);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = MeasureSpec.getSize(widthMeasureSpec);if (needMeasure && (!TextUtils.isEmpty(text))) {needMeasure = false;measureHeightState(text, width);startDrawAnim(0, viewHeight);}else{heightMeasureSpec = MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY);setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);}}public void updateText(String text) {if (!TextUtils.isEmpty(text)) {this.text = text;needMeasure = true;requestLayout();}}private synchronized void measureHeightState(String text, int width) {layout = new StaticLayout(text, textPaint, width - getPaddingLeft() - getPaddingRight(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0f, true);final int lineCount = layout.getLineCount();My_maxLines = (My_maxLines == -1 || My_maxLines > lineCount) ? lineCount : My_maxLines;int text_Height = 0;List<LineText> tempLines = new ArrayList<LineText>();for (int index = 0; index < lineCount; index++) {int start = layout.getLineStart(index);int end = layout.getLineEnd(index);LineText lineText = new LineText();lineText.setStartIndex(start);lineText.setEndIndex(end - 1);lineText.setText(text.substring(start, end));lineText.setTopOffset(layout.getLineTop(index));lineText.setBottomOffset(layout.getLineBottom(index));lineText.setBaseLine(layout.getLineBaseline(index)+getPaddingTop());lineText.setWidth(layout.getLineWidth(index));lineText.setHeight(lineText.getBottomOffset() - lineText.getTopOffset());tempLines.add(lineText);if (index < My_maxLines) {maxLinesHeight += lineText.getHeight();}text_Height += lineText.getHeight();}maxLinesHeight+=getPaddingTop()+getPaddingBottom();expandHeight+=getPaddingTop()+getPaddingBottom();ellipsizWidth = textPaint.measureText(ellipsizText);if (My_maxLines < lineCount) {showTipDrawalbe = expandDrawable != null && shrinkDrawable != null;float textWidth = tempLines.get(My_maxLines - 1).getWidth();float contentWidth = width - getPaddingLeft() - getPaddingRight();float toMarginRight = ellipsizWidth + (showTipDrawalbe ? drawableWidth : 0);String ellipsizLineText = tempLines.get(My_maxLines - 1).getText();if (contentWidth - textWidth < toMarginRight) {showEllipsizText = true;String subString = null;for (int index = ellipsizLineText.length() - 1; index > 0; index--) {subString = ellipsizLineText.substring(0, index);float subStrWidth = textPaint.measureText(subString);if (contentWidth - subStrWidth >= toMarginRight) {ellipsizStartX = subStrWidth + getPaddingLeft();shrinkLineText = subString;break;}}} else {shrinkLineText = ellipsizLineText;showEllipsizText = false;}} else {showTipDrawalbe = false;showEllipsizText = false;}expandHeight += text_Height + ((expandDrawable != null && showTipDrawalbe) ? drawableHeight : 0);viewHeight = My_maxLines == lineCount ? expandHeight : maxLinesHeight;targetLine = My_maxLines;lineTexts = tempLines;if (viewHeight < expandHeight) {setClickable(true);setOnClickListener(this);} else {setClickable(false);}}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (lineTexts.size() == 0) return;for (int index = 0; index < targetLine; index++) {LineText lineText = lineTexts.get(index);if (index < targetLine - 1) {canvas.drawText(lineText.getText(), getPaddingLeft(), lineText.getBaseLine(), textPaint);} else {if (targetLine == My_maxLines && My_maxLines < lineTexts.size()) {//收缩转态if (showEllipsizText)canvas.drawText(ellipsizText, ellipsizStartX, lineText.getBaseLine(), textPaint);canvas.drawText(shrinkLineText, getPaddingLeft(), lineText.getBaseLine(), textPaint);if (showTipDrawalbe){int left=getWidth() - drawableWidth - getPaddingRight();int top=getHeight() - drawableHeight-getPaddingBottom();canvas.drawBitmap(drawabletoZoomBitmap(shrinkDrawable, drawableWidth, drawableHeight), left, top, null);}} else if (targetLine == lineTexts.size()) {//展开状态canvas.drawText(lineText.getText(), getPaddingLeft(), lineText.getBaseLine(), textPaint);if (showTipDrawalbe){int left=getWidth() - drawableWidth - getPaddingRight();int top=getHeight() - drawableHeight-getPaddingBottom();canvas.drawBitmap(drawabletoZoomBitmap(expandDrawable, drawableWidth, drawableHeight), left, top, null);}}}}}@Overridepublic void onClick(View view) {if (My_maxLines == lineTexts.size())return;if (targetLine == My_maxLines) {targetLine = lineTexts.size();startDrawAnim(maxLinesHeight, expandHeight);} else if (targetLine == lineTexts.size()) {targetLine = My_maxLines;startDrawAnim(expandHeight, maxLinesHeight);}}private void startDrawAnim(int startHeight, int endHeight) {ObjectAnimator animator = ObjectAnimator.ofInt(this, "viewHeight", startHeight, endHeight);animator.setDuration(animDuration);
//        animator.setInterpolator(new AccelerateDecelerateInterpolator());animator.start();}public  int getViewHeight() {return viewHeight;}public  void setViewHeight(int viewHeight) {this.viewHeight = viewHeight;requestLayout();}public String getText() {return text;}public void setText(String text) {this.text = text;}/*** drawlable 缩放** @return*/public static Bitmap drawabletoZoomBitmap(Drawable drawable, int w, int h) {// 取 drawable 的长宽int width = drawable.getIntrinsicWidth();int height = drawable.getIntrinsicHeight();// drawable转换成bitmapBitmap oldbmp = drawabletoBitmap(drawable);// 创建操作图片用的Matrix对象Matrix matrix = new Matrix();// 计算缩放比例float sx = ((float) w / width);float sy = ((float) h / height);// 设置缩放比例matrix.postScale(sx, sy);// 建立新的bitmap,其内容是对原bitmap的缩放后的图Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height,matrix, true);return newbmp;}/*** Drawable转换成Bitmap*/public static Bitmap drawabletoBitmap(Drawable drawable) {// 取 drawable 的长宽int width = drawable.getIntrinsicWidth();int height = drawable.getIntrinsicHeight();// 取 drawable 的颜色格式Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888: Bitmap.Config.RGB_565;Bitmap bitmap = Bitmap.createBitmap(width, height, config);Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());drawable.draw(canvas);return bitmap;}}

lineText.java

package com.toolbar;/*** Created by igeek on 2016/9/1.* @author igeek2014@hotmail.com*/
public class LineText {private String text;private int startIndex;private int endIndex;private int lineIndex;private int topOffset;private int bottomOffset;private int paddingTop;private int paddingBottom;private float width;private int height;private int baseLine;public String getText() {return text;}public void setText(String text) {this.text = text;}public int getStartIndex() {return startIndex;}public void setStartIndex(int startIndex) {this.startIndex = startIndex;}public int getEndIndex() {return endIndex;}public void setEndIndex(int endIndex) {this.endIndex = endIndex;}public int getLineIndex() {return lineIndex;}public void setLineIndex(int lineIndex) {this.lineIndex = lineIndex;}public int getTopOffset() {return topOffset;}public void setTopOffset(int topOffset) {this.topOffset = topOffset;}public int getPaddingTop() {return paddingTop;}public void setPaddingTop(int paddingTop) {this.paddingTop = paddingTop;}public int getPaddingBottom() {return paddingBottom;}public void setPaddingBottom(int paddingBottom) {this.paddingBottom = paddingBottom;}public float getWidth() {return width;}public void setWidth(float width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public int getBaseLine() {return baseLine;}public void setBaseLine(int baseLine) {this.baseLine = baseLine;}public int getBottomOffset() {return bottomOffset;}public void setBottomOffset(int bottomOffset) {this.bottomOffset = bottomOffset;}
}
  <com.toolbar.ExpandTextViewandroid:id="@+id/collapsing_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="12dp"android:paddingLeft="8dp"android:paddingRight="8dp"android:paddingBottom="8dp"android:paddingTop="8dp"app:drawableHeight="12dp"app:drawableWidth="14dp"app:expandDrawable="@mipmap/up"app:My_maxLines="2"app:shrinkDrawable="@mipmap/down"app:textColor="@color/colorAccent"app:textSize="14sp" />

ExpandableTextView——一个可折叠的Textview相关推荐

  1. 【小程序】如何实现一个可折叠的列表

    作者刚接触小程序开发不久,打算用 CSDN 把学习过程中遇到的一些问题记录下来,都是一些浅显易懂的内容,希望对你也有所帮助. 如文章标题所示,作者要实现一个可折叠的列表,先来看一下页面效果: 这种展示 ...

  2. 一个仿微博TextView 筛选,直接使用的工具类

    一个仿微博TextView 筛选,直接使用的工具类 package com.example.textviewhtml;import android.content.Context; import an ...

  3. LinearLayout 里面放入一个超宽的TextView

    布局 <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android=&q ...

  4. 可扩展的TextView,ExpandableTextView与Scroller类的使用

    转载时请注明出处,尊重他人的劳动成果,谢谢. 废话不多说,先上图演示下成果(图有些丑,别见怪): 最近一直在研究Scroller类的使用方法,看了很多遍别人的例子总是感觉不得要领,最后还是自己实践一下 ...

  5. 自己实现一个可以折叠展开的TextView

    很多时候我们的文字过长时,都会选择先展示几行,点击展开按钮的时候再展示全部内容,如图所示: 今天我们就是要实现这样一个功能的textview. 实现的功能 我们实现的可以折叠展开的TextView具有 ...

  6. android标题 折叠效果,Android TextView仿微信可折叠效果

    在微信朋友圈中,发送大量的文本信息时,在展示的时候微信会将该文本信息进行折叠处理,出现"全文","收起"的操作提示.当点击全文时,才能看到全部的文本信息,正好最 ...

  7. Android TextView 实现一个单词分两行显示

    今天遇到一个需求,TextView实现自动换行时一个英文单词能够换行显示,使布局整齐.通过网上查询,确定实现逻辑如下: 自定义TextView,重写其onMeasure方法,在测量textView的宽 ...

  8. 细说 AppbarLayout,如何理解可折叠 Toolbar 的定制

    Material Design 是个好东西,它的出现使得 Android 也能定制高颜值的界面,并且指导了如果实现复杂炫丽的交互效果,而 Android Surpport Desgin 这个支持包就是 ...

  9. android点击展开textview,《Android APP可能有的东西》之UI篇:展开TextView全文

    前言 就像朋友圈里面那样的点击查看全文效果,很有可能是在项目中也会遇到.这里给出不实用自定义控件的方法,原理很简单,代码量也不大,可以直接复制粘贴到自己的项目...... 上效果图 我是图 看起来十分 ...

最新文章

  1. TX2 -cartographer安装
  2. GEO芯片数据探针id转化
  3. 《TensorFlow技术解析与实战》——导读
  4. DICOM 开发工具总结
  5. SAP Spartacus cost center list class的赋值逻辑
  6. LeetCode 07. 整数反转
  7. 照片识别出错_AI跨年龄人脸识别技术在跨年龄寻亲的应用简析
  8. JVM001_类文件结构
  9. Java 并发编程之 Callable 和 Future
  10. UVA 10558 A Brief Gerrymander
  11. 通达信众赢全部破解指标(完美无错源码副图)
  12. 关于深入浅出MFC(1)
  13. OpenCV.js 快速入门指南
  14. 计算机毕业设计Java大学生科技创新项目管理系统(源码+系统+mysql数据库+lw文档)
  15. 非常好用的模糊pid温度控制算法_PID参数调试“口诀”,总结的真好!
  16. java 拼图_拼图延迟的历史-Oracle正式将Java 9的发布日期推迟到2017年
  17. 【为您的 Android 应用添加图片】
  18. 阿里云解析是什么?个人版和企业版有什么区别?
  19. HTML中的单选按钮实现男女性别选择
  20. Java 重载(什么是重载?什么时候重载?重载有什么好处?)

热门文章

  1. QUIC构建1——chromium镜像,clone文件depot_tools的过程+git过程中的问题
  2. 围棋GUI界面Sabaki的安装与使用
  3. C Prime Plus 第二章 C语言概述
  4. Linux 磁盘坏块修复处理(错误:read error: Input/output error)
  5. 微信小程序之沉浸式导航
  6. c语言事业单位笔试题目及答案,2017年事业单位考试公共基础知识试题及答案
  7. Android 新技术
  8. javascript之活灵活现的Array
  9. linux开发板汉字显示,Linux Qt 及Arm开发板汉字显示
  10. Fitbit IPO给智能硬件从业者的启示