效果图:

                                     

说明:刚开始使用这个控件我花费了3天的时间,但是一直都没有达到预期的效果,要么就是直接全部不显示,要么就是数据累加了或者点击一级标题两三次才获取到子项数据(是子类父类没有相关联,导致适配器在初始化数据的时候导致数据混乱)

步骤:一.布局的安排

1.activity_menumanager.xml(主布局)代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MenuManager"
android:background="#EDEFF2"
>
<EditText
android:textSize="@dimen/sp_14"
android:layout_margin="@dimen/dp_10"
android:gravity="center"
android:hint="搜索"
android:layout_width="match_parent"
android:layout_height="50dp" />
<ExpandableListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ExpandableListView>
</LinearLayout>

 2.parent_item.xml(一级标题的布局)  代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/parentlist"
android:paddingBottom="8dp"
android:paddingLeft="32dp"
android:paddingTop="8dp"
android:textColor="@android:color/black"
android:textSize="18sp"
android:text="我是大哥大"
/> </RelativeLayout> 3.child_item.xml(二级目录的布局) 代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:id="@+id/childlist"
android:layout_height="wrap_content"
> <RelativeLayout
android:layout_marginTop="@dimen/dp_10"
android:background="#EDEFF2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/list_image_search"
android:padding="5dp"
android:layout_margin="10dp"
android:layout_alignParentLeft="true"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/dream"
/>
<TextView
android:id="@+id/classify"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/list_image_search"
android:text="系统设置"
android:textColor="#000"
android:textSize="14dp"
android:layout_marginTop="14dp"
/>
<TextView
android:id="@+id/link"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/classify"
android:layout_toRightOf="@+id/list_image_search"
android:text="Basefunction\/index"
/>
<TextView
android:id="@+id/color"
android:padding="15dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="black"
/>
</RelativeLayout>
</LinearLayout>

步骤二,JSON实体类

1.parent_item所对应的JSON实体类 代码:

package com.smartgentechnology.entity;

import java.util.List;

public class ParentExpand {

    /**
* info : access
* data : [{"id":"1","pid":"0","name":"系统设置","mca":"Basefunction/index","ico":" icon-cog","color":"black","order_number":"1"},{"id":"15","pid":"0","name":"报表模块","mca":"Ormodule/index","ico":"icon-th-large","color":"","order_number":"2"},{"id":"17","pid":"0","name":"返修模块","mca":"Business/index","ico":"icon-th-large","color":"","order_number":"3"}]
*/ private String info;
private List<DataBean> data; public String getInfo() {
return info;
} public void setInfo(String info) {
this.info = info;
} public List<DataBean> getData() {
return data;
} public void setData(List<DataBean> data) {
this.data = data;
} public static class DataBean {
/**
* id : 1
* pid : 0
* name : 系统设置
* mca : Basefunction/index
* ico : icon-cog
* color : black
* order_number : 1
*/ public DataBean(String name,String id){
this.name=name;
this.id = id;
}
private String id;
private String pid;
private String name;
private String mca;
private String ico;
private String color;
private String order_number;
        private List<ItemBean.DataBean> list_child = new ArrayList<ItemBean.DataBean>();
public List<ItemBean.DataBean> getList_child() {
return list_child;
} public void setList_child(List<ItemBean.DataBean> list_child) {
this.list_child = list_child;
}//致使父类和子类相关联,致使数据不会混乱排序
        public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getPid() {
return pid;
} public void setPid(String pid) {
this.pid = pid;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getMca() {
return mca;
} public void setMca(String mca) {
this.mca = mca;
} public String getIco() {
return ico;
} public void setIco(String ico) {
this.ico = ico;
} public String getColor() {
return color;
} public void setColor(String color) {
this.color = color;
} public String getOrder_number() {
return order_number;
} public void setOrder_number(String order_number) {
this.order_number = order_number;
}
}
}

2.childitem所对应的JSON实体类 代码(parent和child的实体类是一样的,但是child装载的数据是根据parent的id来进行解析的):

package com.smartgentechnology.entity;

import java.util.List;

public class ItemBean {

