1. 程式人生 > >android ExpandableTextView-自定義可以動態展開/收縮顯示長文字的TextView

android ExpandableTextView-自定義可以動態展開/收縮顯示長文字的TextView

前言:

為了保持介面UI的整潔以及將盡可能多的內容顯示在有限的空間中,往往需要將長度過長的TextView進行內容擷取。本控制元件滿足了TextView可在”完整內容”與”擷取內容”兩種模式下進行切換的需求,且可應用在ListView/RecyclerView中並可以動態更新內容。

截圖:

靜態截圖如下:


這裡寫圖片描述


動態效果圖可點選如下連結:

流量黨慎點

主要功能:

  1. 限制行數,行尾新增ClickSpan,點選可以”展開”/”收起”兩種狀態切換;
  2. 可使用在ListView/RecyclerView中,效率較高;
  3. 可在任意時刻更新ExpandableTextView內容(佈局顯示之前或者顯示之後);
  4. 可自定義行數限制,預設最多顯示2行;
  5. 可自定義行尾ClickSpan是否顯示,顏色,文字,按下的背景顏色;
  6. 可新增點選此view後是否在”展開”/”收起”狀態間切換;
  7. 文字不足最大限制行數時,不截斷文字,不顯示末尾的”展開”/”收起”的指示標識;
  8. 可自定義行尾省略語與行尾”展開”/”收起”的指示標識之間的gap文字;

說明:

  1. 效果參考了jQuery的readmore.js,部分程式碼參考了ReadMoreTextView
  2. 與Github上star數最多的ExpandableTextView實現原理及UI完全不同。
  3. 暫時未新增”收縮”/”展開”時的動畫效果。

優化:

  1. 解決末尾顯示的指示標識文字與原來文字寬度不一致時的顯示問題(如原始文字與行尾指示標識文字為不同語言)。如當結尾指示標識文字較寬時,可能會顯示到下一行。以此優化UI體驗。
  2. 解決末尾單詞過長或者跟隨標點後,換行留下的空白問題。此問題源於TextView自帶的一個屬性:當結尾為完整單詞或者跟隨標點時會連同之前的部分文字一起換行。
  3. 解決文字過短時,擷取文字超出邊界的問題。
  4. 解決任何時刻為ExpandableTextView更新文字的問題。

不具有的功能:

  1. 限制字元長度。此控制元件只限制最大行數,不限制字元長度;
  2. 省略標識的位置自定義。省略標識的位置暫時只能顯示在行尾,不能夠指定是否在”行首”/”行中”/”行尾”
  3. 暫時未新增”收縮”/”展開”時的動畫效果。

新增依賴

compile 'cn.carbs.android:ExpandableTextView:1.0.0'

使用方法:

有兩種方法設定文字:
(1)在java中更新文字

//普通檢視中的更新
etv.setText(text);
//在ListView/RecyclerView中的應用
etv.updateForRecyclerView(text, etvWidth, state);//etvWidth為控制元件的真實寬度,state是控制元件所處的狀態,“收縮”/“伸展”狀態

(2)在xml中直接設定文字

<cn.carbs.android.expandabletextview.library.ExpandableTextView
                android:id="@+id/etv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/long_poem" />

實現原理:

  1. 控制元件繼承自TextViewTextView中的setText(CharSequence text)方法為 final 型別,且其內部最終呼叫了setText(CharSequence text, BufferType type),因此ExpandableTextView Override了setText(CharSequence text, BufferType type)方法,且TextView在通過xml佈局檔案設定text時,同樣最終是通過setText(CharSequence text, BufferType type)進行賦值,因此通過Override此方法達到自定義顯示text的效果;
  2. 採用android.text.Layout類來確定在一定寬度下,特定的文字所達到的行數,如果超過最大行數,則新增收縮/展開效果;
  3. 為文字特定位置新增ClickableSpan,以此新增點選部分文字的響應效果;自定義ClickableSpanLinkMovementMethod,達到新增點選ClickableSpan文字背景顏色改變的效果,感謝stackoverflow的解答;
  4. 通過Paint.measureText(String text)方法,找到文字擷取的最優位置,使得在行尾添加了ClickableSpan後,不會出現因文字寬度不同而導致的文字換行或者文字末尾空餘過大的現象;

感謝