根據行數要求實現展開與隱藏TextView
阿新 • • 發佈:2019-01-24
顯示與隱藏本質是:
隱藏狀態下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);
}
}