android 实现微信朋友圈文字收起与全文显示功能

App中有一个类似于朋友圈文章的全文显示与收起的功能,研究了前辈的代码,分享给大家。

唯一的难点在于如何在布局完成之前获得文字的实际行数, 主要方法为view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
在视图树将要绘制的时候提供一个监听,此时视图树已经测量完毕,并且有了布局框架,在这里我们可以在绘制之前得到控件的测量数据,并且修改影响最后的绘制结果。然后我们根据实际行数与需求行数的大小关系来判断文字的显示与折叠,说完了,直接上代码。

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical">
   <TextView
       android:id="@+id/tv_content"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
   <TextView
       android:id="@+id/tv_all"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
       android:layout_marginTop="20dp"
       android:background="@drawable/selector_background_textview"
       android:padding="25dp"
       android:text="全文"
       android:textColor="@android:color/holo_red_dark" />
</LinearLayout>

功能代码:

       //lineCount文字的行数
       //fold是否是折叠状态
       //defaultMaxLine默认最多展示的行数
       tvAll.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               if (lineCount > defaultMaxLine) {
                   if (fold) {
                       tvContent.setMaxLines(10086);
                       tvAll.setText("收起");
                   } else {
                       tvContent.setMaxLines(defaultMaxLine);
                       tvAll.setText("全文");
                   }
                   fold = !fold;
               }
           }
       });
       tvContent.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
           @Override
           public boolean onPreDraw() {
               //这个回调会调用多次,获取完行数记得注销监听
               tvContent.getViewTreeObserver().removeOnPreDrawListener(this);
               lineCount = tvContent.getLineCount();
               if (lineCount > defaultMaxLine) {
                   tvContent.setMaxLines(defaultMaxLine);
                   fold = true;
                   tvAll.setVisibility(View.VISIBLE);
                   tvAll.setText("全文");
               } else {
                   tvAll.setVisibility(View.GONE);
               }
               return true;
           }
       });

源码:

/**
    * Interface definition for a callback to be invoked when the view tree is about to be drawn.
    */
   public interface OnPreDrawListener {
       /**
        * Callback method to be invoked when the view tree is about to be drawn. At this point, all
        * views in the tree have been measured and given a frame. Clients can use this to adjust
        * their scroll bounds or even to request a new layout before drawing occurs.
        *
        * @return Return true to proceed with the current drawing pass, or false to cancel.
        *
        * @see android.view.View#onMeasure
        * @see android.view.View#onLayout
        * @see android.view.View#onDraw
        */
       public boolean onPreDraw();
   }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值