Android仿微信朋友圈全文、收起功能的实例代码
程序员文章站
2023-10-19 22:48:12
前言
一般在社交app中都有类似朋友圈的功能,其中发表的动态内容很长的时候不可能让它全部显示。这里就需要做一个仿微信朋友圈全文、收起功能来解决该问题。在网上看到一个例子-...
前言
一般在社交app中都有类似朋友圈的功能,其中发表的动态内容很长的时候不可能让它全部显示。这里就需要做一个仿微信朋友圈全文、收起功能来解决该问题。在网上看到一个例子-->,写的很不错,但是有个bug,他这个demo只有在条目固定的时候才正常,当增加、删除条目的时候会出现全文、收起显示混乱的问题。原因是他使用了固定的position作为key来保存当前显示的状态。这篇文章在他的基础上进行优化。
效果图
具体代码
(详细解释在代码注释中都有,这里就省略了)
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); } /** * 初始化数据 */ private void initdata() { string longcontent = "-->游泳、快走、慢跑、骑自行车,及一切有氧运动都能锻炼心脏。有氧运动好处多:能锻炼心肺、增强循环系统功能、燃烧脂肪、加大肺活量、降低血压,甚至能预防糖尿病,减少心脏病的发生。美国运动医学院建议,想知道有氧运动强度是否合适,可在运动后测试心率,以达到最高心率的60%—90%为宜。如果想通过有氧运动来减肥,可以选择低度到中度的运动强度,同时延长运动时间,这种方法消耗的热量更多。运动频率每周3—5次,每次20—60分钟。想要锻炼肌肉,可以练举重、做体操以及其他重复伸、屈肌肉的运动。肌肉锻炼可以燃烧热量、增强骨密度、减少受伤,尤其是关节受伤的几率,还能预防骨质疏松。 在做举重运动前,先测一下,如果连续举8次你最多能举多重的东西,就从这个重量开始练习。当你可以连续12次举起这个重量时,试试增加5%的重量。注意每次练习时,要连续举8—12次,这样可以达到肌肉最大耐力的70%—80%,锻炼效果较好。每周2—3次,但要避免连续两天锻炼同一组肌肉群, 以便让肌肉有充分的恢复时间。"; string shortcontent = "-->健身是一种体育项目,如各种徒手健美操、韵律操、形体操以及各种自抗力动作。"; 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;//最大显示行数 private final int state_unknow = -1;//未知状态 private final int state_not_overflow = 1;//文本行数小于最大可显示行数 private final int state_collapsed = 2;//折叠状态 private final int state_expanded = 3;//展开状态 /** * 注意:保存文本状态集合的key一定要是唯一的,如果用position。 * 如果使用position作为key,则删除、增加条目的时候会出现显示错乱 */ private sparsearray<integer> mtextstatelist;//保存文本状态集合 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); //第一次初始化,未知状态 if (state == state_unknow) { holder.content.getviewtreeobserver().addonpredrawlistener(new viewtreeobserver.onpredrawlistener() { @override public boolean onpredraw() { //这个回掉会调用多次,获取完行数后记得注销监听 holder.content.getviewtreeobserver().removeonpredrawlistener(this); //holder.content.getviewtreeobserver().addonpredrawlistener(null); //如果内容显示的行数大于最大显示行数 if (holder.content.getlinecount() > max_line_count) { holder.content.setmaxlines(max_line_count);//设置最大显示行数 holder.expandorfold.setvisibility(view.visible);//显示“全文” holder.expandorfold.settext("全文"); mtextstatelist.put(mlist.get(position).getid(), state_collapsed);//保存状态 } else { holder.expandorfold.setvisibility(view.gone); mtextstatelist.put(mlist.get(position).getid(), state_not_overflow); } return true; } }); holder.content.setmaxlines(integer.max_value);//设置文本的最大行数,为整数的最大数值 holder.content.settext(mlist.get(position).getcontent()); } else { //如果之前已经初始化过了,则使用保存的状态。 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()); } //全文和收起的点击事件 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); } } }); //删除点击事件 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;//内容 private int id;//该条数据的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="内容" 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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。