android开发评论列表,Android类Reddit循环评论列表开发
最近因为项目需求,需要开发类似Reddit里面无限循环的评论列表,于是就开始研究其实现方式和可用性,reddit评论如下:
reddit评论
从最开始的印象看,我们可以看到这是一个树状列表,如果没有限制的话,可以无限循环嵌套,当然我看过的第一实现想法是LinearLayout无限循环的套
树状列表
这种方式最好实现,根据传输的数据结构,View一层层的add,就能实现;但是,由于嵌套过多,性能不行,故抛弃之。
一种方案不行,换一种方案,还是用LinearLayout实现,但是只有一层结构,不嵌套,通过数据结构来告知LinearLayout当前是第几层,根据不同层次来绘制布局,结果如图:
树状列表
大致原理如下:
第一层绘制
1.png
第二层绘制
2.png
第三层绘制
3.png
...
根据层数的不同在最左边添加竖线,以上的实现是行的通的,就是数据结构转换需要花点时间。
按理来说,事情到这已经结束了,但是...但是...通过测试,当加载数据有几百条的时候,会非常非常卡,会卡几秒才加载出来,这非常影响应用体验,抛弃之。
一种方案又不行,继续研究,这次使用RecyclerView形式,至于为什么使用RecyclerView呢,因为它不管你有多少数据,只会加载可见页面的数据,故而对于数据比较多的情况下,效率和体验都能不错(当然ListView应该也行),首先构建数据结构:
public class Comment {
/**
* 孩子数量
*/
private List children;
/**
* 展示内容
*/
private String content;
/**
* 是否可见,父节点收起后,子节点需要隐藏
*/
private boolean isVisible = true;
/**
* 当前节点是否收起状态
*/
private boolean isExpand = true;
/**
* 是否需要还原状态,父节点收起后会影响到子节点的状态
*/
private boolean isNeedReduction = false;
/**
* 当前节点等级,根据等级不同绘制竖线
*/
private int level;
public boolean isNeedReduction() {
return isNeedReduction;
}
public void setNeedReduction(boolean needReduction) {
isNeedReduction = needReduction;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public boolean isExpand() {
return isExpand;
}
public void setExpand(boolean expand) {
isExpand = expand;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public boolean isVisible() {
return isVisible;
}
public void setVisible(boolean visible) {
isVisible = visible;
}
}
伪造数据,此数据是嵌套的树状结构数据,显示时需要转换:
private List initComment() {
List comments1 = new ArrayList<>();
List comments2 = new ArrayList<>();
Comment comment = new Comment();
comment.setChildren(new ArrayList());
comment.setContent("可爱又迷人的反派角色");
comments2.add(comment);
List comments3 = new ArrayList<>();
Comment comment1 = new Comment();
comment1.setChildren(comments2);
comment1.setContent("贯彻爱与真实的邪恶");
comments3.add(comment1);
List comments4 = new ArrayList<>();
Comment comment2 = new Comment();
comment2.setChildren(comments3);
comment2.setContent("为了保护世界的和平");
comments4.add(comment2);
List comments5 = new ArrayList<>();
Comment comment3 = new Comment();
comment3.setChildren(comments4);
comment3.setContent("为了防止世界被破坏");
comments5.add(comment3);
Comment comment4 = new Comment();
comment4.setChildren(new ArrayList());
comment4.setContent("武藏!小次郎!");
comments5.add(comment4);
Comment comment5 = new Comment();
comment5.setChildren(new ArrayList());
comment5.setContent("喵!");
comments5.add(comment5);
Comment comment6 = new Comment();
comment6.setChildren(comments5);
comment6.setContent("我们就大发慈悲的回答你");
comments1.add(comment6);
return comments1;
}
转换数据,最重要的一步:
private void convertComment(List comments, int level) {
for (int i = 0; i < comments.size(); i++) {
Comment comment = comments.get(i);
//数据转换时,层数计算,默认为1
comment.setLevel(level);
comment.setVisible(true);
mComments.add(comment);
if (comment.getChildren() != null && comment.getChildren().size() > 0) {
//当前节点的子节点,比当前节点层数+1
convertComment(comment.getChildren(), level + 1);
}
}
}
构建ViewHolder,这里需要2类ViewHolder,一个是正常显示内容的VH,一类是隐藏内容的VH(当父节点收起时,子节点需要隐藏)
正常显示内容的VH
public class CommentVH extends RecyclerView.ViewHolder {
private ImageView mCommentAnimteIv;
private LinearLayout mCommentLl;
private TextView mCommentDescTv;
public CommentVH(View itemView) {
super(itemView);
mCommentAnimteIv = (ImageView) itemView.findViewById(R.id.comment_animate_iv);
mCommentDescTv = (TextView) itemView.findViewById(R.id.comment_desc_tv);
}
public void update(Comment comment,
Context context) {
mCommentDescTv.setText(comment.getContent());
mCommentLl = (LinearLayout) itemView;
if (mCommentLl.getChildCount() > 2) {
mCommentLl.removeViews(0, mCommentLl.getChildCount() - 2);
}
//根据节点等级增加竖线
if (comment.getLevel() > 1) {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
LayoutInflater inflater = LayoutInflater.from(context);
for (int j = 1; j < comment.getLevel(); j++) {
View lineView = inflater.inflate(R.layout.line_view, null);
mCommentLl.addView(lineView, 0, layoutParams);
}
}
}
//评论缩放处理
public void addZoomListener(final TreeOperationListener treeOperationListener, final int pos) {
if (mCommentAnimteIv != null) {
mCommentAnimteIv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
treeOperationListener.zoom(pos);
}
});
}
}
//增加评论处理
public void addAddListener(final TreeOperationListener treeOperationListener, final int pos) {
if (mCommentLl != null) {
mCommentLl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
treeOperationListener.add(pos);
}
});
}
}
}
基础布局:
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingTop="16dp"
android:orientation="vertical">
android:id="@+id/comment_animate_iv"
android:layout_width="12dp"
android:layout_height="14dp"
android:src="@drawable/comment_direction"/>
android:id="@+id/comment_divider_view"
android:layout_width="1px"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:background="#cccccc"/>
android:id="@+id/comment_desc_rl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:layout_marginLeft="6dp">
android:id="@+id/comment_more_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="#a39b9b"
android:visibility="gone"
android:text="点击加载更多回复"/>
android:id="@+id/comment_desc_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:textSize="14sp"
android:textColor="#272727"
android:text="为了防止世界被破坏"/>
android:id="@+id/comment_info_ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/comment_desc_tv"
android:layout_marginTop="12dp"
android:orientation="horizontal">
android:id="@+id/comment_nickname_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="#a39b9b"
android:text="全麦面包不加糖·"/>
android:id="@+id/comment_like_count_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="#a39b9b"
android:text="100"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:src="@drawable/dislike"/>
竖线布局:
android:layout_width="wrap_content"
android:layout_height="wrap_content">
android:layout_width="1px"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:background="#cccccc"/>
隐藏内容的VH
public class NullVH extends RecyclerView.ViewHolder {
public NullVH(View itemView) {
super(itemView);
}
}
到这里,基本算开发完成了,还要更深入的开发,就是给评论增加收起、放大功能,评论增加、删除了,原理也同样是数据转换。
源码
android开发评论列表,Android类Reddit循环评论列表开发相关推荐
- python 类中定义列表_Python-从类定义中的列表理解访问类变量
小编典典 类范围和列表,集合或字典的理解以及生成器表达式不混合. 为什么:或者,官方用词 在Python 3中,为列表理解赋予了它们自己的适当范围(本地名称空间),以防止其局部变量渗入周围的范围内(即 ...
- Android开发系列(十二) QQ联系人列表升级版——ListView和ScrollView高阶使用方法...
今天继续进行QQ界面的开发工作.前一段时间讲过ExpandableListView的使用并且设置了一个比较简单的具有子菜单效果的联系人列表,本节添加进ScrollView控件,对QQ2013版的联系人 ...
- Android实战开发-Kotlin教程(入门篇-RecyclerView数据列表的实现)
在移动应用开发中,很多时候我们需要去展示数据记录,如电商应用中的商品列表.订单列表等等一系列的数据记录的展示时,我们需要用到Android的列表组件展示这些数据,列表组件应该是我们遇到到比较常见也是必 ...
- Android开发实战---一个汽车销售APP,有汽车列表页、汽车详情页、贷款计算页3个界面。
Android开发实战设计并实现一个汽车销售APP,要求至少有汽车列表页.汽车详情页.贷款计算页3个界面. 已开源:https://github.com/yan123666/wlf 实现结果: 1.计 ...
- 移动开发技术【Android】:【part 2】——RecyclerView实现列表
上一篇请参见:移动开发技术[安卓]--Android_Studio[Part 1] 在上一篇中,我们说到,如何初步的使用Android Studio ,同时完成了基础微信页面的模仿设计.同时我们上一篇 ...
- android开发之网络棋牌类在线游戏开发心得(服务器端、Java) 好文章值得收藏...
标签: android服务器 2013-10-09 17:28 3618人阅读 评论(0) 收藏 举报 分类: android (11) 转自:http://blog.csdn.net/bromon/ ...
- android列表【android开发记录片】android下实现圆角列表布局控件
每日一贴,明天的内容关键字为android列表 引子 明天闲来做了一个类似iphone的圆角列表,先看效果. 图片中绿色线条的是列表头文字,红色的是列表题名文字.此两处都可以显示/隐藏及动态改变值.对 ...
- Android之使用AlertDialog.Builder类创建带列表的对话框和带自己所布局视图的对话框
1.首先,新建一个安卓项目,项目名称为DialogTest1,首先,进行界面布局,打开布局文件res下的layout文件夹下的activity_main.xml文件,附上activity_main的代 ...
- Android多媒体功能开发(11)——使用AudioRecord类录制音频
AudioRecord类优点是能录制到缓冲区,能够实现边录边播(AudioRecord + AudioTrack)以及对音频的实时处理(如QQ电话).缺点是输出是PCM格式的原始采集数据,如果直接保存 ...
最新文章
- activiti集成spring
- python主题壁纸_Python教你如何下载你喜欢的桌面壁纸
- wordpress 新建php文件大小,WordPress最大上传文件大小限制修改
- 单向环形列表及应用场景(约瑟夫环)
- java jar包示例_Java包getImplementationTitle()方法和示例
- 当60亿次攻击来袭,人机联合打了一场漂亮的防御战
- 国资委发文!10本书讲透数字化时代新机遇
- A股开盘:深证区块链50指数涨0.18%,概念股涨多跌少
- 剑指offer之构建乘积数组
- 思必驰AI芯片发布:内置完整语音交互方案,支持离线模式,All in One
- python执行不了elif_浅谈对python中if、elif、else的误解
- 草根力量:同学聚会(嘉定二中校庆60周年)
- matlab——knnsearch用法介绍
- 换信科技B2B供应链平台“换易宝”1.0产品上线发布会盛大召开
- 服务器机柜设备信息卡,信息机房标识标准V.doc
- 缺少tlsys.conf文件
- 必备技能10:管理学类重要期刊名录 -- UTD24 和 FT50
- bilibili弹幕游戏
- 只用html+js+css实现2048小游戏(带源码)
- 听觉外围分析matlab,扫描附近的低功耗 Bluetooth 外围设备 - MATLAB blelist
- MathWorks 中国...
热门文章
- 10种流行的机器学习算法进行泰坦尼克幸存者分析
- 如何利用EXCEL生成任意自由度任意显著因子的F分布表
- emqx使用自制CA证书登录配置(双向认证)
- EXCEL2010数据挖掘插件 下载地址
- mysql时间戳与PHP时间戳,php – 当mysql时间戳gt; 20分钟时删除时间戳比较
- python tell方法_Python File tell() 方法
- 前淘宝技术专家谈12306:这个网站很神奇
- zzulioj:1168: 账单(指针专题)
- 百度离线瓦片地图原理解析(附C#源码,可下载带样式地图)
- java 替换文件中的字符串