Giter Club home page Giter Club logo

commentlisttextview's Introduction

CommentListTextView#

说明

我是将朋友圈分成了几个独立模块单独自定义的View,通过回调完成交互,耦合性算是非常低了,主要有以下及部分:

1.评论布局(自定义TextView)

CommentListTextView

Lu_PingLunLayout

2.点赞布局(原理和评论的自定义TextView一样,都是用的SpannableString)

PraiseTextView

3.图片列表(出门右转,理论上没有数量限制,和listView配合使用也很好,缓存也自己处理了)

MultiImageViewLayout

我也是找第三方例子不好找,于是自己写了一个,我和同事还打算做一套IM系统,app和后台都要做,我们自己定义sdk,我们还要封装H5,类似hbuilder如果有什么问题,可以联系我,

QQ:1264957104

CSDN:http://blog.csdn.net/hnsugar

GitHub:https://github.com/hnsugar

个人做测试项目的服务器:http://lujianchao.com http://itgowo.com

链接是跳转到GitHub的,部分文章我会直接贴出关键View的代码。

示例

##主要方法##

####设置评论最大显示行数####

mCommentListTextView.setMaxlines (6);

####设置超过最大行数下面显示的提示文本####

mCommentListTextView.setMoreStr ("查看更多");

####设置名字文本显示颜色####

mCommentListTextView.setNameColor (Color.parseColor ("#fe671e"));

####设置评论内容文本颜色####

mCommentListTextView.setCommentColor (Color.parseColor ("#242424"));

####设置名字之间的文本####

mCommentListTextView.setTalkStr ("回复");

####设置名字之间的文本颜色####

mCommentListTextView.setTalkColor (Color.parseColor ("#242424"));

####设置显示数据####

mCommentListTextView.setData (mCommentInfos);

####设置监听

mCommentListTextView.setonCommentListener (new CommentListTextView.onCommentListener ())

onNickNameClick (int position, CommentListTextView.CommentInfo mInfo)

“A回复B”中A名称被点击 position是第几条评论,mInfo是这条评论的信息

onToNickNameClick (int position, CommentListTextView.CommentInfo mInfo)

“A回复B”中B名称被点击 position是第几条评论,mInfo是这条评论的信息

onCommentItemClick (int position, CommentListTextView.CommentInfo mInfo)

position是第几条评论,mInfo是这条评论的信息

onOtherClick

内部处理了点击文字会触发两个回调的问题,这个是点击非文字或者没有单独定义点击事件的回调

布局

<?xml version="1.0" encoding="utf-8"?>
	<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:tools="http://schemas.android.com/tools"
	android:id="@+id/activity_main"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:orientation="vertical"
	android:paddingBottom="@dimen/activity_vertical_margin"
	android:paddingLeft="@dimen/activity_horizontal_margin"
	android:paddingRight="@dimen/activity_horizontal_margin"
	android:paddingTop="@dimen/activity_vertical_margin"
	tools:context="com.lujianchao.commentlisttextview.commentlisttextview.MainActivity">

	<com.lujianchao.commentlisttextview.commentlisttextview.CommentListTextView
		android:id="@+id/commentlist"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:textSize="15sp"/>

	<TextView
		android:id="@+id/log"
		android:layout_width="match_parent"
		android:scrollbars="vertical"
		android:layout_height="match_parent"/>
</LinearLayout>

代码

public class MainActivity extends AppCompatActivity {
	private CommentListTextView mCommentListTextView;
	private TextView mTextView;

	@Override
	protected void onCreate (Bundle savedInstanceState) {
		super.onCreate (savedInstanceState);
		setContentView (R.layout.activity_main);
		mCommentListTextView = (CommentListTextView) findViewById (R.id.commentlist);
		mTextView = (TextView) findViewById (R.id.log);
		test ();
	}