    /**
* info : access
* data : [{"id":"1","pid":"0","name":"系统设置","mca":"Basefunction/index","ico":" icon-cog","color":"black","order_number":"1"},{"id":"15","pid":"0","name":"报表模块","mca":"Ormodule/index","ico":"icon-th-large","color":"","order_number":"2"},{"id":"17","pid":"0","name":"返修模块","mca":"Business/index","ico":"icon-th-large","color":"","order_number":"3"}]
*/ private String info;
private List<DataBean> data; public String getInfo() {
return info;
} public void setInfo(String info) {
this.info = info;
} public List<DataBean> getData() {
return data;
} public void setData(List<DataBean> data) {
this.data = data;
} public static class DataBean {
/**
* id : 1
* pid : 0
* name : 系统设置
* mca : Basefunction/index
* ico : icon-cog
* color : black
* order_number : 1
*/ public DataBean(String name,String mca,String color){
this.name=name;
this.mca =mca;
this.color = color; }
private String id;
private String pid;
private String name;
private String mca;
private String ico;
private String color;
private String order_number; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getPid() {
return pid;
} public void setPid(String pid) {
this.pid = pid;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getMca() {
return mca;
} public void setMca(String mca) {
this.mca = mca;
} public String getIco() {
return ico;
} public void setIco(String ico) {
this.ico = ico;
} public String getColor() {
return color;
} public void setColor(String color) {
this.color = color;
} public String getOrder_number() {
return order_number;
} public void setOrder_number(String order_number) {
this.order_number = order_number;
}
}
}

步骤三,menumanager活动的JSON数据解析(parent和child的数据的解析,然后传输给ExpandListViewAdapter进行数据的展示):

package com.smartgentechnology;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ExpandableListView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast; import com.google.gson.Gson; import com.smartgentechnology.adapter.ExpandableAdapter; import com.smartgentechnology.entity.ItemBean;
import com.smartgentechnology.entity.ParentExpand;
import com.smartgentechnology.post.GetHttp;
import com.syd.oden.circleprogressdialog.core.CircleProgressDialog; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response; public class MenuManager extends AppCompatActivity {
private static final String TAG = "tag";
// 准备数据
private List<ParentExpand.DataBean> groupString;//新建一个数据接受器
private ExpandableListView expandableListView;//控件
private String address;
Context context; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menumanager);
address = getString(R.string.menu_manager);
initDatas();
}
private void initDatas() {
groupString = new ArrayList<ParentExpand.DataBean>();
new Thread(new Runnable() {
@Override
public void run() {
GetHttp.getOkHttpRequest(address, "10", "0", "0", new Callback() {//get网络请求给一级标题
@Override
public void onFailure(Call call, IOException e) {
Log.i("expanding false", "" + e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
String result = response.body().string();
Log.i("wiqu", "f" + result); parseJsonWith(result);
response.body().close();//关闭网络请求 }
});
}
}).start();
} private void parseJsonWith(String result) {//解析数据传入界面(一级标题)
ParentExpand parentExpand = new Gson().fromJson(result, ParentExpand.class);
List<ParentExpand.DataBean> dataBeans = parentExpand.getData();
for (ParentExpand.DataBean dataBean : dataBeans) {
ParentExpand.DataBean mData = new ParentExpand.DataBean(dataBean.getName(), dataBean.getId());
//String groupid = dataBean.getId();
mData.setList_child(sendSecond(groupid));
groupString.add(mData);
Log.i("kukuku", "" + groupString);
}
inii();
} private void inii() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
expandableListView = findViewById(R.id.list);
ExpandableAdapter adapter = new ExpandableAdapter(MenuManager.this, groupString);
expandableListView.setAdapter(adapter); expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
ItemBean.DataBean dataBean = groupString.get(groupPosition).getList_child().get(childPosition);
Toast.makeText(MenuManager.this, dataBean.getName(), Toast.LENGTH_SHORT).show();
return false;
}
}); }
});
} private List<ItemBean.DataBean> sendSecond(String id) { final List<ItemBean.DataBean> Data = new ArrayList<>(); GetHttp.getOkHttpRequest(address, "10", "0", id, new Callback() {//Get网络请求
@Override
public void onFailure(Call call, IOException e) {
} @Override
public void onResponse(Call call, Response response) throws IOException {//JSON数据解析
String responseData = response.body().string();
Log.i("wiqu", "z" + responseData);
ItemBean itemBean = new Gson().fromJson(responseData, ItemBean.class);
List<ItemBean.DataBean> dataBeans = itemBean.getData();
for (ItemBean.DataBean dataBean : dataBeans) {
ItemBean.DataBean mData = new ItemBean.DataBean(dataBean.getName(), dataBean.getMca(), dataBean.getColor());
Data.add(mData);
}
response.body().close();//关闭数据连接
}
});
return Data;//返回数据
}
2.ExpandableAdapter适配器的编写,继承自BaseExpandableListAdapter,重写它的方法
package com.smartgentechnology.adapter;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.TextView; import com.smartgentechnology.MainActivity;
import com.smartgentechnology.R;
import com.smartgentechnology.entity.ItemBean;
import com.smartgentechnology.entity.ParentExpand; import java.util.List;
import java.util.Map; public class ExpandableAdapter extends BaseExpandableListAdapter {
// public String address = "http://192.168.30.89/OR/index.php/Navjson/dis/";
List<ParentExpand.DataBean> groupString;//父级列表数据
// List<ItemBean.DataBean> childString;//子级列表数据,装在子项数据
Context context;//应用上下文 public ExpandableAdapter(Context context, List<ParentExpand.DataBean> groupString) {
this.context = context;
this.groupString = groupString;
Log.i("shujua", "" + groupString);
} @Override
public int getGroupCount() {//组的个数
Log.i("groupcount", " " + groupString.size());
return groupString.size();
} /*
* 取得指定分组的子元素数
*/
@Override
public int getChildrenCount(int groupPosition) {
Log.i("fenzu", " " + groupString.size());
return groupString.get(groupPosition).getList_child().size();
} @Override
public Object getGroup(int groupPosition) {
Log.i("getGruop", " " + groupString.size());
return groupString.get(groupPosition);
} @Override
public Object getChild(int groupPosition, int childPosition) {
//Log.i("mingzia",""+childString.get(groupPosition).get(childPosition).getName());
//我们这里返回一下每个item的名称,以便单击item时显示
// = childString.get(childPosition);
return groupString.get(groupPosition).getList_child().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 View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupViewHolder groupViewHolder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.parent_item, null);
groupViewHolder = new GroupViewHolder();
groupViewHolder.tvTitle = (TextView) convertView.findViewById(R.id.parentlist);
convertView.setTag(groupViewHolder);
} else {
groupViewHolder = (GroupViewHolder) convertView.getTag();
} groupViewHolder.tvTitle.setText(groupString.get(groupPosition).getName());
Log.i("didijiuwo", "" + groupString.get(groupPosition).getName()); return convertView; } @Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildViewHolder childViewHolder = null;
if (childViewHolder == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.childitem, null);
childViewHolder = new ChildViewHolder();
childViewHolder.tvTitle = (TextView) convertView.findViewById(R.id.classify);
childViewHolder.tvContent = (TextView) convertView.findViewById(R.id.link);
childViewHolder.tvColor = (TextView) convertView.findViewById(R.id.color);
convertView.setTag(childViewHolder);
} else {
childViewHolder = (ChildViewHolder) convertView.getTag();
}
Log.i("teammess", groupPosition + "分割" + childPosition);
childViewHolder.tvTitle.setText(groupString.get(groupPosition).getList_child().get(childPosition).getName());
childViewHolder.tvContent.setText(groupString.get(groupPosition).getList_child().get(childPosition).getMca());
childViewHolder.tvColor.setText(groupString.get(groupPosition).getList_child().get(childPosition).getColor());
Log.i("qisil", " " + groupString.get(groupPosition).getList_child().get(childPosition).getName());
return convertView;
} @Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
} private class GroupViewHolder {
TextView tvTitle; } private class ChildViewHolder {
TextView tvTitle;
TextView tvContent;
TextView tvColor;
} } 补充添加:
ExpandableListView的长按事件获取父项,子项详细id
expandableListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) { // long packedPos = ((ExpandableListView)parent).getExpandableListPosition(position);//这些都是普通版的长按操作
// int groupPosition=
// ExpandableListView.getPackedPositionGroup(packedPos);
// int childPosition = ExpandableListView.getPackedPositionChild(packedPos);
// Log.i("groupPosition----",""+groupPosition);
// Log.i("childPosition----",""+childPosition);
// if(childPosition == -1){//长按的是父项
// //这里做关于父项的相关操作......
// Toast.makeText(MenuManager.this,"parent",Toast.LENGTH_SHORT).show();
// }
// else {//长按的是子项
// //这里做关于子项的相关操作.......
// ItemBean.DataBean dataBean = groupString.get(groupPosition).getList_child().get(childPosition);
// Toast.makeText(MenuManager.this,dataBean.getName(),Toast.LENGTH_SHORT).show();
// }
// return true;
//加强版的长按操作 (本人亲自操刀,不足之处望谅解!)
long packedPos = ((ExpandableListView) parent).getExpandableListPosition(position);
final int groupPosition =
ExpandableListView.getPackedPositionGroup(packedPos);
final int childPosition = ExpandableListView.getPackedPositionChild(packedPos);
final String[] item = {"修改", "删除"};
final AlertDialog.Builder builder = new AlertDialog.Builder(MenuManager.this);
builder.setTitle("请选择"); builder.setItems(item, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { if (item[which].equals("删除")) {
if (childPosition == -1) {//长按的是父项
                                      //这里做关于父项的相关操作......
                                        ParentExpand.DataBean FdataBean = groupString.get(groupPosition);
postVolley(FdataBean.getId());
requestQueue.start();
//Toast.makeText(MenuManager.this, FdataBean.getId(), Toast.LENGTH_SHORT).show();
} else {//子项
ItemBean.DataBean dataBean = groupString.get(groupPosition).getList_child().get(childPosition);
postVolley(dataBean.getId());
requestQueue.start();
// Toast.makeText(MenuManager.this, dataBean.getId(), Toast.LENGTH_SHORT).show();
Log.i("kanbuqing",""+dataBean.getId());
} }
}
});
builder.setNegativeButton("取消", null);
builder.show();
// }
return true;
}
}); }
});
} private void postVolley(final String id) {//使用Volley发送网络请求
urls = getString(R.string.menu_del);
StringRequest request = new StringRequest(com.android.volley.Request.Method.POST, urls, new com.android.volley.Response.Listener<String>() {
@Override
public void onResponse(String response) {
//Toast.makeText(MenuManager.this,response,Toast.LENGTH_SHORT).show();
parseNum(response);
}
}, new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MenuManager.this,"网络加载失败。。。",Toast.LENGTH_SHORT).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map = new HashMap<>();
map.put("id",id);
return map;
}
};
request.setTag("menu");
requestQueue.add(request);
} private void parseNum(String response) {
AddClass addClass = new Gson().fromJson(response,AddClass.class);
String info = addClass.getInfo();
Toast.makeText(MenuManager.this,info,Toast.LENGTH_SHORT).show();
}
总结:也没什么好讲的,主要还是数据一定要相关联,不然多层JSON数据解析完毕初始化时数据混乱,以及感谢超哥的帮助和参考文献:
参考文献地址:https://www.cnblogs.com/yangxiu/p/5931367.html
这个是一个简单的ExpandableListView的例子 完毕!

