Android可伸展textview

这篇具有很好参考价值的文章主要介绍了Android可伸展textview。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 文章来源地址https://www.toymoban.com/news/detail-833002.html

  • 显示内容最大显示行数配置
  • 显示内容字体大小颜色配置
  • 展开/收起图标配置
  • 展开/收起位置配置
  • 展开/收起字体大小颜色配置
  • 展开/收起变化监听
//收缩TextView
    implementation 'com.jaydenxiao:ExpandableTextView:1.0.0'
ExpandableTextView
package com.example.testcsdnproject.view;


import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.SparseBooleanArray;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.core.content.ContextCompat;

import jaydenxiao.com.expandabletextview.UIUtil;

/**
 * des:可伸展textview
 */
public class ExpandableTextView extends LinearLayout implements View.OnClickListener {

    /* 默认最高行数 */
    private static final int MAX_COLLAPSED_LINES = 5;

    /* 默认动画执行时间 */
    private static final int DEFAULT_ANIM_DURATION = 200;

    /*内容textview*/
    protected TextView mTvContent;

    /*展开收起textview*/
    protected TextView mTvExpandCollapse;

    /*是否有重新绘制*/
    private boolean mRelayout;

    /*默认收起*/
    private boolean mCollapsed = true;

    /*展开图片*/
    private Drawable mExpandDrawable;
    /*收起图片*/
    private Drawable mCollapseDrawable;
    /*动画执行时间*/
    private int mAnimationDuration;
    /*是否正在执行动画*/
    private boolean mAnimating;
    /* 展开收起状态回调 */
    private jaydenxiao.com.expandabletextview.ExpandableTextView.OnExpandStateChangeListener mListener;
    /* listview等列表情况下保存每个item的收起/展开状态 */
    private SparseBooleanArray mCollapsedStatus;
    /* 列表位置 */
    private int mPosition;

    /*设置内容最大行数,超过隐藏*/
    private int mMaxCollapsedLines;

    /*这个linerlayout容器的高度*/
    private int mCollapsedHeight;

    /*内容tv真实高度(含padding)*/
    private int mTextHeightWithMaxLines;

    /*内容tvMarginTopAmndBottom高度*/
    private int mMarginBetweenTxtAndBottom;

    /*内容颜色*/
    private int contentTextColor;
    /*收起展开颜色*/
    private int collapseExpandTextColor;
    /*内容字体大小*/
    private float contentTextSize;
    /*收起展字体大小*/
    private float collapseExpandTextSize;
    /*收起文字*/
    private String textCollapse;
    /*展开文字*/
    private String textExpand;

    /*收起展开位置,默认左边*/
    private int grarity;

    public ExpandableTextView(Context context) {
        this(context, null);
    }

