Android 自定义评论回复view
先上效果图:
一、创建xml
1.android_ceshi_activity
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rvAndroid"android:layout_width="match_parent"android:layout_height="match_parent"android:overScrollMode="never"android:paddingBottom="12dp"app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"tools:itemCount="4"tools:listitem="@layout/android_ceshi_item" /></LinearLayout>
2.android_ceshi_item
<?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:layout_marginTop="10dp"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:id="@+id/tvName"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:minHeight="46dp"android:padding="10dp"android:text="测试灯虎试试看"android:textColor="@color/black"android:textSize="@dimen/sp_14" /><TextViewandroid:id="@+id/btnPinglun"android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center_vertical"android:minHeight="46dp"android:padding="10dp"android:layout_alignParentEnd="true"android:text="评论"android:textColor="@color/black"android:textSize="@dimen/sp_14" /></RelativeLayout><com.june.wt.commentview.CommentsViewandroid:id="@+id/commentView"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginStart="15dp"android:layout_marginEnd="15dp"/><TextViewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@color/gray" /></LinearLayout>
二、创建评论相关的实体类
1.CeshiBean
package com.june.wt.commentviewclass CeshiBean {var name = ""var commentList: List<CommentsBean>? = null}
2.CommentsBean
package com.june.wt.commentview;import java.io.Serializable;public class CommentsBean implements Serializable {// 评论IDprivate String id;// 园地IDprivate String scopeId;// 发布评论人的IDprivate String userId;// 回复人ID()private String userCodeId;// 评论内容private String commentCount;// 发布评论人的 姓名private String createBy;// 回复人的 姓名private String updateBy;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getScopeId() {return scopeId;}public void setScopeId(String scopeId) {this.scopeId = scopeId;}public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}public String getUserCodeId() {return userCodeId;}public void setUserCodeId(String userCodeId) {this.userCodeId = userCodeId;}public String getCommentCount() {return commentCount;}public void setCommentCount(String commentCount) {this.commentCount = commentCount;}public String getCreateBy() {return createBy;}public void setCreateBy(String createBy) {this.createBy = createBy;}public String getUpdateBy() {return updateBy;}public void setUpdateBy(String updateBy) {this.updateBy = updateBy;}@Overridepublic String toString() {return "CommentsBean{" +"id='" + id + '\'' +", scopeId='" + scopeId + '\'' +", userId='" + userId + '\'' +", userCodeId='" + userCodeId + '\'' +", commentCount='" + commentCount + '\'' +", createBy='" + createBy + '\'' +", updateBy='" + updateBy + '\'' +'}';} }
三、自定义View
1.CommentsView
package com.june.wt.commentview;import android.content.Context; import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.TextPaint; import android.text.TextUtils; import android.text.style.ClickableSpan; import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView;import androidx.annotation.Nullable;import java.util.List;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) {CommentsBean item = mDatas.get(position);String replyId = item.getUserCodeId();boolean hasReply = false; // 是否有回复if (!TextUtils.isEmpty(replyId)) {hasReply = true;}TextView textView = new TextView(mContext);textView.setTextSize(15);textView.setTextColor(0xff686868); //回复与冒号 字体颜色SpannableStringBuilder builder = new SpannableStringBuilder();String name = item.getCreateBy();if (hasReply) {builder.append(setClickableSpan(item.getUpdateBy()));builder.append(" 回复 ");builder.append(setClickableSpan(name));} else {builder.append(setClickableSpan(name));}builder.append(" : ");builder.append(setClickableSpanContent(position, item));builder.append(" ");textView.setText(builder);// 设置点击背景色textView.setHighlightColor(getResources().getColor(android.R.color.transparent)); // textView.setHighlightColor(0xff000000);final CircleMovementMethod method = new CircleMovementMethod(0xffcccccc, 0xffcccccc);textView.setMovementMethod(method);// textView.setOnClickListener(new OnClickListener() { // @Override // public void onClick(View v) { // if (method.isParseTv()) {if (listener != null) {listener.onItemClick(position, item);} // } // } // });return textView;}/*** 设置评论内容点击事件** @param item* @param position* @return*/public SpannableString setClickableSpanContent(final int position, final CommentsBean commentBean) {final SpannableString string = new SpannableString(commentBean.getCommentCount());ClickableSpan span = new ClickableSpan() {@Overridepublic void onClick(View widget) {if (listener != null) {listener.onItemClick(position, commentBean);}}@Overridepublic 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 SpannableString string = new SpannableString(item);ClickableSpan span = new ClickableSpan() {@Overridepublic void onClick(View widget) {// TODO: 2017/9/3 评论用户名字点击事件 // Toast.makeText(mContext, "评论用户名字点击事件", Toast.LENGTH_SHORT).show();}@Overridepublic 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);} }
2.背景色类 CircleMovementMethod
package com.june.wt.commentview;import android.text.Layout; import android.text.Selection; import android.text.Spannable; import android.text.method.BaseMovementMethod; import android.text.method.Touch; import android.text.style.BackgroundColorSpan; import android.text.style.ClickableSpan; import android.view.MotionEvent; import android.widget.TextView;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;private boolean isParseTv = false;public boolean isParseTv() {return isParseTv;}public void setParseTv(boolean parseTv) {isParseTv = parseTv;}/*** @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) {setParseTv(false);// 点击的是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 {setParseTv(true);// 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) {//移除点击时设置的背景spanbuffer.removeSpan(mBgSpan);}} else {}Selection.removeSelection(buffer);widget.setBackgroundResource(DEFAULT_COLOR_ID);} else if (action == MotionEvent.ACTION_MOVE) {//这种情况不用做处理} else {if (mBgSpan != null) {//移除点击时设置的背景spanbuffer.removeSpan(mBgSpan);}widget.setBackgroundResource(DEFAULT_COLOR_ID);}return Touch.onTouchEvent(widget, buffer, event);}}
四、使用
1.CeshiAdapter
package com.june.wt.commentviewimport android.content.Context import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.june.wt.Rclass CeshiAdapter(val context: Context) : RecyclerView.Adapter<CeshiAdapter.YuanDiHolder>() {var mDatas: List<CeshiBean>? = nullset(value) {field = valueif (value != null) {notifyDataSetChanged()}}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CeshiAdapter.YuanDiHolder {//LayoutInflater.from指定写法val view =LayoutInflater.from(parent.context).inflate(R.layout.android_ceshi_item, parent, false)return CeshiAdapter.YuanDiHolder(view)}override fun onBindViewHolder(holder: CeshiAdapter.YuanDiHolder, position: Int) {/*** 数据操作*/val ceshiBean = mDatas!![position]val comList = ceshiBean.commentListholder.tvName.text = ceshiBean.nameholder.commentView.setList(comList)holder.commentView.setOnItemClickListener { _, bean ->Log.e("++++++", "content = " + bean.commentCount)refushCommentLisitenner.setItemRefushComment(position, holder.commentView)}holder.commentView.notifyDataSetChanged()holder.btnPinglun.setOnClickListener {refushCommentLisitenner.setItemRefushComment(position, holder.commentView)}}override fun getItemCount(): Int {return if (mDatas != null) mDatas!!.size else 0}/*** 创建ViewHolder* 元素声明*/class YuanDiHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {var tvName: TextView = itemView.findViewById(R.id.tvName)var btnPinglun: TextView = itemView.findViewById(R.id.btnPinglun)var commentView: CommentsView = itemView.findViewById(R.id.commentView)}/*** 刷新新的评论页面* */lateinit var refushCommentLisitenner: RefushCommentLisitennerinterface RefushCommentLisitenner {fun setItemRefushComment(position: Int, commentView: CommentsView)}fun setRefushCommentClick(refushClick: RefushCommentLisitenner) {refushCommentLisitenner = refushClick} }
2.CommentViewActivity
package com.june.wt.commentviewimport com.june.wt.R import com.june.wt.base.BaseUnNeedVPActivity import kotlinx.android.synthetic.main.android_ceshi_activity.*class CommentViewActivity : BaseUnNeedVPActivity() {lateinit var ceshiAdapter: CeshiAdapteroverride fun getLayout(): Int {return R.layout.android_ceshi_activity}override fun initView() {ceshiAdapter = CeshiAdapter(mContext)rvAndroid.adapter = ceshiAdapterceshiAdapter.setRefushCommentClick(object : CeshiAdapter.RefushCommentLisitenner {override fun setItemRefushComment(position: Int, commentView: CommentsView) {var newCommentList = ceshiList[position].commentList as MutableList<CommentsBean>var commBean = CommentsBean()commBean.id = "1"commBean.scopeId = "17"commBean.commentCount = "的点点滴滴多多多多多"commBean.userId = "208"commBean.createBy = "贾宝玉"commBean.userCodeId = "108"commBean.updateBy = "玉帝"newCommentList.add(commBean)commentView.setList(newCommentList)commentView.notifyDataSetChanged()}})}override fun initData() {getCeshiDatas()ceshiAdapter.mDatas = ceshiList}/*** 添加测试数据* */lateinit var ceshiList: MutableList<CeshiBean>fun getCeshiDatas() {ceshiList = mutableListOf()var ceshiBean = CeshiBean()ceshiBean.name = "账单上符合"var commentList = mutableListOf<CommentsBean>()var commBean = CommentsBean()commBean.id = "1"commBean.scopeId = "17"commBean.commentCount = "剑少的花费时间客户反馈司机电话副书记等回复"commBean.userId = "205"commBean.createBy = "张琪"commBean.userCodeId = "105"commBean.updateBy = "名企"commentList.add(commBean)ceshiBean.commentList = commentListceshiList.add(ceshiBean)ceshiBean = CeshiBean()ceshiBean.name = "就分号结束分角色"commentList = mutableListOf<CommentsBean>()commBean = CommentsBean()commBean.id = "2"commBean.scopeId = "18"commBean.commentCount = "噢噢噢噢偶偶偶偶偶偶偶偶多扩付所扩付或说所扩"commBean.userId = "206"commBean.createBy = "柯南"commBean.userCodeId = "106"commBean.updateBy = "鸣人"commentList.add(commBean)ceshiBean.commentList = commentListceshiList.add(ceshiBean)} }
最后是交流公众号,大家可以关注一下
Android 自定义评论回复view相关推荐
- android自定义LinearLayout和View
自定义线性布局经常用到: 第一种是在扩展的LinearLayout构造函数中使用Inflater加载一个布局,并从中提取出相关的UI组件进行封装,形成一个独立的控件.在使用该控件时,由于它所有的子元素 ...
- android自定义验证码倒计时View
关于自定义View的构造方法里面的参数的含义可以参考: http://www.cnblogs.com/angeldevil/p/3479431.html 代码: 倒计时类: public class ...
- android自定义空的view,ListView android中的自定义空视图
如果ListView适配器中没有数据,我想显示刷新Button和TextView.我还希望能够向将重新加载列表的按钮添加单击侦听器.以下是我定义当前活动的方式: protected void onCr ...
- Android 自定义手势解锁View
直接上代码了: /****@ClassName:GraphicsView*@author:WYL*@Date:2022/9/29*/ class GraphicsView : View {privat ...
- Android 自定义数字角标
需要显示购物车数量,网上看了一些实现方式,有的是通过把页面view控件作为子view添加的,但是会改变我已有的样式和操作,因此决定自己编写 实现显示角标的功能. 我这里的需求是使用FloatingAc ...
- Android 自定义 圆环,Android自定义view实现圆环效果实例代码
先上效果图,如果大家感觉不错,请参考实现代码. 重要的是如何实现自定义的view效果 (1)创建类,继承view,重写onDraw和onMesure方法 public class CirclePerc ...
- Android仿支付宝UI功能开发,Android 自定义view仿支付宝咻一咻功能
支付宝上有一个咻一咻的功能,就是点击图片后四周有水波纹的这种效果,今天也写一个类似的功能. 效果如下所示: 思路: 就是几个圆的半径不断在变大,这个可以使用动画缩放实现,还有透明动画 还有就是这是好几 ...
- android可以定义函数吗,Android自定义view 你所需要知道的基本函数总结
Android自定义view 你所需要知道的基本函数 首先 往Canvas上面draw需要一个Paint. 画笔常用的函数有哪些呢.由于木有调试环境,函数基本上默写,有错请评论提出,蟹蟹! Paint ...
- android自定义view案例,Android自定义View的实现方法实例详解
一.自绘控件 下面我们准备来自定义一个计数器View,这个View可以响应用户的点击事件,并自动记录一共点击了多少次.新建一个CounterView继承自View,代码如下所示: 可以看到,首先我们在 ...
最新文章
- python的工资为什么这么低-你拿着3k的工资,不明白为什么别人年薪 200万
- fs_struct和file_struct关系
- 模电这么学,谁还会说不懂晶体管?
- caffe 框架梳理(待续)
- AtCoder Beginner Contest 084(AB)
- socket编程初级
- 2016年的云计算安全趋势
- 《电脑报》:中国“人肉搜索第一案”幕后之谜
- [芯片] 2、接口技术·实验二·定时/计数器8253
- CCF NOI1031 等腰三角形
- 语音识别技术发展史与行业最佳实践全解析
- springmvc中校验框架(hibernate)
- MyBatis官方文档-简介
- 数字证书及 CA 的扫盲介绍
- android 语音播报,android实现语音播报textToSpeech
- 机器学习-分类Classification
- 中外合作办学硕士—社科院杜兰金融管理硕士,给23考研加一重保险
- 软件工程毕业设计课题(34)基于JAVA毕业设计JAVA医院预约挂号系统毕设作品项目
- C51 - DS18B20
- flutterdio_强大的Flutter http请求库dio