ExpandableListView解析JSON数据的更多相关文章

  1. 使用Python解析JSON数据的基本方法

    这篇文章主要介绍了使用Python解析JSON数据的基本方法,是Python入门学习中的基础知识,需要的朋友可以参考下:     ----------------------------------- ...

  2. 使用jQuery解析JSON数据

    我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法. 上例中得到的JSON数据如下,是一个嵌套JSON: {"comments&quo ...

  3. [转]javascript eval函数解析json数据时为什加上圆括号eval("("+data+")")

    javascript eval函数解析json数据时为什么 加上圆括号?为什么要 eval这里要添加 “("("+data+")");//”呢?   原因在于: ...

  4. 用jquery解析JSON数据的方法以及字符串转换成json的3种方法

    用jquery解析JSON数据的方法,作为jquery异步请求的传输对象,jquery请求后返回的结果是 json对象,这里考虑的都是服务器返回JSON形式的字符串的形式,对于利用JSONObject ...

  5. Android中使用Gson解析JSON数据的两种方法

    Json是一种类似于XML的通用数据交换格式,具有比XML更高的传输效率;本文将介绍两种方法解析JSON数据,需要的朋友可以参考下   Json是一种类似于XML的通用数据交换格式,具有比XML更高的 ...

  6. fastjson生成和解析json数据,序列化和反序列化数据

    本文讲解2点: 1. fastjson生成和解析json数据 (举例:4种常用类型:JavaBean,List<JavaBean>,List<String>,List<M ...

  7. 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来的Json数据写入数据库表中

    摘自:http://blog.csdn.net/mazhaojuan/article/details/8592015 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来 ...

  8. JSONKit解析json数据

    先将第三方文件拖进工程 JSONKit.h和JSONKit.m 然后设置在ARC工程中添加MRC文件,如下图所示 #import "ViewController.h" #impor ...

  9. Android网络之数据解析----使用Google Gson解析Json数据

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

随机推荐

  1. Elasticsearch-6.7.0系列(一)9200端口 .tar.gz版本centos7环境--下载安装运行

    https://www.elastic.co/guide/index.html(推荐)        ES官方英文原版文档,一般会更新到最新版本 https://www.elastic.co/cn/d ...

  2. WinSDK-键盘消息

    一 参考url http://www.cnblogs.com/5iedu/p/4656178.html http://blog.csdn.net/yiyefangzhou24/article/deta ...

  3. shell中使用类似Python的参数处理

    params=$* for param in ${params} do name=$() value=$() if [[ "$name" = "run_type" ...

  4. Promise的一点感悟~

    在什么大环境下? 今天要讨论的Promise,是js的同步|异步任务的概念下出来的 什么是同步?什么是异步? 我的理解: 一件事情Q 分三部分:Q1 ,  Q2  ,  Q3 同步方式完成: Q1 - ...

  5. 团队第九次 # scrum meeting

    github 本此会议项目由PM召开,召开时间为4-14日晚上9点,以大家在群里讨论为主 召开时长10分钟 任务表格 袁勤 负责协调前后端 https://github.com/buaa-2016/p ...

  6. Redis Sentinel实现高可用配置

    一般情况下yum安装redis的启动目录在:”/usr/sbin” :配置目录在”/etc/redis/”在其目录下会有默认的redis.conf和redis-sentinel.conf redis高 ...

  7. Oracle的SQL优化思路

    个人总结SQL脚本优化,大体如下: (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表dir ...

  8. (7/24) 插件配置之html文件的打包发布

    从前面几节到现在,其实我们的项目结构是有问题的,因为我们直接把index.html文件放到了dist文件夹目录下.这肯定是不正确的,应该放到我们src目录下,然后打包到dist目录下,前面为了学习,才 ...

  9. SSM的搭建

    1.首先是工具的准备. eclipse jdk1.7 maven 3.5.4 tomcat 8.5 2.工具环境的搭建 首先,new建立选择maven project工程,勾选simple proje ...

  10. django 加载css、js和图片记载不上

    在django的setting里加以下配置 STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), 'Djago/static/',)