Android仿QQ空间二级评论列表

之前项目中产品需求带二级的评论列表,首先想到是QQ空间评论列表。
先上效果图
这里写图片描述
下面我们来分析一下布局结构,首先一级列表是listview,然后二级列表也可以有多条,为了省事我只添加了一条,第一反应是listview嵌套listview,然而listview嵌套又会出现显示不全等问题,于是自定义listview解决高度问题,废话不多说直接上代码:
布局文件最外层是竖直的LinearLayout

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <com.world.compet.view.CircleImageView
        android:id="@+id/commentItemImg"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_marginLeft="12dp"
        android:layout_marginTop="15dp"
        android:contentDescription="@string/app_name"
        android:src="@drawable/photo_pic" />

    <RelativeLayout
        android:id="@+id/rl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="12dp"
        android:layout_marginTop="13dp" >

        <!-- 评论人昵称 -->

        <TextView
            android:id="@+id/commentNickname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:text="游客1"
            android:textColor="#333333"
            android:textSize="14sp" />

        <ImageView
            android:id="@+id/male"
            android:layout_width="11dp"
            android:layout_height="11dp"
            android:layout_alignTop="@+id/commentNickname"
            android:layout_centerVertical="true"
            android:layout_marginLeft="7dp"
            android:layout_marginTop="4dp"
            android:visibility="invisible"
            android:layout_toRightOf="@+id/commentNickname"
            android:background="@drawable/nv" />
        <!-- 评论时间 -->

        <TextView
            android:id="@+id/commentItemTime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@id/commentNickname"
            android:layout_marginTop="3dp"
            android:text="6秒前"
            android:textColor="#b6b6b6"
            android:textSize="11sp" />
        <!-- 评论人内容 -->

        <LinearLayout
            android:id="@+id/description_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/commentItemTime"
            android:orientation="vertical"
            android:paddingTop="15dip" >

            <TextView
                android:id="@+id/commentItemContent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_below="@id/commentItemTime"
                android:ellipsize="end"
                android:textColor="#666666"
                android:lineSpacingExtra="2dp"
                android:textSize="14sp" />


        </LinearLayout>

        <LinearLayout
            android:id="@+id/ll_comment"
            android:layout_width="wrap_content"
            android:layout_height="30dp"
            android:layout_alignParentRight="true"
            android:layout_marginTop="2dp"
            android:orientation="horizontal" >

            <LinearLayout
                android:id="@+id/ll_dig"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginRight="20dp"
                android:orientation="horizontal" >

                <ImageView
                    android:id="@+id/like"
                    android:layout_width="15dp"
                    android:layout_height="15dp"
                    android:layout_marginRight="4dp"
                    android:background="@drawable/pinglunzan1" />

                <TextView
                    android:id="@+id/like_num"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="0"
                    android:textColor="#b6b6b6"
                    android:textSize="12dp" />
            </LinearLayout>

            <LinearLayout
                android:id="@+id/ll_comm"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <ImageView
                    android:id="@+id/com"
                    android:layout_width="15dp"
                    android:layout_height="15dp"
                    android:layout_marginRight="4dp"
                    android:background="@drawable/xiaoxiicon" />

                <TextView
                    android:id="@+id/tv_commentnum"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="0"
                    android:textColor="#b6b6b6"
                    android:textSize="12dp" />
            </LinearLayout>
        </LinearLayout>

        <com.world.compet.view.NoScrollListView
            android:id="@+id/replyList"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/description_layout"
            android:layout_marginTop="15dp"
            android:divider="#00000000"
            android:focusable="false" />

        <View
            android:id="@+id/line"
            android:layout_width="match_parent"
            android:layout_height="15dp"
            android:layout_below="@+id/replyList"
            android:background="#00ffffff" />
    </RelativeLayout>
</LinearLayout>



<View
    android:id="@+id/nolast"
    android:layout_width="match_parent"
    android:layout_height="0.5dp"
    android:layout_marginLeft="57dp"
    android:layout_marginRight="12dp"
    android:background="#f3f3f3" />
<View
    android:id="@+id/last"
    android:visibility="gone"
    android:layout_width="match_parent"
    android:layout_height="0.5dp"
    android:layout_marginRight="12dp"
    android:background="#f3f3f3" />

自定义listview:
package com.example.jing.commentdemo.view;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;