	private void test () {
		mTextView.setMovementMethod (ScrollingMovementMethod.getInstance ());


		mCommentListTextView.setMaxlines (6);
		mCommentListTextView.setMoreStr ("查看更多");
		mCommentListTextView.setNameColor (Color.parseColor ("#fe671e"));
		mCommentListTextView.setCommentColor (Color.parseColor ("#242424"));
		mCommentListTextView.setTalkStr ("回复");
		mCommentListTextView.setTalkColor (Color.parseColor ("#242424"));


		List<CommentListTextView.CommentInfo> mCommentInfos = new ArrayList<> ();
		mCommentInfos.add (new CommentListTextView.CommentInfo ().setID (1111).setComment ("今天天气真好啊!11").setNickname ("张三").setTonickname ("赵四"));
		mCommentInfos.add (new CommentListTextView.CommentInfo ().setID (2222).setComment ("今天天气真好啊!22").setNickname ("赵四"));
		mCommentInfos.add (new CommentListTextView.CommentInfo ().setID (3333).setComment ("今天天气真好啊!33").setNickname ("王五").setTonickname ("小三"));
		mCommentInfos.add (new CommentListTextView.CommentInfo ().setID (4444).setComment ("今天天气真好啊!44").setNickname ("小三").setTonickname ("王五"));
		mCommentInfos.add (new CommentListTextView.CommentInfo ().setID (5555).setComment ("今天天气真好啊!55").setNickname ("李大"));
		mCommentInfos.add (new CommentListTextView.CommentInfo ().setID (6666).setComment ("今天天气真好啊!66").setNickname ("小三").setTonickname ("王五"));
		mCommentInfos.add (new CommentListTextView.CommentInfo ().setID (7777).setComment ("今天天气真好啊!77").setNickname ("李大").setTonickname ("张三"));
		mCommentInfos.add (new CommentListTextView.CommentInfo ().setID (8888).setComment ("今天天气真好啊!88").setNickname ("小三").setTonickname ("王五"));
		mCommentInfos.add (new CommentListTextView.CommentInfo ().setID (9999).setComment ("今天天气真好啊!99").setNickname ("李大").setTonickname ("张三"));
		mCommentListTextView.setData (mCommentInfos);
		mCommentListTextView.setonCommentListener (new CommentListTextView.onCommentListener () {


			@Override
			public void onNickNameClick (final int position, final CommentListTextView.CommentInfo mInfo) {
				mTextView.append ("onNickNameClick  position = [" + position + "], mInfo = [" + mInfo + "]" + "\r\n");
			}

			@Override
			public void onToNickNameClick (final int position, final CommentListTextView.CommentInfo mInfo) {
				mTextView.append ("onToNickNameClick  position = [" + position + "], mInfo = [" + mInfo + "]" + "\r\n");
			}

			@Override
			public void onCommentItemClick (final int position, final CommentListTextView.CommentInfo mInfo) {
				mTextView.append ("onCommentItemClick  position = [" + position + "], mInfo = [" + mInfo + "]" + "\r\n");
			}

			@Override
			public void onOtherClick () {
				mTextView.append ("onOtherClick" + "\r\n");
			}
		});
	}
}

##源码##

package com.lujianchao.commentlisttextview.commentlisttextview;

import android.content.Context;
import android.graphics.Color;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

import java.util.List;

/**
 * Created by lujianchao on 2017/1/19.
 *
 * @author lujianchao
 */

public class CommentListTextView extends TextView {
    /**
     * 所有评论数据
     */
    private List<CommentInfo> mInfos;
    private onCommentListener mListener;

    /**
     * 点击文字会触发两个回调,用这个变量控制屏蔽掉一个
     */
    private boolean isNickNameClick = false;


    /**
     * 最大显示行数,超过指定行数多一行显示为查看更多文本,可设置文本
     */
    private int mMaxlines = 6;
    /**
     * 当超过n行后,n+1行显示为这个文本;
     */
    private String mMoreStr = "查看全部评论";
    /**
     * 谁回复谁中回复字符串,可以变成别的
     */
    private String mTalkStr = "回复";
    /**
     * 人名称颜色
     */
    private int mNameColor = Color.parseColor ("#fe671e");
    private int mCommentColor = Color.parseColor ("#242424");
    private int mTalkColor = Color.parseColor ("#242424");

    public int getTalkColor () {
        return mTalkColor;
    }

    public CommentListTextView setTalkColor (final int mTalkColor) {
        this.mTalkColor = mTalkColor;
        return this;
    }

    public int getMaxlines () {
        return mMaxlines;
    }

    public CommentListTextView setMaxlines (final int mMaxlines) {
        this.mMaxlines = mMaxlines;
        return this;
    }

