Android实现朋友圈评论回复列表
作者:发强 发布时间:2022-12-16 03:40:36
标签:Android,朋友圈,评论
本文实例为大家分享了Android实现朋友圈评论回复列表的具体代码,供大家参考,具体内容如下
Android实现朋友圈评论回复列表
Android实现朋友圈点赞列表
Android实现朋友圈多图显示功能
正文
还是老流程,先来看一下效果图:
然后是主要实现代码:
CommentsView
public class CommentsView extends LinearLayout {
private Context mContext;
private List<CommentsBean> mDatas;
private onItemClickListener listener;
public CommentsView(Context context) {
this(context, null);
}
public CommentsView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CommentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOrientation(VERTICAL);
this.mContext = context;
}
/**
* 设置评论列表信息
*
* @param list
*/
public void setList(List<CommentsBean> list) {
mDatas = list;
}
public void setOnItemClickListener(onItemClickListener listener) {
this.listener = listener;
}
public void notifyDataSetChanged() {
removeAllViews();
if (mDatas == null || mDatas.size() <= 0) {
return;
}
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 10, 0, 10);
for (int i = 0; i < mDatas.size(); i++) {
View view = getView(i);
if (view == null) {
throw new NullPointerException("listview item layout is null, please check getView()...");
}
addView(view, i, layoutParams);
}
}
private View getView(final int position) {
final CommentsBean item = mDatas.get(position);
UserBean replyUser = item.getReplyUser();
boolean hasReply = false; // 是否有回复
if (replyUser != null) {
hasReply = true;
}
TextView textView = new TextView(mContext);
textView.setTextSize(15);
textView.setTextColor(0xff686868);
SpannableStringBuilder builder = new SpannableStringBuilder();
UserBean comUser = item.getCommentsUser();
String name = comUser.getUserName();
if (hasReply) {
builder.append(setClickableSpan(name, item.getCommentsUser()));
builder.append(" 回复 ");
builder.append(setClickableSpan(replyUser.getUserName(), item.getReplyUser()));
} else {
builder.append(setClickableSpan(name, item.getCommentsUser()));
}
builder.append(" : ");
builder.append(setClickableSpanContent(item.getContent(), position));
textView.setText(builder);
// 设置点击背景色
textView.setHighlightColor(getResources().getColor(android.R.color.transparent));
// textView.setHighlightColor(0xff000000);
textView.setMovementMethod(new CircleMovementMethod(0xffcccccc, 0xffcccccc));
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onItemClick(position, item);
}
}
});
return textView;
}
/**
* 设置评论内容点击事件
*
* @param item
* @param position
* @return
*/
public SpannableString setClickableSpanContent(final String item, final int position) {
final SpannableString string = new SpannableString(item);
ClickableSpan span = new ClickableSpan() {
@Override
public void onClick(View widget) {
// TODO: 2017/9/3 评论内容点击事件
Toast.makeText(mContext, "position: " + position + " , content: " + item, Toast.LENGTH_SHORT).show();
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
// 设置显示的内容文本颜色
ds.setColor(0xff686868);
ds.setUnderlineText(false);
}
};
string.setSpan(span, 0, string.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return string;
}
/**
* 设置评论用户名字点击事件
*
* @param item
* @param bean
* @return
*/
public SpannableString setClickableSpan(final String item, final UserBean bean) {
final SpannableString string = new SpannableString(item);
ClickableSpan span = new ClickableSpan() {
@Override
public void onClick(View widget) {
// TODO: 2017/9/3 评论用户名字点击事件
Toast.makeText(mContext, bean.getUserName(), Toast.LENGTH_SHORT).show();
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
// 设置显示的用户名文本颜色
ds.setColor(0xff387dcc);
ds.setUnderlineText(false);
}
};
string.setSpan(span, 0, string.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return string;
}
/**
* 定义一个用于回调的接口
*/
public interface onItemClickListener {
void onItemClick(int position, CommentsBean bean);
}
}
CircleMovementMethod
public class CircleMovementMethod extends BaseMovementMethod {
private final static int DEFAULT_COLOR_ID = android.R.color.transparent;
/**
* 整个textView的背景色
*/
private int textViewBgColor;
/**
* 点击部分文字时部分文字的背景色
*/
private int clickableSpanBgClor;
private BackgroundColorSpan mBgSpan;
private ClickableSpan[] mClickLinks;
/**
* @param clickableSpanBgClor 点击选中部分时的背景色
*/
public CircleMovementMethod(int clickableSpanBgClor) {
this.clickableSpanBgClor = clickableSpanBgClor;
}
/**
* @param clickableSpanBgClor 点击选中部分时的背景色
* @param textViewBgColor 整个textView点击时的背景色
*/
public CircleMovementMethod(int clickableSpanBgClor, int textViewBgColor) {
this.textViewBgColor = textViewBgColor;
this.clickableSpanBgClor = clickableSpanBgClor;
}
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
mClickLinks = buffer.getSpans(off, off, ClickableSpan.class);
if (mClickLinks.length > 0) {
// 点击的是Span区域,不要把点击事件传递
Selection.setSelection(buffer,
buffer.getSpanStart(mClickLinks[0]),
buffer.getSpanEnd(mClickLinks[0]));
//设置点击区域的背景色
mBgSpan = new BackgroundColorSpan(clickableSpanBgClor);
buffer.setSpan(mBgSpan,
buffer.getSpanStart(mClickLinks[0]),
buffer.getSpanEnd(mClickLinks[0]),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
// textview选中效果
// widget.setBackgroundColor(textViewBgColor);
widget.setBackgroundResource(DEFAULT_COLOR_ID);
}
} else if (action == MotionEvent.ACTION_UP) {
if (mClickLinks.length > 0) {
mClickLinks[0].onClick(widget);
if (mBgSpan != null) {//移除点击时设置的背景span
buffer.removeSpan(mBgSpan);
}
} else {
}
Selection.removeSelection(buffer);
widget.setBackgroundResource(DEFAULT_COLOR_ID);
} else if (action == MotionEvent.ACTION_MOVE) {
//这种情况不用做处理
} else {
if (mBgSpan != null) {//移除点击时设置的背景span
buffer.removeSpan(mBgSpan);
}
widget.setBackgroundResource(DEFAULT_COLOR_ID);
}
return Touch.onTouchEvent(widget, buffer, event);
}
}
相关数据结构(模拟)
CommentsBean
public class CommentsBean implements Serializable {
private int commentsId;
private String content;
private UserBean replyUser; // 回复人信息
private UserBean commentsUser; // 评论人信息
public int getCommentsId() {
return commentsId;
}
public void setCommentsId(int commentsId) {
this.commentsId = commentsId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public UserBean getReplyUser() {
return replyUser;
}
public void setReplyUser(UserBean replyUser) {
this.replyUser = replyUser;
}
public UserBean getCommentsUser() {
return commentsUser;
}
public void setCommentsUser(UserBean commentsUser) {
this.commentsUser = commentsUser;
}
}
UserBean
public class UserBean implements Serializable {
private int userId;
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
用法
<com.lvfq.myworkingtest.dynamic.view.CommentsView
android:id="@+id/commentView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_20" />
commentView = LvV.find(this, R.id.commentView);
commentView.setList(Data.getComments());
commentView.setOnItemClickListener(new CommentsView.onItemClickListener() {
@Override
public void onItemClick(int position, CommentsBean bean) {
}
});
commentView.notifyDataSetChanged();
代码已整理到Github
附:如果需要完整朋友圈项目的话,这里推荐一个 Github 项目仿微信实现的朋友圈
来源:http://blog.csdn.net/lv_fq/article/details/77836700


猜你喜欢
- 反编译jar包并修改class文件重新打包这两天碰到一个需求:需要修改一个jar包中的逻辑代码,并且重新打包本来是很简单的问题,但是因为这个
- 本文实例为大家分享了在Android中如何实现下拉导航选择菜单效果的全过程,供大家参考,具体内容如下关于下拉导航选择菜单效果在新闻客户端中用
- 本文实例总结了Android TextView字体颜色设置方法。分享给大家供大家参考,具体如下:对于setTextView(int a)这里
- 这里我们以拨打电话申请权限来写个小例子,也就是CALL_PHONE,因为拨打电话会涉及用户手机的资费问题,因而被列为了危险权限,在Andro
- 背景笔者所在项目组在搭建一个全新项目的时候选用了SpringBoot3.x,项目中应用了很多SpringBoot2.x时代相关的第三方组件例
- 每次新项目的时候,都要从头去找一遍数据库工具类。这里分享一个简单实用的C#的通用DbHelper工具类,支持数据连接池。连接池配置<c
- 本文实例讲述了Android编程自定义AlertDialog样式的方法。分享给大家供大家参考,具体如下:开发的时候,通常我们要自定义Aler
- 一、介绍以及编解码流程MediaCodec 类可用于访问低级媒体编解码器,即编码器/解码器组件。它是 Android 低级多媒体支持基础结构
- MVC三层架构我们在刚刚成为程序员的时候,就会被前辈们 “教育” 说系统的设计要遵循 MVC(Model-View-Controller)架
- 本文实例讲述了winform中的ListBox和ComboBox绑定数据用法。分享给大家供大家参考。具体实现方法如下:本例实现将集合数据绑定
- Unity IPostprocessBuildWithReportUnity IPostprocessBuildWithReport是Uni
- 在利用C#开发Winform应用程序的时候,我们有可能使用RichTextBox来实现实时显示应用程序日志的功能,日志又分为:一般消息,警告
- 1. 引入当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象, 只有通过new关键字才会产生出对象,这时系统才会
- 介绍今天上班的时候有个哥们问我怎么去实现一个按钮式的进度条,先来看看他需要实现的效果图。和普通的圆形进度条类似,只是中间的地方有两个状态表示
- Java持久化框架:Hibernate与MybatisHibernate和Mybatis是两个Java持久化框架,用于将Java对象映射到关
- 前言:自定义View可以分为两种方式:第一种通过继承ViewGroup,内部通过addView的方式将其他的View组合到一起。第二种则是通
- 这篇文章主要介绍了spring web.xml指定配置文件过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价
- 本文实例讲述了Java基本数据类型与类型转换。分享给大家供大家参考,具体如下:相关内容:基本数据类型整型浮点型字符型布尔型数据类型转换数组首
- this总要有个事物来代表类的当前对象,就像C++中的this指针一样,Java中的this关键字就是代表当前对象的引用。它有三个主要的作用
- 目录定义数据库表访问表中的数据插入数据查询数据创建数据库测试 DaoRoom 是 SQLite 的封装,它使 Android 对数据库的操作