零、expandableListview评论的效果图
一、expandableListView基本用法
- 基本上与listView一样的引入方式相同
- expandablelistveiw的adapter要继承
自expandableListview
二、expandableListview去掉Group指示标志
- 只需要在xml文件中添加:android:groupIndicator=”@null”
三、expandableListView设置groupdivider,childivider
- 默认的情况下父和子都有分割线
- 子分割线 在xml文件中添加 :android:childDivider=”*“;
- 父分割线 在xml文件中添加 :android:groupDivider=”*”(中可以用drawable文件)
- 去掉分割线:android:childDivider=”@drawable/transparent_bg”(使用一个透明的shape)
四、expandableListView展开
在expandableListView中默认列表时不展开的,所以为了将相应的子列表展开可以添加以下代码:
for (int i = 0; i < groupArray.size(); i++){
elvComment.expandGroup(i);
}
其中(elvComment为expandablelistview这个对象,groupArray为相应父数据)
ExpandableListView 中Adapter
该expandableListView的adapter是继承BaseExpandableListAdapter默认要重写getGroupCount(),getGroup(),getGroupView() ,getGroupId() , getChildCount(),getChild(),getChildView,getChildId(),hasStableIds(),isChildSelectable() 这些方法可以在该链接中找到传送门,总而言之最后两个方法的boole值就直接返回为true就行。
重点来了
expandableListview怎样来设置空视图呢?
如果直接在代码中套用expandableListView.setEmpterView()这个方法会发现该方法不起作用,这时应该在Adapter中重写方法isEmpty()代码如下
@Override
public boolean isEmpty() {
//groupArray为相应的父数据
if(groupArray!=null && groupArray.size()>0){
return false;
}else {
return true;
}
}
这时你会发现你的空视图就这样可以了,看网上许多人直接return true这是不对,或者说是没有请求网络数据,这时会发现不管你的是否有父数据你都发现这个视图不会出现或者根本是个空白,这里还是有个坑,就这如果写成这样貌似也是不行,会出现一直空视图
@Override
public boolean isEmpty() {
//groupArray为相应的父数据
if(groupArray!=null && groupArray.size()>0){
return false;
}
return true;
}
ExpandableListView怎么加载网络数据并且正常的刷新?
我在网上找了很长时间但是大多数都是相应静态数据,那么问题来了,我要做个评论这种视图,怎么办,不能说我就搞个静态数据吧,用listView那种更新方法是不能起作用的,当然可以listview套用listview,这里暂且不提,下面来看看网络怎么加载expandableListView数据(当然感谢那些说用handler的人,具体是哪个网址也忘了,不好意思),虽然说了使用方式但是只是给了个片段,让我们这些小白很受伤所以我就把我在项目做得更新方式拿出来了,效果达到了。不知是不是好的方式。
在handlerMessage中expandableListView.collapseGroup(msg.arg1);
expandableListView.expandGroup(msg.arg1);这两个方法必须写,
这是在Activity中的代码
private List<Object> groupArray = new ArrayList<>();
private List<List<Object>> childArray = new ArrayList<>();
public void loadCommentData() {
showLoadingDialog();
Map<String, Object> params = new HashMap<>();
params.put(ConstantUtil.URL_TYPE, "1");
params.put("size", 10000);
params.put("page", 1);
HaoConnect.request("cw_deal_comment/dealcommentlist", params, "get", new HaoResultHttpResponseHandler() {
@Override
public void onSuccess(HaoResult result) {
dismissLoadingDialog();
groupArray.clear();
childArray.clear();
ArrayList<Object> asList = result.findAsList("results>");
for (int i = 0; i <asList.size() ; i++) {
CwDealCommentResult cwDealCommentResult = (CwDealCommentResult) asList.get(i);
groupArray.add(cwDealCommentResult); //这是添加相应的父数据;
//这是用于显示相应的子回复;
LogUtils.i("---->>>" + groupArray.size());
List<Object> sonList = (List<Object>) cwDealCommentResult.findReplyInfo();
List<Object> childItem = new ArrayList<>();
for (Object p : sonList) {
childItem.add(p);
}
childArray.add(i,childItem);
}
for (int i = 0; i < groupArray.size(); i++) {
adapter.refresh(elvComment, i, childArray.get(i));
}
}
@Override
public void onFail(HaoResult result) {
super.onFail(result);
dismissLoadingDialog();
AppDialog.showHintDialog(CommentActivity.this, result.errorStr);
}
}, CommentActivity.this);
}
这是在Adapter中的代码
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 0:
childArray.add(msg.arg1, (List<Object>) msg.obj);
expandableListView.collapseGroup(msg.arg1);
//必须重新伸缩之后才能更新数据
expandableListView.expandGroup(msg.arg1);
break;
}
notifyDataSetChanged(); //更新数据
super.handleMessage(msg);
}
};
/*供外界更新数据的方法*/
public void refresh(ExpandableListView expandableListView, int groupPosition,List<Object> childItem){
this.expandableListView = expandableListView;
Message message = new Message();
message.obj = childItem;
message.arg1 = groupPosition;
message.what = 0;
handler.sendMessage(message);
}
下面来贴出完整的adapter代码,因为Activity代码中除了以上设置默认展开之外基本与listview是相同的
/**
* Created by limei on 2017/4/12.
*/
public class MessageCommentExpandableAdapter extends BaseExpandableListAdapter {
private Context mContext;
private List<Object> groupArray;
private List<List<Object>> childArray;
private LayoutInflater inflater;
private ExpandableListView expandableListView;
private String type = null;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 0:
childArray.add(msg.arg1, (List<Object>) msg.obj);
expandableListView.collapseGroup(msg.arg1);
//必须重新伸缩之后才能更新数据
expandableListView.expandGroup(msg.arg1);
break;
}
notifyDataSetChanged(); //更新数据
super.handleMessage(msg);
}
};
public static final int TYPE_ITEMS = 1;
public static final int TYPE_FOOTER = 2;
public MessageCommentExpandableAdapter(Context mContext,String type ,List<Object> groupArray, List<List<Object>> childArray) {
this.mContext = mContext;
this.groupArray = groupArray;
this.childArray = childArray;
this.type = type;
inflater = LayoutInflater.from(mContext);
}
@Override
public int getGroupCount() {
if(groupArray!=null){
return groupArray.size()==0 ? 0 :groupArray.size();
}
return 0;
}
@Override
public Object getGroup(int groupPosition) {
return groupArray.get(groupPosition);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return childArray.get(groupPosition).get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public int getChildrenCount(int groupPosition) {
if(groupArray!=null){
return childArray != null ? childArray.get(groupPosition).size() + 1 : 1;
}
return 0;
}
@Override
public int getChildTypeCount() {
return 3;
}
@Override
public int getChildType(int groupPosition, int childPosition) {
if(groupArray!=null){
int size = getChildrenCount(groupPosition);
if(childPosition == size-1 ){
return TYPE_FOOTER;
}else {
return TYPE_ITEMS;
}
}
return -1;
}
//这个在空视图时候必须重写,否则会失效。
@Override
public boolean isEmpty() {
//groupArray为相应的父数据
if(groupArray!=null && groupArray.size()>0){
return false;
}else {
return true;
}
}
// //这个在空视图时候必须重写,否则会失效。
// @Override
// public boolean isEmpty() {
// //groupArray为相应的父数据
// if(groupArray!=null && groupArray.size()>0){
// return false;
// }
// return true;
// }
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
MessageCommentExpandableAdapter.GroupHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_comment_group, parent, false);
holder = new MessageCommentExpandableAdapter.GroupHolder(convertView);
convertView.setTag(holder);
} else {
holder = (MessageCommentExpandableAdapter.GroupHolder) convertView.getTag();
}
if(type.equals(CommentActivity.COMMENT_TYPE)){
//这个是在消息产生的评论
holder.llCommentProject.setVisibility(View.VISIBLE);
holder.ivReviewIcon.setVisibility(View.VISIBLE);
holder.tvReviewText.setVisibility(View.GONE);
}else if(type.equals(ProjectCommentActivity.COMMENT_TYPE)){
//这个是在项项目下产生的评论
holder.llCommentProject.setVisibility(View.GONE);
holder.ivReviewIcon.setVisibility(View.GONE);
holder.tvReviewText.setVisibility(View.VISIBLE);
}
CwDealCommentResult result = (CwDealCommentResult)groupArray.get(groupPosition);
String userName = result.findUserName().toString()==null ? "":result.findUserName().toString();
holder.tvUserName.setText(userName);
String imgIcon = result.findAvatars().toString();
if(imgIcon!=null){
GlideUtil.getInstance().loadCircleImage(mContext,holder.ivUserIcon,imgIcon);
}
String time = (String) result.findCreateTimeLabel();
holder.tvUserTime.setText(time==null?"":time);
String imageUrl = result.findImageUrl().toString();
if(imageUrl!=null){
GlideUtil.getInstance().loadImage(mContext,holder.ivItemIcon,imageUrl,true);
}else {
holder.ivItemIcon.setImageResource(R.mipmap.dawen_payment);
}
String projectTitle = result.findProjectName().toString();
holder.tvItemTitle.setText(projectTitle==null?"佚名":projectTitle);
String comment = result.findContent().toString();
holder.tvUserComment.setText( comment==null?"":comment);
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
MessageCommentExpandableAdapter.ChildHolder holder = null;
switch (getChildType(groupPosition,childPosition)){
case TYPE_ITEMS:
if(convertView == null){
convertView = inflater.inflate(R.layout.item_comment_child,parent,false);
holder = new MessageCommentExpandableAdapter.ChildHolder(convertView);
convertView.setTag(holder);
}else {
holder = (MessageCommentExpandableAdapter.ChildHolder) convertView.getTag();
}
case TYPE_FOOTER:
if(convertView == null){
convertView = inflater.inflate(R.layout.item_comment_child_footer,parent,false);
holder = new MessageCommentExpandableAdapter.ChildHolder(convertView);
convertView.setTag(holder);
}else {
holder = (MessageCommentExpandableAdapter.ChildHolder) convertView.getTag();
}
}
switch (getChildType(groupPosition,childPosition)){
case TYPE_ITEMS:
CwDealCommentResult cwResult = (CwDealCommentResult) childArray.get(groupPosition).get(childPosition);
if(cwResult!=null){
holder.tvReviewer.setText(cwResult.findReplyUserName().toString()+": ");
holder.tvReviewComment.setText(cwResult.findContent().toString());
}
break;
case TYPE_FOOTER:
holder.tvReviewCount.setVisibility(View.GONE);
break;
}
// convertView.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
CommentDetail2Activity.startAction(mContext);
// }
// });
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
private class GroupHolder {
private ImageView ivUserIcon, ivReviewIcon, ivItemIcon;
private TextView tvUserName,tvUserComment,tvUserTime,tvReviewText,tvItemTitle,tvAllComment;
private LinearLayout llCommentProject;
public GroupHolder(View convertView) {
ivUserIcon = (ImageView) convertView.findViewById(R.id.iv_user_icon);
ivReviewIcon = (ImageView) convertView.findViewById(R.id.iv_review_icon);
ivItemIcon = (ImageView) convertView.findViewById(R.id.iv_item_icon);
tvUserName = (TextView) convertView.findViewById(R.id.tv_user_name);
tvUserComment = (TextView) convertView.findViewById(R.id.tv_user_comment);
tvUserTime = (TextView) convertView.findViewById(R.id.tv_user_time);
tvItemTitle = (TextView) convertView.findViewById(R.id.tv_item_title);
tvReviewText = (TextView) convertView.findViewById(R.id.tv_review_text);
llCommentProject = (LinearLayout) convertView.findViewById(R.id.ll_comment_project);
}
}
private class ChildHolder {
TextView tvReviewer,tvReviewComment, tvReviewCount;;
public ChildHolder(View convertView) {
tvReviewer = (TextView) convertView.findViewById(R.id.tv_reviewer);
tvReviewComment = (TextView) convertView.findViewById(R.id.tv_reviewer_comment);
tvReviewCount = (TextView) convertView.findViewById(R.id.tv_review_count);
}
}
/*供外界更新数据的方法*/
public void refresh(ExpandableListView expandableListView, int groupPosition,List<Object> childItem){
this.expandableListView = expandableListView;
Message message = new Message();
message.obj = childItem;
message.arg1 = groupPosition;
message.what = 0;
handler.sendMessage(message);
}
}
这里应该注意一个坑(这个坑是在当子固定一个非网络请求的数据,栗子:共有**条回复),如果不考虑父数据没有时,会出现错误,所以我在getGroupCount和getChildCount中都做了相应的判断
怎么给子添加添加尾视图
这里应该重写getChildType() ,getChildTypeCount(),在getChildType()中应该判断groupArray是否为空,否则会报错,在个getChildTypeCount()中应该return 3 ,不能return 2,这里不知道为什么错误?