public class NoScrollListView extends ListView {
public NoScrollListView(Context context, AttributeSet attrs) {
super(context,attrs);
}
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int mExpandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, mExpandSpec);
}

}
下面主要是adapter
public class CommentAdapter extends BaseAdapter {

private Context context;
private List<CommentBean> list;
private LayoutInflater inflater;
private replyClickListener rClickListener;
private AnimateFirstDisplayListener animateFirstDisplayListener = new AnimateFirstDisplayListener();
@SuppressWarnings("unused")
private String nid;
private Handler handler;
int maxDescripLine = 5;

// int isdigg=0;

public CommentAdapter(String nid, Context context,
                      List<CommentBean> list, int resourceId, Handler handler) {
    this.nid = nid;
    this.list = list;
    this.context = context;
    inflater = LayoutInflater.from(context);
    this.handler = handler;
}

@Override
public int getCount() {
    return list.size();
}

@Override
public Object getItem(int position) {
    return list.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@SuppressLint("CutPasteId")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final CommentBean bean = list.get(position);
    ViewHolder holder = null;
    if (convertView == null) {
        holder = new ViewHolder();
        convertView = inflater.inflate(R.layout.all_comment_item, null);
        holder.nolast=convertView.findViewById(R.id.nolast);
        holder.last=convertView.findViewById(R.id.last);
        holder.commentItemImg = (CircleImageView) convertView
                .findViewById(R.id.commentItemImg);
        holder.commentNickname = (TextView) convertView
                .findViewById(R.id.commentNickname);
        holder.likeNum = (TextView) convertView.findViewById(R.id.like_num);
        holder.commentItemTime = (TextView) convertView
                .findViewById(R.id.commentItemTime);
        holder.commentItemContent = (TextView) convertView
                .findViewById(R.id.commentItemContent);
        holder.replyList = (NoScrollListView) convertView
                .findViewById(R.id.replyList);

        holder.ivLike = (ImageView) convertView.findViewById(R.id.like);
        holder.ivSex = (ImageView) convertView.findViewById(R.id.male);
        holder.replayNum = (TextView) convertView
                .findViewById(R.id.tv_commentnum);
        holder.digLayout = (LinearLayout) convertView
                .findViewById(R.id.ll_dig);
        holder.comLayout = (LinearLayout) convertView
                .findViewById(R.id.ll_comm);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    if (position==list.size()-1) {
        holder.last.setVisibility(View.VISIBLE);
        holder.nolast.setVisibility(View.GONE);
    }else {
        holder.nolast.setVisibility(View.VISIBLE);
        holder.last.setVisibility(View.GONE);

    }
    final ComReplyAdapter adapter = new ComReplyAdapter(
            context, bean.getL2_comment(), R.layout.reply_item);
     holder.replyList.setAdapter(adapter);
    // Utility.setListViewHeightBasedOnChildren(holder.replyList);
    holder.comLayout
            .setOnClickListener(new TextviewClickListener(position) {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    super.onClick(v);
                }
            });
    holder.digLayout
            .setOnClickListener(new TextviewClickListener(position) {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    super.onClick(v);
                }

            });
    holder.commentItemContent.setOnClickListener(new TextviewClickListener(
            position) {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            super.onClick(v);
        }

    });
    holder.replayNum.setText(bean.getComment_count());
    if (holder.commentItemImg.getTag() == null
            || !holder.commentItemImg.getTag().toString()
                    .equals(bean.getAvatar())) {

        App.getImageLoader().displayImage(bean.getAvatar(),
                holder.commentItemImg, App.getInstance().getOptions(),
                animateFirstDisplayListener);
    }
    holder.commentItemImg.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            // 跳转个人主页
             Toast.makeText(context, bean.getNick_name(),
             Toast.LENGTH_SHORT).show();

        }
    });
    holder.commentNickname.setText(bean.getNick_name());
    holder.commentItemTime.setText(bean.getCreate_time() + " "
            + bean.getUnivs_name());
    // holder.commentItemContent.setText(bean.getContent());
    final TextView descriptionView = (TextView) convertView
            .findViewById(R.id.commentItemContent);
    descriptionView.setText(bean.getContent());




    holder.likeNum.setText(bean.getDigg_count());
    // notifyDataSetChanged();
    adapter.setOnCommentClickListenern(new ComReplyAdapter.commentClickListener() {

        @Override
        public void OnCommentClick(String realName, String tuid,
                                   String parentid, int sonPosition) {
            // TODO Auto-generated method stub
            // SKApp.getInstance().showErrToast(realName);
            rClickListener.onClick(realName, tuid, parentid, position,
                    sonPosition);

        }
    });
    if (bean.getL2_comment().size() > 0) {
        holder.replyList.setVisibility(View.VISIBLE);
    } else {
        holder.replyList.setVisibility(View.GONE);
    }
    return convertView;
}

private final class ViewHolder {
    public CircleImageView commentItemImg; // 评论人图片
    public TextView commentNickname; // 评论人昵称
    public TextView likeNum; // 点赞人数
    public TextView commentItemTime; // 评论时间
    public TextView commentItemContent; // 评论内容
    public NoScrollListView replyList; // 评论回复列表
    public ImageView ivLike;
    public ImageView ivSex;
    public TextView replayNum;
    public LinearLayout digLayout;
    public LinearLayout comLayout;
    public View last;
    public View nolast;
    // public Button moreButton;
    // public View line;

}

/**
 * 事件点击监听器
 */
private class TextviewClickListener implements OnClickListener {

    int position;

