Android仿微信朋友圈查看全文/收起功能(雷驚風)

  最近開發需求中要模仿微信朋友圈文章的展開收起功能,網上找了找,發現都有問題,於是乎自己在前輩的基礎上進行了一定量的修改,下邊將源碼貼出來供大家參考:

1.主Activity佈局文件就不粘貼了,很簡單,就一個ListView.

2.主Activity功能實現:

package com.example.textviewdemo;
import java.util.HashMap;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.BufferType;

public class MainActivity extends Activity {
String mStr;
int type;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Globl.map = new HashMap<Integer, Boolean>();
ListView listview = (ListView) findViewById(R.id.listview);
mStr = "手指在ListView上下滾動時,ListViewItem背景變黑,因爲在滾動的時候爲了提升性能做了優化,爲提高滾動的性能,Android 框架在ListView中引入CacheColorHint屬性。如果該值爲非0,則說明該ListView繪製在單色不透明的背景上,在默認情況下該值 爲#191919,也就是黑色主題中的黑色背景顏色值,這樣當ListView滾動的時候";
listview.setAdapter(new MyListAdpter(this));
}
class MyListAdpter extends BaseAdapter {
Context con;
CollapsibleTextView tv;

public MyListAdpter(Context con) {
this.con = con;

}

@Override
public int getCount() {
// TODO Auto-generated method stub
return 10;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}

HashMap<Integer, View> hashM = new HashMap<Integer, View>();
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder = null;
View view;
if (hashM.get(position) == null) {
holder = new Holder();
view = LayoutInflater.from(con).inflate(R.layout.item_list,
null);
holder.tv = (CollapsibleTextView) view
.findViewById(R.id.tv_text);
holder.tvcount = (TextView) view.findViewById(R.id.tvcount);
view.setTag(holder);
hashM.put(position, view);
} else {
view = hashM.get(position);
holder = (Holder) view.getTag();
}

// if (Globl.map.get(position) == false) {
// Globl.map.put(position, false);
// type = 2;
// } else {
// type = 1;
// }
// tv.setNowType(type);
// int typeNow = tv.getNowType();
holder.tvcount.setText(position + "");
holder.tv.setDesc(mStr, holder.tv, BufferType.NORMAL);
return view;
}

class Holder {
CollapsibleTextView tv;
TextView tvcount;
}
}

}



3.自定義控件CollapsibleTextView 源碼:

/**
 * @Explain: Text過長收起 帶有查看全文/收起功能控件;
 * @Author:LYl
 * @Time:2014-11-27 下午4:33:05
 * @Version V2.1.54
 */
public class CollapsibleTextView extends LinearLayout implements
OnClickListener {
/** 最大顯示的行數 */
private static final int DEFAULT_MAX_LINE_COUNT = 8;
/** 實際展示的行數 */
private static final int DEFAULT_SHOW_LINE_COUNT = 6;


private static final int COLLAPSIBLE_STATE_NONE = 0;
/** View處於展開狀態 **/
private static final int COLLAPSIBLE_STATE_SHRINKUP = 1;
/** view收縮時狀態 **/
private static final int COLLAPSIBLE_STATE_SPREAD = 2;
/** 顯示內容的View */
private TextView tv_context;
/** 展開/收起按鈕 */
private TextView bt_spread;
private String shrinkup;
private String spread;
/** 當前正處於的狀態 */
// private int mState;
private boolean flag;
private int nowType;
private CollapsibleTextView coTextView;
/** 判斷是不是點擊了查看更多、收起 */
private boolean isClicke = false;
private int lookCount = 0;

public CollapsibleTextView(Context context, AttributeSet attrs) {
super(context, attrs);
shrinkup = "收起";
spread = "查看全文";
View view = inflate(context, R.layout.collapsible_textview, this);
view.setPadding(0, -1, 0, 0);
tv_context = (TextView) view.findViewById(R.id.tv_context);
bt_spread = (TextView) view.findViewById(R.id.bt_spread);
bt_spread.setOnClickListener(this);
}

public CollapsibleTextView(Context context) {
this(context, null);
}

/**
* 賦值
*/
public final void setDesc(CharSequence charSequence,
CollapsibleTextView tv, BufferType bufferType) {
this.coTextView = tv;
// 對內容中的網址進行處理;
tv_context.setAutoLinkMask(Linkify.WEB_URLS);
tv_context.setMovementMethod(LinkMovementMethod.getInstance());
tv_context.setText(charSequence, bufferType);
// 初始類型
if (lookCount == 0) {
coTextView.setNowType(COLLAPSIBLE_STATE_SPREAD);
}
lookCount += 1;
// TODO LYL 放到ListView中需要加下句:falg=false;一般情況去掉就可
flag = false;
requestLayout();
}


@Override
public void onClick(View v) {
flag = false;
isClicke = true;
requestLayout();
}


@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (!flag) {
flag = true;
if (tv_context.getLineCount() <= DEFAULT_MAX_LINE_COUNT) {
bt_spread.setVisibility(View.GONE);
tv_context.setMaxLines(DEFAULT_MAX_LINE_COUNT + 1);
coTextView.setNowType(COLLAPSIBLE_STATE_NONE);
} else {
post(new InnerRunnable());


}
}
}


