Android仿QQ空间二级评论列表
2017-02-17 11:53
232 查看
之前项目中产品需求带二级的评论列表,首先想到是QQ空间评论列表。
先上效果图
下面我们来分析一下布局结构,首先一级列表是listview,然后二级列表也可以有多条,为了省事我只添加了一条,第一反应是listview嵌套listview,然而listview嵌套又会出现显示不全等问题,于是自定义listview解决高度问题,废话不多说直接上代码:
布局文件最外层是竖直的LinearLayout
自定义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 {
}
二级adapter
public class ComReplyAdapter extends BaseAdapter {
// 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);
}
activity中使用:
demo地址:http://download.csdn.net/detail/u010702071/9756595
如果不足之处还望指正,谢谢!
先上效果图
下面我们来分析一下布局结构,首先一级列表是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二级listview列表
- Android中的二级列表的应用
- Android 横向二级ListView列表
- Android二级分类列表ListView GirdView in ViewPager
- Android二级分类列表GirdView
- android二级列表(BaseExpandableListAdapter的使用) 仿通话记录
- Android开发实现二级联动下拉列表
- Android点击列表后弹出输入框,所点击项自动滚动到输入框上方(类似微信的评论)
- android二级listview列表
- 实现QQ空间评论列表样式
- android二级listview列表
- android二级listview列表
- android二级listview列表实现代码(高仿大众点评)
- [Android UI开发] 固定在ScrollView顶部的View,类似于新浪微博的评论列表的顶部
- android二级listview列表
- android二级listview列表
- AdapterView及其子类之三:基于ListView及ArrayAdapter实现列表 分类: H1_ANDROID 2013-11-19 22:35 987人阅读 评论(0) 收藏
- Android应用开发-小巫CSDN博客客户端之获取评论列表
- Android应用开发-小巫CSDN博客client之获取评论列表
- Android -- 固定在ScrollView顶部的View,类似于新浪微博的评论列表的顶部