Android實(shí)現(xiàn)朋友圈評(píng)論回復(fù)列表
本文實(shí)例為大家分享了Android實(shí)現(xiàn)朋友圈評(píng)論回復(fù)列表的具體代碼,供大家參考,具體內(nèi)容如下
Android實(shí)現(xiàn)朋友圈評(píng)論回復(fù)列表
Android實(shí)現(xiàn)朋友圈點(diǎn)贊列表
正文
還是老流程,先來(lái)看一下效果圖:
然后是主要實(shí)現(xiàn)代碼:
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; } /** * 設(shè)置評(píng)論列表信息 * * @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; // 是否有回復(fù) 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(" 回復(fù) "); 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); // 設(shè)置點(diǎn)擊背景色 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; } /** * 設(shè)置評(píng)論內(nèi)容點(diǎn)擊事件 * * @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 評(píng)論內(nèi)容點(diǎn)擊事件 Toast.makeText(mContext, "position: " + position + " , content: " + item, Toast.LENGTH_SHORT).show(); } @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); // 設(shè)置顯示的內(nèi)容文本顏色 ds.setColor(0xff686868); ds.setUnderlineText(false); } }; string.setSpan(span, 0, string.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return string; } /** * 設(shè)置評(píng)論用戶名字點(diǎn)擊事件 * * @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 評(píng)論用戶名字點(diǎn)擊事件 Toast.makeText(mContext, bean.getUserName(), Toast.LENGTH_SHORT).show(); } @Override public void updateDrawState(TextPaint ds) { super.updateDrawState(ds); // 設(shè)置顯示的用戶名文本顏色 ds.setColor(0xff387dcc); ds.setUnderlineText(false); } }; string.setSpan(span, 0, string.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return string; } /** * 定義一個(gè)用于回調(diào)的接口 */ 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; /** * 整個(gè)textView的背景色 */ private int textViewBgColor; /** * 點(diǎn)擊部分文字時(shí)部分文字的背景色 */ private int clickableSpanBgClor; private BackgroundColorSpan mBgSpan; private ClickableSpan[] mClickLinks; /** * @param clickableSpanBgClor 點(diǎn)擊選中部分時(shí)的背景色 */ public CircleMovementMethod(int clickableSpanBgClor) { this.clickableSpanBgClor = clickableSpanBgClor; } /** * @param clickableSpanBgClor 點(diǎn)擊選中部分時(shí)的背景色 * @param textViewBgColor 整個(gè)textView點(diǎn)擊時(shí)的背景色 */ 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) { // 點(diǎn)擊的是Span區(qū)域,不要把點(diǎn)擊事件傳遞 Selection.setSelection(buffer, buffer.getSpanStart(mClickLinks[0]), buffer.getSpanEnd(mClickLinks[0])); //設(shè)置點(diǎn)擊區(qū)域的背景色 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) {//移除點(diǎn)擊時(shí)設(shè)置的背景span buffer.removeSpan(mBgSpan); } } else { } Selection.removeSelection(buffer); widget.setBackgroundResource(DEFAULT_COLOR_ID); } else if (action == MotionEvent.ACTION_MOVE) { //這種情況不用做處理 } else { if (mBgSpan != null) {//移除點(diǎn)擊時(shí)設(shè)置的背景span buffer.removeSpan(mBgSpan); } widget.setBackgroundResource(DEFAULT_COLOR_ID); } return Touch.onTouchEvent(widget, buffer, event); } }
相關(guān)數(shù)據(jù)結(jié)構(gòu)(模擬)
CommentsBean
public class CommentsBean implements Serializable { private int commentsId; private String content; private UserBean replyUser; // 回復(fù)人信息 private UserBean commentsUser; // 評(píng)論人信息 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
附:如果需要完整朋友圈項(xiàng)目的話,這里推薦一個(gè) Github 項(xiàng)目仿微信實(shí)現(xiàn)的朋友圈
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Android6.0運(yùn)行時(shí)權(quán)限管理
自從Android6.0發(fā)布以來(lái),在權(quán)限上做出了很大的變動(dòng),不再是之前的只要在manifest設(shè)置就可以任意獲取權(quán)限,而是更加的注重用戶的隱私和體驗(yàn)。本文詳細(xì)介紹了Android6.0運(yùn)行時(shí)權(quán)限管理。需要的朋友一起來(lái)看下吧2016-12-12Android高級(jí)組件Gallery畫廊視圖使用方法詳解
這篇文章主要為大家詳細(xì)介紹了Android高級(jí)組件Gallery畫廊視圖的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android Studio3.6新特性之視圖綁定ViewBinding使用指南
這篇文章主要介紹了Android Studio3.6新特性之視圖綁定ViewBinding使用指南,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03android 引導(dǎo)界面的實(shí)現(xiàn)方法
現(xiàn)在越來(lái)越多程序都有引導(dǎo)頁(yè)面了。網(wǎng)上資料不全。現(xiàn)在自己實(shí)現(xiàn)下。2013-06-06Android彈出DatePickerDialog并獲取值的方法
這篇文章主要為大家詳細(xì)介紹了Android彈出DatePickerDialog并獲取值的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05Android混合開發(fā)教程之WebView的使用方法總結(jié)
WebView是一個(gè)基于webkit引擎、展現(xiàn)web頁(yè)面的控件,下面這篇文章主要給大家介紹了關(guān)于Android混合開發(fā)教程之WebView的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧2018-05-05Android動(dòng)態(tài)添加碎片代碼實(shí)例
這篇文章主要介紹了Android動(dòng)態(tài)添加碎片代碼實(shí)例,2019-06-06Android從系統(tǒng)Gallery獲取圖片具體實(shí)現(xiàn)
這篇文章主要介紹了Android從系統(tǒng)Gallery獲取圖片具體實(shí)現(xiàn),有需要的朋友可以參考一下2013-12-12