1. 程式人生 > >根據行數要求實現展開與隱藏TextView

根據行數要求實現展開與隱藏TextView

顯示與隱藏本質是:
隱藏狀態下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);
    }
}