class InnerRunnable implements Runnable {
@Override
public void run() {
int zType = 0;
// 第一次進入操作(沒有點擊並且是第一次進入);
System.out.println("lookCount:" + lookCount);
if (!isClicke && lookCount == 1) {
if (coTextView.getNowType() == COLLAPSIBLE_STATE_SPREAD) {
tv_context.setMaxLines(DEFAULT_SHOW_LINE_COUNT);
bt_spread.setVisibility(View.VISIBLE);
bt_spread.setText(spread);
zType = COLLAPSIBLE_STATE_SHRINKUP;
} else if (coTextView.getNowType() == COLLAPSIBLE_STATE_SHRINKUP) {
tv_context.setMaxLines(Integer.MAX_VALUE);
bt_spread.setVisibility(View.VISIBLE);
bt_spread.setText(shrinkup);
zType = COLLAPSIBLE_STATE_SPREAD;
}
coTextView.setNowType(zType);
// 點擊了查看更多、收起轉換狀態;
} else if (isClicke) {
isClicke = false;
if (coTextView.getNowType() == COLLAPSIBLE_STATE_SPREAD) {
tv_context.setMaxLines(DEFAULT_SHOW_LINE_COUNT);
bt_spread.setVisibility(View.VISIBLE);
bt_spread.setText(spread);
coTextView.setNowType(COLLAPSIBLE_STATE_SHRINKUP);
} else if (coTextView.getNowType() == COLLAPSIBLE_STATE_SHRINKUP) {
tv_context.setMaxLines(Integer.MAX_VALUE);
bt_spread.setVisibility(View.VISIBLE);
bt_spread.setText(shrinkup);
coTextView.setNowType(COLLAPSIBLE_STATE_SPREAD);
}
// 滑動listView 從新載入到可見界面 不做操作,保持原有狀態;(爲了後面看得人能夠更理解寫上)
} else if (!isClicke && lookCount != 1) {

}

}
}


public int getNowType() {
return nowType;
}


public void setNowType(int nowType) {
this.nowType = nowType;
}

}




4.自定義控件加載的Layout:

<?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_context"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4.0dip"
        android:gravity="center_vertical"
        android:textColor="#ff000000"
        android:textSize="14.0dip" />
    <TextView
        android:id="@+id/bt_spread"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="4.0dip"
        android:gravity="center"
        android:singleLine="true"
        android:textColor="#ff576b95"
        android:textSize="18.0dip"
        android:visibility="gone" />
</LinearLayout>


現在經過修改後其實還是有點小問題的,如果按照上邊的寫的話,偶爾點擊收起/展開按鈕會失效,但是一滑動整體ListView就會執行操作;如果,將getView()方法中的HashMap判斷換成ConvertView判斷,點擊就沒問題了,但是展開一個item後慢慢的滑出屏幕,您會發現,下邊剛剛出現的Item會處於打開狀態,本人才疏學淺,猜測可能是複用了,目前沒想到什麼好的方法解決,希望能有大神指點一下,這是目的之一,同時也希望能幫助初學者!

下邊是運行後的結果:


發佈了29 篇原創文章 · 獲贊 29 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章