expandableListview
零圃伶、expandableListview評論的效果圖
一侥猩、expandableListView基本用法
- 基本上與listView一樣的引入方式相同
- expandablelistveiw的adapter要繼承
自expandableListview
二瓣俯、expandableListview去掉Group指示標志
- 只需要在xml文件中添加:android:groupIndicator="@null"
三驼仪、expandableListView設(shè)置groupdivider,childivider
- 默認的情況下父和子都有分割線
- 子分割線 在xml文件中添加 :android:childDivider="***";
- 父分割線 在xml文件中添加 :android:groupDivider="*"(中可以用drawable文件)
- 去掉分割線:android:childDivider="@drawable/transparent_bg"(使用一個透明的shape)
四、expandableListView展開
在expandableListView中默認列表時不展開的,所以為了將相應(yīng)的子列表展開可以添加以下代碼:
for (int i = 0; i < groupArray.size(); i++){
elvComment.expandGroup(i);
}
其中(elvComment為expandablelistview這個對象,groupArray為相應(yīng)父數(shù)據(jù))
ExpandableListView 中Adapter
該expandableListView的adapter是繼承BaseExpandableListAdapter默認要重寫getGroupCount(),getGroup(),getGroupView() ,getGroupId() , getChildCount(),getChild(),getChildView,getChildId(),hasStableIds(),isChildSelectable() 這些方法可以在該鏈接中找到傳送門,總而言之最后兩個方法的boole值就直接返回為true就行杉编。
重點來了
expandableListview怎樣來設(shè)置空視圖呢?
如果直接在代碼中套用expandableListView.setEmpterView()這個方法會發(fā)現(xiàn)該方法不起作用,這時應(yīng)該在Adapter中重寫方法isEmpty()代碼如下
@Override
public boolean isEmpty() {
//groupArray為相應(yīng)的父數(shù)據(jù)
if(groupArray!=null && groupArray.size()>0){
return false;
}else {
return true;
}
}
這時你會發(fā)現(xiàn)你的空視圖就這樣可以了,看網(wǎng)上許多人直接return true這是不對,或者說是沒有請求網(wǎng)絡(luò)數(shù)據(jù),這時會發(fā)現(xiàn)不管你的是否有父數(shù)據(jù)你都發(fā)現(xiàn)這個視圖不會出現(xiàn)或者根本是個空白,這里還是有個坑,就這如果寫成這樣貌似也是不行,會出現(xiàn)一直空視圖
@Override
public boolean isEmpty() {
//groupArray為相應(yīng)的父數(shù)據(jù)
if(groupArray!=null && groupArray.size()>0){
return false;
}
return true;
}
ExpandableListView怎么加載網(wǎng)絡(luò)數(shù)據(jù)并且正常的刷新娄昆?
我在網(wǎng)上找了很長時間但是大多數(shù)都是相應(yīng)靜態(tài)數(shù)據(jù)扒俯,那么問題來了,我要做個評論這種視圖,怎么辦,不能說我就搞個靜態(tài)數(shù)據(jù)吧,用listView那種更新方法是不能起作用的,當(dāng)然可以listview套用listview,這里暫且不提惦积,下面來看看網(wǎng)絡(luò)怎么加載expandableListView數(shù)據(jù)(當(dāng)然感謝那些說用handler的人睦柴,具體是哪個網(wǎng)址也忘了恬试,不好意思)妇拯,雖然說了使用方式但是只是給了個片段,讓我們這些小白很受傷所以我就把我在項目做得更新方式拿出來了,效果達到了。不知是不是好的方式。
在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); //這是添加相應(yīng)的父數(shù)據(jù);
//這是用于顯示相應(yīng)的子回復(fù);
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);
//必須重新伸縮之后才能更新數(shù)據(jù)
expandableListView.expandGroup(msg.arg1);
break;
}
notifyDataSetChanged(); //更新數(shù)據(jù)
super.handleMessage(msg);
}
};
/*供外界更新數(shù)據(jù)的方法*/
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代碼中除了以上設(shè)置默認展開之外基本與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);
//必須重新伸縮之后才能更新數(shù)據(jù)
expandableListView.expandGroup(msg.arg1);
break;
}
notifyDataSetChanged(); //更新數(shù)據(jù)
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為相應(yīng)的父數(shù)據(jù)
if(groupArray!=null && groupArray.size()>0){
return false;
}else {
return true;
}
}
// //這個在空視圖時候必須重寫撵割,否則會失效故硅。
// @Override
// public boolean isEmpty() {
// //groupArray為相應(yīng)的父數(shù)據(jù)
// 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)){
//這個是在消息產(chǎn)生的評論
holder.llCommentProject.setVisibility(View.VISIBLE);
holder.ivReviewIcon.setVisibility(View.VISIBLE);
holder.tvReviewText.setVisibility(View.GONE);
}else if(type.equals(ProjectCommentActivity.COMMENT_TYPE)){
//這個是在項項目下產(chǎn)生的評論
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);
}
}
/*供外界更新數(shù)據(jù)的方法*/
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);
}
}
這里應(yīng)該注意一個坑(這個坑是在當(dāng)子固定一個非網(wǎng)絡(luò)請求的數(shù)據(jù)鬼廓,栗子:共有**條回復(fù))馏锡,如果不考慮父數(shù)據(jù)沒有時,會出現(xiàn)錯誤,所以我在getGroupCount和getChildCount中都做了相應(yīng)的判斷
怎么給子添加添加尾視圖
這里應(yīng)該重寫getChildType() ,getChildTypeCount(),在getChildType()中應(yīng)該判斷groupArray是否為空,否則會報錯,在個getChildTypeCount()中應(yīng)該return 3 ,不能return 2,這里不知道為什么錯誤?