android全文收起功能,Android仿微信朋友圈查看全文/收起功能(雷惊风)

本文介绍如何在Android应用中实现类似微信朋友圈文章的展开收起功能,通过自定义CollapsibleTextView控件,实现了文本内容的动态展开和收起。在ListView中使用该控件时,遇到一些问题,如点击收起/展开按钮偶现失效,滑动ListView后新显示的Item状态异常。作者分享了源码并提出了当前解决方案存在的小问题,希望能帮助其他开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近开发需求中要模仿微信朋友圈文章的展开收起功能,网上找了找,发现都有问题,于是乎自己在前辈的基础上进行了一定量的修改,下边将源码贴出来供大家参考:

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();

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 hashM = new HashMap();

@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:

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

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" />

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" />

现在经过修改后其实还是有点小问题的,如果按照上边的写的话,偶尔点击收起/展开按钮会失效,但是一滑动整体ListView就会执行操作;如果,将getView()方法中的HashMap判断换成ConvertView判断,点击就没问题了,但是展开一个item后慢慢的滑出屏幕,您会发现,下边刚刚出现的Item会处于打开状态,本人才疏学浅,猜测可能是复用了,目前没想到什么好的方法解决,希望能有大神指点一下,这是目的之一,同时也希望能帮助初学者!

下边是运行后的结果:

0818b9ca8b590ca3270a3433284dd417.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值