您的位置:首页 > 移动开发 > Android开发

Android仿QQ空间二级评论列表

2017-02-17 11:53 232 查看
之前项目中产品需求带二级的评论列表,首先想到是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

如果不足之处还望指正,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android qq空间 布局