Android 朋友圈之评论回复列表

转载请注明出处:http://blog.csdn.net/lv_fq/article/details/77836700 – [发强博客]


系列博客

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 项目仿微信实现的朋友圈

猜你喜欢

转载自blog.csdn.net/lv_fq/article/details/77836700