    public String getMoreStr () {
        return mMoreStr;
    }

    public CommentListTextView setMoreStr (final String mMoreStr) {
        this.mMoreStr = mMoreStr;
        return this;
    }

    public String getTalkStr () {
        return mTalkStr;
    }

    public CommentListTextView setTalkStr (final String mTalkStr) {
        this.mTalkStr = mTalkStr;
        return this;
    }

    public int getNameColor () {
        return mNameColor;
    }

    public CommentListTextView setNameColor (final int mNameColor) {
        this.mNameColor = mNameColor;
        return this;
    }

    public int getCommentColor () {
        return mCommentColor;
    }

    public CommentListTextView setCommentColor (final int mCommentColor) {
        this.mCommentColor = mCommentColor;
        return this;
    }

    public CommentListTextView (final Context context) {
        super (context);
    }



    public CommentListTextView (final Context context, final AttributeSet attrs) {
        super (context, attrs);
    }

    public CommentListTextView setonCommentListener (final onCommentListener mListener) {
        this.mListener = mListener;
        return this;
    }

    public void setData (List<CommentInfo> mInfos) {
        this.mInfos = mInfos;
        /**
         * textview必须设置,否则自定义点击事件没响应
         */
        setMovementMethod (LinkMovementMethod.getInstance ());
        setHighlightColor (Color.TRANSPARENT);
        setText (getCommentString ());
        setOnClickListener (new OnClickListener () {
            @Override
            public void onClick (final View v) {
                if (isNickNameClick) {
                    isNickNameClick = false;
                    return;
                }
                if (mListener != null) {
                    mListener.onOtherClick ();
                }
            }
        });
    }

