前言
一般在社交APP中都有類似朋友圈的功能,其中發(fā)表的動(dòng)態(tài)內(nèi)容很長的時(shí)候不可能讓它全部顯示彪笼。這里就需要做一個(gè)仿微信朋友圈全文钻注、收起功能來解決該問題。在網(wǎng)上看到一個(gè)例子--> http://blog.csdn.net/e042kuuw/article/details/55107537 配猫,寫的很不錯(cuò)幅恋,但是有個(gè)bug,他這個(gè)Demo只有在條目固定的時(shí)候才正常泵肄,當(dāng)增加捆交、刪除條目的時(shí)候會(huì)出現(xiàn)全文、收起顯示混亂的問題腐巢。原因是他使用了固定的position作為key來保存當(dāng)前顯示的狀態(tài)零渐。這篇文章在他的基礎(chǔ)上進(jìn)行優(yōu)化。
效果圖
具體代碼
(詳細(xì)解釋在代碼注釋中都有系忙,這里就省略了)
MainActivity.java
package com.wildma.wildmaexpandfoldtext;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
/**
* Author wildma
* DATE 2017/8/3
* Des ${TODO}
*/
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
List<ExpandFoldTextBean> mList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
ExpandFoldTextAdapter adapter = new ExpandFoldTextAdapter(mList, this);
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
mRecyclerView.setAdapter(adapter);
}
/**
* 初始化數(shù)據(jù)
*/
private void initData() {
String longContent = "-->游泳诵盼、快走、慢跑银还、騎自行車风宁,及一切有氧運(yùn)動(dòng)都能鍛煉心臟。有氧運(yùn)動(dòng)好處多:能鍛煉心肺蛹疯、增強(qiáng)循環(huán)系統(tǒng)功能戒财、燃燒脂肪、加大肺活量捺弦、降低血壓饮寞,甚至能預(yù)防糖尿病,減少心臟病的發(fā)生列吼。美國運(yùn)動(dòng)醫(yī)學(xué)院建議幽崩,想知道有氧運(yùn)動(dòng)強(qiáng)度是否合適,可在運(yùn)動(dòng)后測試心率寞钥,以達(dá)到最高心率的60%—90%為宜慌申。如果想通過有氧運(yùn)動(dòng)來減肥,可以選擇低度到中度的運(yùn)動(dòng)強(qiáng)度理郑,同時(shí)延長運(yùn)動(dòng)時(shí)間蹄溉,這種方法消耗的熱量更多咨油。運(yùn)動(dòng)頻率每周3—5次,每次20—60分鐘柒爵。想要鍛煉肌肉役电,可以練舉重、做體操以及其他重復(fù)伸棉胀、屈肌肉的運(yùn)動(dòng)宴霸。肌肉鍛煉可以燃燒熱量、增強(qiáng)骨密度膏蚓、減少受傷,尤其是關(guān)節(jié)受傷的幾率畸写,還能預(yù)防骨質(zhì)疏松驮瞧。 在做舉重運(yùn)動(dòng)前,先測一下枯芬,如果連續(xù)舉8次你最多能舉多重的東西论笔,就從這個(gè)重量開始練習(xí)。當(dāng)你可以連續(xù)12次舉起這個(gè)重量時(shí)千所,試試增加5%的重量狂魔。注意每次練習(xí)時(shí),要連續(xù)舉8—12次淫痰,這樣可以達(dá)到肌肉最大耐力的70%—80%最楷,鍛煉效果較好。每周2—3次待错,但要避免連續(xù)兩天鍛煉同一組肌肉群籽孙, 以便讓肌肉有充分的恢復(fù)時(shí)間。";
String shortContent = "-->健身是一種體育項(xiàng)目火俄,如各種徒手健美操犯建、韻律操、形體操以及各種自抗力動(dòng)作瓜客。";
for (int i = 0; i < 20; i++) {
ExpandFoldTextBean bean = new ExpandFoldTextBean();
if (i % 2 == 0) {
bean.setContent(i + shortContent);
bean.setId(i);
} else {
bean.setContent(i + longContent);
bean.setId(i);
}
mList.add(bean);
}
}
}
ExpandFoldTextAdapter.java
package com.wildma.wildmaexpandfoldtext;
import android.app.Activity;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.TextView;
import java.util.List;
/**
* Author wildma
* DATE 2017/8/3
* Des ${展開折疊文本適配器}
*/
public class ExpandFoldTextAdapter extends RecyclerView.Adapter<ExpandFoldTextAdapter.MyViewHolder> {
private Activity mContent;
private final int MAX_LINE_COUNT = 3;//最大顯示行數(shù)
private final int STATE_UNKNOW = -1;//未知狀態(tài)
private final int STATE_NOT_OVERFLOW = 1;//文本行數(shù)小于最大可顯示行數(shù)
private final int STATE_COLLAPSED = 2;//折疊狀態(tài)
private final int STATE_EXPANDED = 3;//展開狀態(tài)
/**
* 注意:保存文本狀態(tài)集合的key一定要是唯一的适瓦,如果用position。
* 如果使用position作為key谱仪,則刪除玻熙、增加條目的時(shí)候會(huì)出現(xiàn)顯示錯(cuò)亂
*/
private SparseArray<Integer> mTextStateList;//保存文本狀態(tài)集合
List<ExpandFoldTextBean> mList;
public ExpandFoldTextAdapter(List<ExpandFoldTextBean> list, Activity context) {
mContent = context;
this.mList = list;
mTextStateList = new SparseArray<>();
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(mContent.getLayoutInflater().inflate(R.layout.item_expand_fold_text, parent, false));
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
int state = mTextStateList.get(mList.get(position).getId(), STATE_UNKNOW);
//第一次初始化,未知狀態(tài)
if (state == STATE_UNKNOW) {
holder.content.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
//這個(gè)回掉會(huì)調(diào)用多次疯攒,獲取完行數(shù)后記得注銷監(jiān)聽
holder.content.getViewTreeObserver().removeOnPreDrawListener(this);
//holder.content.getViewTreeObserver().addOnPreDrawListener(null);
//如果內(nèi)容顯示的行數(shù)大于最大顯示行數(shù)
if (holder.content.getLineCount() > MAX_LINE_COUNT) {
holder.content.setMaxLines(MAX_LINE_COUNT);//設(shè)置最大顯示行數(shù)
holder.expandOrFold.setVisibility(View.VISIBLE);//顯示“全文”
holder.expandOrFold.setText("全文");
mTextStateList.put(mList.get(position).getId(), STATE_COLLAPSED);//保存狀態(tài)
} else {
holder.expandOrFold.setVisibility(View.GONE);
mTextStateList.put(mList.get(position).getId(), STATE_NOT_OVERFLOW);
}
return true;
}
});
holder.content.setMaxLines(Integer.MAX_VALUE);//設(shè)置文本的最大行數(shù)揭芍,為整數(shù)的最大數(shù)值
holder.content.setText(mList.get(position).getContent());
} else {
//如果之前已經(jīng)初始化過了,則使用保存的狀態(tài)卸例。
switch (state) {
case STATE_NOT_OVERFLOW:
holder.expandOrFold.setVisibility(View.GONE);
break;
case STATE_COLLAPSED:
holder.content.setMaxLines(MAX_LINE_COUNT);
holder.expandOrFold.setVisibility(View.VISIBLE);
holder.expandOrFold.setText("全文");
break;
case STATE_EXPANDED:
holder.content.setMaxLines(Integer.MAX_VALUE);
holder.expandOrFold.setVisibility(View.VISIBLE);
holder.expandOrFold.setText("收起");
break;
}
holder.content.setText(mList.get(position).getContent());
}
//全文和收起的點(diǎn)擊事件
holder.expandOrFold.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int state = mTextStateList.get(mList.get(position).getId(), STATE_UNKNOW);
if (state == STATE_COLLAPSED) {
holder.content.setMaxLines(Integer.MAX_VALUE);
holder.expandOrFold.setText("收起");
mTextStateList.put(mList.get(position).getId(), STATE_EXPANDED);
} else if (state == STATE_EXPANDED) {
holder.content.setMaxLines(MAX_LINE_COUNT);
holder.expandOrFold.setText("全文");
mTextStateList.put(mList.get(position).getId(), STATE_COLLAPSED);
}
}
});
//刪除點(diǎn)擊事件
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mList.remove(position);
notifyDataSetChanged();
}
});
}
@Override
public int getItemCount() {
return mList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView nickname;
public TextView content;
public TextView delete;
public TextView expandOrFold;
public MyViewHolder(View itemView) {
super(itemView);
nickname = (TextView) itemView.findViewById(R.id.tv_nickname);
content = (TextView) itemView.findViewById(R.id.tv_content);
delete = (TextView) itemView.findViewById(R.id.tv_delete);
expandOrFold = (TextView) itemView.findViewById(R.id.tv_expand_or_fold);
}
}
}
ExpandFoldTextBean.java
package com.wildma.wildmaexpandfoldtext;
/**
* Author wildma
* DATE 2017/8/3
* Des ${TODO}
*/
public class ExpandFoldTextBean {
private String content;//內(nèi)容
private int id;//該條數(shù)據(jù)的id
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
item_expand_fold_text.xml
<?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="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginRight="16dp"
android:gravity="center"
android:scaleType="centerCrop"
android:src="@mipmap/ic_launcher"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_nickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="wildma"
android:textColor="@android:color/black"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginLeft="12dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="刪除"
android:textColor="@android:color/holo_red_dark"
android:textSize="14sp"/>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="56dp"
android:orientation="vertical"
android:paddingBottom="8dp">
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:alpha="0.85"
android:ellipsize="end"
android:text="內(nèi)容"
android:textColor="@android:color/black"
android:textSize="14sp"/>
<TextView
android:id="@+id/tv_expand_or_fold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全文"
android:textColor="@color/colorPrimaryDark"
android:textSize="14sp"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@android:color/black"/>
</LinearLayout>
源碼地址:https://github.com/wildma/WildmaExpandFoldText 歡迎star !
參考:http://blog.csdn.net/e042kuuw/article/details/55107537