根据行数要求实现展开与隐藏TextView

该博客介绍了一种在Android中实现TextView展开和隐藏的方法,关键在于切换TextView在隐藏和显示状态下的高度。通过在FrameLayout下放置两个TextView,一个用于显示,一个用于计算高度,然后使用内部类存储不同状态的高度信息,并通过点击事件来切换状态,可以考虑添加属性动画增强用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

显示与隐藏本质是:
隐藏状态下TextView的高度和展开状态下TextView高度的切换。所以这个问题的关键是如何得到两种状态TextView的高度:
step1:
在Framlayout下放置两个TextView,一个用于显示一个用于计算展开状态下的TextView的高度。

<FrameLayout
       android:id="@+id/fl_survey"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
       <TextView
            android:id="@+id/tv_survey"
            style="@style/sty_project_tab_content" />
       <TextView
            android:id="@+id/tv_survey_back"
            style="@style/sty_project_tab_content" />
</FrameLayout>
<style name="sty_project_tab_content_back">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textSize">@dimen/project_detail_fs_tab_content</item>
    <item name="android:textColor">@color/app_font_light</item>
    <item name="android:paddingLeft">@dimen/app_padding_left</item>
    <item name="android:paddingRight">@dimen/app_padding_right</item>
    <item name="android:paddingBottom">@dimen/base_padding_20</item>
    <item name="android:background">@color/app_content_bg</item>
    <item name="android:visibility">gone</item>
</style>

<style name="sty_project_tab_content"
parent="@style/sty_project_tab_content_back">
    <item name="android:maxLines">2</item>
    <item name="android:ellipsize">end</item>
    <item name="android:visibility">visible</item>
</style>

step2
建立一个内部类(当然也可以是其它方式)用来表示展开与隐藏状态下的高度

private class TextViewHeightInfo{
    private int normalHeight;//默认显示的高度
    private int expandHeight;//展开后的高度

    public int getNormalHeight() {
        return normalHeight;
    }

    public void setNormalHeight(int normalHeight) {
        this.normalHeight = normalHeight;
    }

    public int getExpandHeight() {
        return expandHeight;
    }

    public void setExpandHeight(int expandHeight) {
        this.expandHeight = expandHeight;
    }
}

step3
建立一个集合存储要操作的TextView与TextViewHeightInfo信息

private HashMap<TextView,TextViewHeightInfo> tvMaps;

step4
通过以下方法去计算存储展开与隐藏状态下TextView的高度信息

/**
 * 根据文字的行数自动确定其原始高度和实际高度的大小,并保存
 * @param ivArrow 箭头对象,当隐藏状态下能全部展示内容时,箭头应该不用展示
 * @param textView 隐藏状态下的TextView,也是真实操作的TextView
 * @param textViewBack 占位TextView,主要用于计算展开式TextView的高度
 * @param content 要显示的内容
 */
private void calculateTvHeightInfo(final ImageView ivArrow,
        final TextView textView,
        final TextView textViewBack, 
        String content)
{
    textView.setText(content);
    ViewTreeObserver vto = textView.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            tvMaps.get(textView).setNormalHeight(textView.getHeight());
            textView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    });

    textViewBack.setText(content);
    ViewTreeObserver vtoBack = textViewBack.getViewTreeObserver();
    vtoBack.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            tvMaps.get(textView).setExpandHeight(textViewBack.getHeight());
            textViewBack.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            textViewBack.setVisibility(View.GONE);
            int norH = tvMaps.get(textView).getNormalHeight();
            int ExpH = tvMaps.get(textView).getExpandHeight();
            if(norH >= ExpH){
                //无需展开
                ivArrow.setVisibility(View.GONE);
            }else{
                ivArrow.setVisibility(View.VISIBLE);
            }
        }
    });
}

step5
点击箭头的事件封装,这里是单纯的改变高度,在这里完全可以加入属性动画已达到更炫酷的效果

/**
 * 点击箭头自动修改其高度已实现全部展示还是只展示初始高度
 * @param ivArrow 箭头
 * @param changedTv 要改变高度的TextView
 */
private void onClickArrow(ImageView ivArrow,TextView changedTv){
    int normalHeight = tvMaps.get(changedTv).getNormalHeight();
    int expandHeight = tvMaps.get(changedTv).getExpandHeight();
    if(expandHeight > normalHeight){
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) changedTv.getLayoutParams();
        boolean expandSurvey  = (boolean) changedTv.getTag();
        if(expandSurvey){
            params.height = normalHeight;
            changedTv.setTag(false);
            changedTv.setMaxLines(2);
            ivArrow.setImageResource(R.drawable.xiangxia);
        }else{
            params.height = expandHeight;
            changedTv.setMaxLines(Integer.MAX_VALUE);
            changedTv.setTag(true);
            ivArrow.setImageResource(R.drawable.xiangshang);
        }
        changedTv.setLayoutParams(params);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值