    private SpannableStringBuilder getCommentString () {
        SpannableStringBuilder mStringBuilder = new SpannableStringBuilder ();
        /**
         * 对评论数据进行处理,默认超过mMaxlines条则第mMaxlines+1条显示查看全部
         */
        for (int mI = 0; mI < mInfos.size (); mI++) {
            final CommentInfo mInfo = mInfos.get (mI);
            /**
             * 拼接成“张三:今天天气真好”这种形式,就是一行显示的文本。
             * 或者为张三 回复 李四:今天天气真好
             */
            String mS = null;
            if (mInfo.getTonickname () == null || mInfo.getTonickname ().equals ("")) {
                mS = mInfo.getNickname () + ":" + mInfo.getComment ();
            } else {
                mS = mInfo.getNickname () + mTalkStr + mInfo.getTonickname () + ":" + mInfo.getComment ();
            }
            /**
             * 获得一个SpannableString文本的对象
             */
            SpannableString mString = new SpannableString (mS);
            /**
             * 我们假设“张三:今天天气真好”这句话中“张三:”这三个字符为橘红色字体并且添加点击事件,其余评论内容单独添加事件,一般业务需求是点击人名跳到个人主页或者聊天,点击评论内容是对这条评论进行评论。
             * 谁回复谁同理,就不写了
             */
            int start = 0;
            int end = (mInfo.getNickname ()).length ();
            final int finalMI = mI;
            /**
             * 处理第一个人名
             * 设置文本从第0个开始到end位置具有点击事件,点击后回调,updateDrawState中设置文本从第0个到第end位置的文本前景色就是文字颜色为橘红色
             */
            mString.setSpan (new ClickableSpan () {

                @Override
                public void updateDrawState (TextPaint ds) {
                    /**
                     * 是否有下划线
                     */
                    ds.setUnderlineText (false);
                    /**
                     * 橘红色字体
                     */
                    ds.setColor (mNameColor);
                }

                @Override
                public void onClick (final View widget) {
                    isNickNameClick = true;
                    if (mListener != null) {
                        mListener.onNickNameClick (finalMI, mInfos.get (finalMI));
                    }
                }
            }, 0, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            mString.setSpan (new ForegroundColorSpan (mTalkColor),mInfo.getNickname ().length (),mInfo.getNickname ().length ()+mTalkStr.length (),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            /**
             * 处理第二个人名
             */
            if (mInfo.getTonickname () != null && !mInfo.getTonickname ().equals ("")) {
                start = mInfo.getNickname ().length () + mTalkStr.length ();
                end = mInfo.getNickname ().length () + mTalkStr.length () + mInfo.getTonickname ().length ();
                mString.setSpan (new ClickableSpan () {
                    @Override
                    public void updateDrawState (TextPaint ds) {
                        /**
                         * 是否有下划线
                         */
                        ds.setUnderlineText (false);
                        /**
                         * 橘红色字体
                         */
                        ds.setColor (mNameColor);
                    }

                    @Override
                    public void onClick (final View widget) {
                        isNickNameClick = true;
                        if (mListener != null) {
                            mListener.onToNickNameClick (finalMI, mInfos.get (finalMI));
                        }
                    }
                }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }

            /**
             * 设置文本从第end个开始到最后位置具有点击事件,点击后回调,updateDrawState中设置文本从第end个到最后的文本前景色就是文字颜色为黑色
             */

            mString.setSpan (new ClickableSpan () {

                @Override
                public void updateDrawState (TextPaint ds) {
                    /**
                     * 是否有下划线
                     */
                    ds.setUnderlineText (false);
                    /**
                     * 黑色字体
                     */
                    ds.setColor (mCommentColor);
                }

                @Override
                public void onClick (final View widget) {
                    isNickNameClick = true;
                    if (mListener != null) {
                        mListener.onCommentItemClick (finalMI, mInfos.get (finalMI));
                    }
                }
            }, end, mS.length (), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            /**
             * 设置文本从第end个到最后的文本前景色就是文字颜色为黑色,即评论内容为黑色
             */

            mStringBuilder.append (mString);
            mStringBuilder.append ("\r\n");
            if (mI == (mMaxlines - 1)) {
                break;
            }
        }
        if (mInfos.size () > mMaxlines) {
            mStringBuilder.append ("查看全部评论");
        } else {
            /**
             * 如果不大于3条,则删除最后的换行
             */
            mStringBuilder.delete (mStringBuilder.length () - 2, mStringBuilder.length ());
        }
        return mStringBuilder;
    }


    public interface onCommentListener {
        /**
         * 点击人名的回调
         *
         * @param position 第几条评论  从0开始
         * @param mInfo    评论相关信息
         */
        public void onNickNameClick (int position, CommentInfo mInfo);

        /**
         * 点击被评论人名的回调
         *
         * @param position 第几条评论  从0开始
         * @param mInfo    评论相关信息
         */
        public void onToNickNameClick (int position, CommentInfo mInfo);

        /**
         * 点击评论文本回调,主要针对对谁回复操作
         *
         * @param position
         * @param mInfo
         */
        public void onCommentItemClick (int position, CommentInfo mInfo);

        /**
         * 点击非文字部分
         */
        public void onOtherClick ();
    }

    public static  class CommentInfo {
        /**
         * 评论ID
         */
        private int ID;
        /**
         * 评论人名称
         */
        private String nickname;
        /**
         * 评论内容
         */
        private String comment;
        /**
         * 被评论人名称
         */
        private String tonickname;

        @Override
        public String toString () {
            return "CommentInfo{" +
                    "ID=" + ID +
                    ", nickname='" + nickname + '\'' +
                    ", comment='" + comment + '\'' +
                    ", tonickname='" + tonickname + '\'' +
                    '}';
        }

        /**
         * 下面可以继续写自定义需要的属性,需要传什么写什么
         */


        public int getID () {
            return ID;
        }

        public CommentInfo setID (final int mID) {
            ID = mID;
            return this;
        }

        public String getNickname () {
            return nickname;
        }

        public CommentInfo setNickname (final String mNickname) {
            nickname = mNickname;
            return this;
        }

        public String getComment () {
            return comment;
        }

        public CommentInfo setComment (final String mComment) {
            comment = mComment;
            return this;
        }

        public String getTonickname () {
            return tonickname;
        }

        public CommentInfo setTonickname (final String mTonickname) {
            tonickname = mTonickname;
            return this;
        }
    }
}

commentlisttextview's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

commentlisttextview's Issues

怎么没有第二张类似朋友圈的demo ?

你给出的只是第一张的实例,第二张例子怎么没有代码? 而且你这个使用环境在什么情况下?

我评论肯定是listview 展示的!你这样是listview的item?

关于分割线

你好,请问像第二张效果图那样每条评论下面加一条线要怎么设置?研究半天了没找到办法!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.