    public TextviewClickListener(int position) {
        this.position = position;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.ll_dig:
            Message digmsg = handler.obtainMessage();
            digmsg.what = 10;
            digmsg.arg1 = position;

            handler.sendMessage(digmsg);
            break;
        case R.id.ll_comm:
            Message msg = handler.obtainMessage();
            msg.what = 11;
            msg.arg1 = position;
            handler.sendMessage(msg);
            break;
        case R.id.commentItemContent:
            Message msg1 = handler.obtainMessage();
            msg1.what = 11;
            msg1.arg1 = position;
            handler.sendMessage(msg1);
            break;
        }
    }
}

public interface replyClickListener {
    public void onClick(String realName, String tuid, String parentid,
                        int pos, int sonPosition);
}

public void SetOnRepalClickListener(replyClickListener rListener) {

    rClickListener = rListener;

}

}
二级adapter
public class ComReplyAdapter extends BaseAdapter {

private List<L2CommentBean> list;
private LayoutInflater inflater;
private TextView replyContent;
private SpannableString ss;
private commentClickListener commClickListener;
private Context context;

public ComReplyAdapter(Context context,
                       List<L2CommentBean> list, int resourceId) {
    this.context = context;
    this.list = list;
    inflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
    return list.size();
}

@Override
public Object getItem(int position) {
    return list.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final L2CommentBean bean = list.get(position);
    convertView = inflater.inflate(R.layout.reply_item, null);
    replyContent = (TextView) convertView.findViewById(R.id.replyContent);

    final String replyNickName = bean.getNick_name() + " ";
    final String commentNickName = " " + bean.getTo_nick_name();
    String replyContentStr = bean.getContent();
    // 用来标识在 Span 范围内的文本前后输入新的字符时是否把它们也应用这个效果
    // Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括)
    // Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包括,后面不包括)
    // Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包括,后面包括)
    // Spanned.SPAN_INCLUSIVE_INCLUSIVE(前后都包括)
    if (!TextUtils.isEmpty(commentNickName)) {

        ss = new SpannableString(replyNickName + "回复" + commentNickName
                + " " + replyContentStr);
    } else {
        ss = new SpannableString(replyNickName + " " + replyContentStr);

    }

    ss.setSpan(new ForegroundColorSpan(Color.parseColor("#22bfa7")), 0,
            replyNickName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    ss.setSpan(new ForegroundColorSpan(Color.parseColor("#22bfa7")),
            replyNickName.length() + 2, replyNickName.length()
                    + commentNickName.length() + 2,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    // 为回复的人昵称添加点击事件----前面的名字
    ss.setSpan(new TextSpanClick(replyNickName) {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            super.onClick(v);

// Toast.makeText(context,”个人中心”,Toast.LENGTH_SHORT).show();
}
}, 0, replyNickName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// //为评论的人的添加点击事件——-后面的名字
ss.setSpan(new TextSpanClick(commentNickName) {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
super.onClick(v);
// Toast.makeText(context,”个人中心”,Toast.LENGTH_SHORT).show();
}
}, replyNickName.length() + 2,
replyNickName.length() + commentNickName.length() + 2,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
replyContent.setText(ss);

    // 添加点击事件时,必须设置
    replyContent.setMovementMethod(LinkMovementMethod.getInstance());
    replyContent.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            // Toast.makeText(context, replyNickName+"~~",
            // Toast.LENGTH_SHORT).show();


                commClickListener.OnCommentClick(replyNickName,
                        bean.getUid(), bean.getParent_comment_id(),
                        position);

        }
    });
    return convertView;
}

private class TextSpanClick extends ClickableSpan {
    @SuppressWarnings("unused")
    private String nam;

    public TextSpanClick(String name) {
        nam = name;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        ds.setUnderlineText(false);// 取消下划线
    }

    @Override
    public void onClick(View v) {
        // 跳转个人主页
        // Toast.makeText(context, nam, Toast.LENGTH_SHORT).show();
    }
}

public interface commentClickListener {
    public void OnCommentClick(String realName, String tuid,
                               String parentid, int sonPosition);
}

public void setOnCommentClickListenern(commentClickListener comListener) {
    // if (commClickListener==null) {

    commClickListener = comListener;
    // }
}

public void addAll(List<L2CommentBean> list) {
    this.list = list;
    notifyDataSetChanged();
}

}
activity中使用:

 mAdapter = new CommentAdapter("0", MainActivity.this,
                comments, R.layout.comment_item, handler);
        mAdapter.SetOnRepalClickListener(new CommentAdapter.replyClickListener() {
            @Override
            public void onClick(String realName, String tuid, String parentid,
                                int pos, int sonPosition) {// 二级评论的回复
                Toast.makeText(MainActivity.this, "二级的回复", Toast.LENGTH_SHORT).show();

            }
        });
        mListView.setAdapter(mAdapter);
private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 10:

                    break;
                case 11:// 一级评论的回复

                    break;
                default:
                    break;
            }

        }
    };

demo地址:http://download.csdn.net/detail/u010702071/9756595
如果不足之处还望指正,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值