    public ExpandableTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public ExpandableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs);
    }

    @Override
    public void setOrientation(int orientation) {
        if (LinearLayout.HORIZONTAL == orientation) {
            throw new IllegalArgumentException("ExpandableTextView only supports Vertical Orientation.");
        }
        super.setOrientation(orientation);
    }
    /**
     * 初始化属性
     * @param attrs
     */
    private void init(AttributeSet attrs) {
        mCollapsedStatus=new SparseBooleanArray();

        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView);
        mMaxCollapsedLines = typedArray.getInt(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_maxCollapsedLines, MAX_COLLAPSED_LINES);
        mAnimationDuration = typedArray.getInt(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_animDuration, DEFAULT_ANIM_DURATION);
        mExpandDrawable = typedArray.getDrawable(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_expandDrawable);
        mCollapseDrawable = typedArray.getDrawable(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_collapseDrawable);

        textCollapse = typedArray.getString(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_textCollapse);
        textExpand = typedArray.getString(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_textExpand);

        if (mExpandDrawable == null) {
            mExpandDrawable = ContextCompat.getDrawable(getContext(), jaydenxiao.com.expandabletextview.R.drawable.icon_green_arrow_down);
        }
        if (mCollapseDrawable == null) {
            mCollapseDrawable = ContextCompat.getDrawable(getContext(), jaydenxiao.com.expandabletextview.R.drawable.icon_green_arrow_up);
        }

        if (TextUtils.isEmpty(textCollapse)) {
            textCollapse = getContext().getString(jaydenxiao.com.expandabletextview.R.string.collapse);
        }
        if (TextUtils.isEmpty(textExpand)) {
            textExpand = getContext().getString(jaydenxiao.com.expandabletextview.R.string.expand);
        }
        contentTextColor = typedArray.getColor(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_contentTextColor, ContextCompat.getColor(getContext(), jaydenxiao.com.expandabletextview.R.color.gray));
        contentTextSize = typedArray.getDimension(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_contentTextSize, UIUtil.sp2px(getContext(),14));

        collapseExpandTextColor = typedArray.getColor(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_collapseExpandTextColor, ContextCompat.getColor(getContext(), jaydenxiao.com.expandabletextview.R.color.main_color));
        collapseExpandTextSize = typedArray.getDimension(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_collapseExpandTextSize, UIUtil.sp2px(getContext(),14));

        grarity = typedArray.getInt(jaydenxiao.com.expandabletextview.R.styleable.ExpandableTextView_collapseExpandGrarity, Gravity.CENTER);

        typedArray.recycle();
        // enforces vertical orientation
        setOrientation(LinearLayout.VERTICAL);
        // default visibility is gone
        setVisibility(GONE);
    }

    /**
     * 渲染完成时初始化view
     */
    @SuppressLint("MissingSuperCall")
    @Override
    protected void onFinishInflate() {
        findViews();
    }

    /**
     * 初始化viwe
     */
    private void findViews() {
        LayoutInflater inflater = (LayoutInflater) getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(jaydenxiao.com.expandabletextview.R.layout.item_expand_collapse, this);
        mTvContent = (TextView) findViewById(jaydenxiao.com.expandabletextview.R.id.expandable_text);
        mTvContent.setOnClickListener(this);
        mTvExpandCollapse = (TextView) findViewById(jaydenxiao.com.expandabletextview.R.id.expand_collapse);
        mTvExpandCollapse.setCompoundDrawablesWithIntrinsicBounds(null,null,mCollapsed ? mExpandDrawable : mCollapseDrawable,null);
        mTvExpandCollapse.setText(mCollapsed ? getResources().getString(jaydenxiao.com.expandabletextview.R.string.expand) : getResources().getString(jaydenxiao.com.expandabletextview.R.string.collapse));
        mTvExpandCollapse.setOnClickListener(this);

        mTvContent.setTextColor(contentTextColor);
        mTvContent.getPaint().setTextSize(contentTextSize);

        mTvExpandCollapse.setTextColor(collapseExpandTextColor);
        mTvExpandCollapse.getPaint().setTextSize(collapseExpandTextSize);

        //设置收起展开位置:左或者右
        LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        lp.gravity = grarity;
        mTvExpandCollapse.setLayoutParams(lp);
    }

    public void showShouTextview(){
        if (mTvExpandCollapse.getVisibility() != View.VISIBLE) {
            return;
        }
        mCollapsed = !mCollapsed;
        //修改收起/展开图标、文字
        mTvExpandCollapse.setCompoundDrawablesWithIntrinsicBounds(null,null,mCollapsed ? mExpandDrawable : mCollapseDrawable,null);
        mTvExpandCollapse.setText(mCollapsed ? getResources().getString(jaydenxiao.com.expandabletextview.R.string.expand) : getResources().getString(jaydenxiao.com.expandabletextview.R.string.collapse));
        //保存位置状态
        if (mCollapsedStatus != null) {
            mCollapsedStatus.put(mPosition, mCollapsed);
        }
        // 执行展开/收起动画
        mAnimating = true;
        ValueAnimator valueAnimator;
        if (mCollapsed) {
//            mTvContent.setMaxLines(mMaxCollapsedLines);
            valueAnimator = new ValueAnimator().ofInt(getHeight(), mCollapsedHeight);
        } else {
            valueAnimator = new ValueAnimator().ofInt(getHeight(), getHeight() +
                    mTextHeightWithMaxLines - mTvContent.getHeight());
        }
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int animatedValue = (int) valueAnimator.getAnimatedValue();
                mTvContent.setMaxHeight(animatedValue - mMarginBetweenTxtAndBottom);
                getLayoutParams().height = animatedValue;
                requestLayout();
            }
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {

            }
            @Override
            public void onAnimationEnd(Animator animator) {
                // 动画结束后发送结束的信号
                /// clear the animation flag
                mAnimating = false;
                // notify the listener
                if (mListener != null) {
                    mListener.onExpandStateChanged(mTvContent, !mCollapsed);
                }
            }
            @Override
            public void onAnimationCancel(Animator animator) {

            }
            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });
        valueAnimator.setDuration(mAnimationDuration);
        valueAnimator.start();
    }
    /**
     * 点击事件
     * @param view
     */
    @Override
    public void onClick(View view) {
        if (mTvExpandCollapse.getVisibility() != View.VISIBLE) {
            return;
        }
        mCollapsed = !mCollapsed;
        //修改收起/展开图标、文字
        mTvExpandCollapse.setCompoundDrawablesWithIntrinsicBounds(null,null,mCollapsed ? mExpandDrawable : mCollapseDrawable,null);
        mTvExpandCollapse.setText(mCollapsed ? getResources().getString(jaydenxiao.com.expandabletextview.R.string.expand) : getResources().getString(jaydenxiao.com.expandabletextview.R.string.collapse));
        //保存位置状态
        if (mCollapsedStatus != null) {
            mCollapsedStatus.put(mPosition, mCollapsed);
        }
        // 执行展开/收起动画
        mAnimating = true;
        ValueAnimator valueAnimator;
        if (mCollapsed) {
//            mTvContent.setMaxLines(mMaxCollapsedLines);
            valueAnimator = new ValueAnimator().ofInt(getHeight(), mCollapsedHeight);
        } else {
            valueAnimator = new ValueAnimator().ofInt(getHeight(), getHeight() +
                    mTextHeightWithMaxLines - mTvContent.getHeight());
        }
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int animatedValue = (int) valueAnimator.getAnimatedValue();
                mTvContent.setMaxHeight(animatedValue - mMarginBetweenTxtAndBottom);
                getLayoutParams().height = animatedValue;
                requestLayout();
            }
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {

            }
            @Override
            public void onAnimationEnd(Animator animator) {
                // 动画结束后发送结束的信号
                /// clear the animation flag
                mAnimating = false;
                // notify the listener
                if (mListener != null) {
                    mListener.onExpandStateChanged(mTvContent, !mCollapsed);
                }
            }
            @Override
            public void onAnimationCancel(Animator animator) {

            }
            @Override
            public void onAnimationRepeat(Animator animator) {

            }
        });
        valueAnimator.setDuration(mAnimationDuration);
        valueAnimator.start();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // 当动画还在执行状态时,拦截事件,不让child处理
        return mAnimating;
    }
    /**
     * 重新测量
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // If no change, measure and return
        if (!mRelayout || getVisibility() == View.GONE) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }
        mRelayout = false;

        // Setup with optimistic case
        // i.e. Everything fits. No button needed
        mTvExpandCollapse.setVisibility(View.GONE);
        mTvContent.setMaxLines(Integer.MAX_VALUE);

        // Measure
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //如果内容真实行数小于等于最大行数,不处理
        if (mTvContent.getLineCount() <= mMaxCollapsedLines) {
            return;
        }
        // 获取内容tv真实高度(含padding)
        mTextHeightWithMaxLines = getRealTextViewHeight(mTvContent);

        // 如果是收起状态,重新设置最大行数
        if (mCollapsed) {
            mTvContent.setMaxLines(mMaxCollapsedLines);
        }
        mTvExpandCollapse.setVisibility(View.VISIBLE);

        // Re-measure with new setup
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if (mCollapsed) {
            // Gets the margin between the TextView's bottom and the ViewGroup's bottom
            mTvContent.post(new Runnable() {
                @Override
                public void run() {
                    mMarginBetweenTxtAndBottom = getHeight() - mTvContent.getHeight();
                }
            });
            // 保存这个容器的测量高度
            mCollapsedHeight = getMeasuredHeight();
        }
    }
    /**
     * 获取内容tv真实高度(含padding)
     * @param textView
     * @return
     */
    private static int getRealTextViewHeight( TextView textView) {
        int textHeight = textView.getLayout().getLineTop(textView.getLineCount());
        int padding = textView.getCompoundPaddingTop() + textView.getCompoundPaddingBottom();
        return textHeight + padding;
    }




    /*********暴露给外部调用方法***********/

    /**
     * 设置收起/展开监听
     * @param listener
     */
    public void setOnExpandStateChangeListener( jaydenxiao.com.expandabletextview.ExpandableTextView.OnExpandStateChangeListener listener) {
        mListener = listener;
    }

    /**
     * 设置内容
     * @param text
     */
    public void setText( CharSequence text) {
        mRelayout = true;
        mTvContent.setText(text);
        setVisibility(TextUtils.isEmpty(text) ? View.GONE : View.VISIBLE);
    }

    /**
     * 设置内容,列表情况下,带有保存位置收起/展开状态
     * @param text
     * @param position
     */
    public void setText( CharSequence text,int position) {
        mPosition = position;
        //获取状态,如无,默认是true:收起
        mCollapsed = mCollapsedStatus.get(position, true);
        clearAnimation();
        //设置收起/展开图标和文字
        mTvExpandCollapse.setCompoundDrawablesWithIntrinsicBounds(null,null,mCollapsed ? mExpandDrawable : mCollapseDrawable,null);
        mTvExpandCollapse.setText(mCollapsed ? getResources().getString(jaydenxiao.com.expandabletextview.R.string.expand) : getResources().getString(jaydenxiao.com.expandabletextview.R.string.collapse));

        setText(text);
        getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
        requestLayout();
    }

    /**
     * 获取内容
     * @return
     */
    public CharSequence getText() {
        if (mTvContent == null) {
            return "";
        }
        return mTvContent.getText();
    }

    /**
     * 定义状态改变接口
     */
    public interface OnExpandStateChangeListener {
        /**
         * @param textView   - TextView being expanded/collapsed
         * @param isExpanded - true if the TextView has been expanded
         */
        void onExpandStateChanged(TextView textView, boolean isExpanded);
    }
}

 xml:

<com.example.testcsdnproject.view.ExpandableTextView
        android:id="@+id/tv_lab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="数据"
        android:textColor="@color/black"
        android:textSize="12sp"
        app:layout_constraintTop_toBottomOf="@+id/btn_get_lab"
        tools:ignore="MissingConstraints"
        tools:layout_editor_absoluteX="0dp"

        app:collapseDrawable="@mipmap/ic_up_aztec"
        app:collapseExpandTextColor="#FF3D5AFE"
        app:collapseExpandTextSize="12sp"
        app:contentTextSize="12sp"
        app:expandDrawable="@mipmap/ic_down_aztec"
        app:maxCollapsedLines="3"
        app:textCollapse="收起"
        app:textExpand="展开"
        app:contentTextColor="#FFB9B9B9"
        app:collapseExpandGrarity="right"


        /><!-- app:collapseExpandGrarity="right" 默认居中,可以设置左右-->

 collapseDrawable,expandDrawable  设置展开收起的图标

 代码中设置TextView的内容:

tv_lab.setText(labStr);

Android可伸展textview,android

Android可伸展textview,android 

 

到了这里,关于Android可伸展textview的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android中TextView滚动实现方式

    下面展示一些 内联代码片 。

    2024年02月21日
    浏览(38)
  • Android TextView字体加粗效果

    两种不同的字体加粗效果: 正常情况下,TextView 设置字体加粗效果,直接在 xml 中设置, 第二种,则是通过代码设置 TextView,此处就不要设置 blod 了 看下,两种字体的加粗效果,看情况设置吧

    2024年02月07日
    浏览(44)
  • Android应用开发(6)TextView进阶用法

     Android应用开发学习笔记——目录索引 上一章Android应用开发(5)文本视图(TextView)介绍了文本视图(TextView)设置文本内容、设置文本大小、设置文本显示颜色。 TextView是最基础的文本显示控件,常用的基本属性和设置方法有: XML中的属性 TextView类的设置方法 说明 andro

    2024年02月14日
    浏览(47)
  • 【Android】TextView字体大小自适应的方式

    众所周知,同样的一个话在中英文环境中的字符长度是不一样的。如果TextView没有做相应的适配,那么在切换环境之后读取xml中文本会导致UI变样。尤其是英文文本容易展示不全的问题。 在android 8 以及以上添加了用来动态改变TextView字体大小的新特性 Autosizing TextViews,只需要

    2024年02月13日
    浏览(42)
  • Android 妙用TextView实现左边文字,右边图片

    原文: Android 妙用TextView实现左边文字,右边图片 - Stars-One的杂货小窝 有时候,需要文字在左边,右边有个箭头,我个人之前会有两种做法: 使用线性布局来实现 或者使用约束布局,一个左对齐,一个右对齐 这几天突然想到是否可以使用TextView的设置图标的方式实现,研究发现确实可以

    2024年02月17日
    浏览(47)
  • Android TextView文字使用字体的3种方法

    Android给文字添加字体效果有3种方法: 1.直接在xml布局里面添加 先将字体文件复制到该位置  然后在xml中引用该文件 2.在activity里面设置(1)  先将字体文件复制到该位置 然后在activity里面设置该字体  3.在activity里面设置(2) 先将字体文件复制到该位置 然后在activity里面设

    2024年02月06日
    浏览(42)
  • Android入门教程 | TextView简介(宽高、文字、间距)

    TextView简介 文字,是我们传达信息的一种常见方式。在安卓应用上显示文字,我们通常使用TextView。 之前我们已经知道如何获取到layout中的TextView,也知道 setText() 方法可以修改显示的文字。 结合我们实际的生活和学习经验,写字的时候,有哪些方面是可以由我们来控制的?

    2024年02月04日
    浏览(46)
  • Android基础篇 TextView 设置行间距字间距

    TextView 设置行间距可以通过设置TextView属性的 android:lineSpacingExtra 或 android:lineSpacingMultiplier 来达到效果 1、 android:lineSpacingExtra 设置行间距: 2、 android:lineSpacingMultiplier 设置行间距的倍数 通过设置 android:letterSpacing 这个属性就可以非常方便的设置水平方向文本的字间距 1、XML中

    2024年02月11日
    浏览(49)
  • Android学习笔记(四):TextView 设置内容、字体大小、颜色、背景

             如图所示,我们可以在Android手机中设置文本字体的大小、颜色,以及背景颜色。         我们前面章节已经提到过,如何利用TextView模块显示文本内容,在这里再简单提及一次吧。         想必,通过前面的学习,你已经能够读懂以上代码的含义,并且,能够在对

    2024年02月05日
    浏览(83)
  • Android根据TextView的文本大小计算其宽度和高度

    Android根据TextView的文本大小计算其宽度和高度 在Android开发中,TextView是常用的UI组件之一,用于显示文本内容。有时候我们需要根据TextView的文本大小来动态计算其宽度和高度,以便适应不同长度的文本内容。本文将介绍如何使用Java代码来实现这一功能。 首先,我们需要获取

    2024年02月02日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包