在网上搜了非常长时间。没有找到合适的Android三级菜单。所以就自己动手写了一个,主要使用了BaseExpandableList来实现,通过三个布局文件来完毕相应的菜单项,详细实现请參照下图。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2FpNDYzODUwNzY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="300" height="600" alt="">

通过上面两图能够看出为三级菜单,每个菜单相应一个实体类,能够通过json解析数据载入进来,这里就只是多解释了。直接上源代码!

Activity实现类:

package com.zkq.activity;

import java.util.ArrayList;
import java.util.List; import com.example.teltest.R;
import com.zkq.model.FirstItem;
import com.zkq.model.SecondItem;
import com.zkq.model.ThirdItem; import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast; import com.zkq.adapter.*; public class MainActivity extends Activity {
private ExpandableListView listView;
private List<FirstItem> firstList;
private ExpandableListAdapter eAdpater; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
} private void initView() {
// TODO Auto-generated method stub
listView = (ExpandableListView) findViewById(R.id.expandList);
firstList = new ArrayList<FirstItem>();
} private void initData() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
FirstItem firstItem = new FirstItem();
firstItem.setId(i);
firstItem.setTitle("这是第" + i + "个");
List<SecondItem> seList = new ArrayList<SecondItem>();
for (int j = i; j < 10; j++) {
SecondItem secondItem = new SecondItem();
secondItem.setId(i);
secondItem.setTitle("子的第" + j * 78 + "条");
seList.add(secondItem);
List<ThirdItem> thirdList = new ArrayList<ThirdItem>();
for (int k = 0; k < j + 1; k++) {
ThirdItem thirdItem = new ThirdItem();
thirdItem.setId(k);
thirdItem.setImage("sss");
thirdItem.setName("张凯强" + k + j);
thirdItem.setTel("10086" + j + k);
thirdList.add(thirdItem);
}
secondItem.setThirdItems(thirdList);
}
firstItem.setSecondItems(seList);
firstList.add(firstItem);
}
eAdpater = new ExpandAdapter(MainActivity.this, firstList,stvClickEvent);
listView.setAdapter(eAdpater);
listView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View view,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this,
childPosition + "---ccc===" + groupPosition,
Toast.LENGTH_LONG).show();
return false;
}
});
} OnChildClickListener stvClickEvent = new OnChildClickListener() { @Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
String msg = "parent_id = " + groupPosition + " child_id = "
+ childPosition;
Toast.makeText(MainActivity.this, msg,
Toast.LENGTH_SHORT).show();
return false;
}
}; @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }

两个Adapter:

package com.zkq.adapter;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast; import com.example.teltest.R;
import com.zkq.model.FirstItem;
import com.zkq.model.SecondItem;
import com.zkq.util.Constants; public class ExpandAdapter extends BaseExpandableListAdapter { private Context context;
private List<FirstItem> firstList;
private OnChildClickListener stvClickEvent;//外部回调函数
// private List<SecondItem> secondList; public ExpandAdapter(Context context, List<FirstItem> firstList,OnChildClickListener stvClickEvent) {
// TODO Auto-generated constructor stub
this.context = context;
this.firstList = firstList;
this.stvClickEvent=stvClickEvent;
// this.secondList = secondList;
} @Override
public Object getChild(int groupPosition, int childPosition) {
return firstList.get(groupPosition).getSecondItems();
} @Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
} @Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ExpandableListView treeView = getExpandableListView(firstList.get(groupPosition).getSecondItems().size());
ExpandAdapter2 expandAdapter2 = new ExpandAdapter2(context, firstList,
childPosition, groupPosition,treeView,stvClickEvent);
//treeView.setOnChildClickListener(stvClickEvent);
treeView.setAdapter(expandAdapter2);
return treeView;
} public ExpandableListView getExpandableListView(int position) {
AbsListView.LayoutParams params = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, Constants.SECOND_ITEM_HEIGHT*position);
ExpandableListView superTreeView = new ExpandableListView(context);
superTreeView.setLayoutParams(params);
return superTreeView;
} @Override
public int getChildrenCount(int position) {
// TODO Auto-generated method stub
return 1;
} @Override
public Object getGroup(int position) {
// TODO Auto-generated method stub
return firstList.get(position);
} @Override
public int getGroupCount() {
// TODO Auto-generated method stub
return firstList.size();
} @Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
} @Override
public View getGroupView(int position, boolean flag, View convertView,
ViewGroup group) {
// TODO Auto-generated method stub
FirstHolder holder = null;
if (convertView == null) {
holder = new FirstHolder();
convertView = LayoutInflater.from(context).inflate(
R.layout.first_lay, null);
holder.first_arrow = (ImageView) convertView
.findViewById(R.id.first_arrow);
holder.first_image = (ImageView) convertView
.findViewById(R.id.first_image);
holder.first_title = (TextView) convertView
.findViewById(R.id.first_title);
convertView.setTag(holder);
} else {
holder = (FirstHolder) convertView.getTag();
}
FirstItem firstItem = firstList.get(position);
holder.first_title.setText(firstItem.getTitle());
return convertView;
} @Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
} @Override
public boolean isChildSelectable(int arg0, int arg1) {
// TODO Auto-generated method stub
return true;
}
} class FirstHolder {
TextView first_title;
ImageView first_image;
ImageView first_arrow;
} class SecondHolder {
TextView second_title;
ImageView second_arrow;
}
package com.zkq.adapter;

import java.util.List;

import com.example.teltest.R;
import com.zkq.activity.MainActivity;
import com.zkq.model.FirstItem;
import com.zkq.model.SecondItem;
import com.zkq.model.ThirdItem;
import com.zkq.util.Constants; import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.AbsListView;
import android.widget.Toast;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.ImageView;
import android.widget.TextView; public class ExpandAdapter2 extends BaseExpandableListAdapter { private Context context;
private List<FirstItem> firstList; private int cpostion;
private int gposition;
private ExpandableListView treeView;
private OnChildClickListener stvClickEvent;//外部回调函数
private int secondlength; // private List<SecondItem> secondList; public ExpandAdapter2(Context context, List<FirstItem> firstList,
int cposition, int gposition, ExpandableListView treeView,OnChildClickListener stvClickEvent) {
// TODO Auto-generated constructor stub
this.context = context;
this.firstList = firstList;
this.cpostion = cposition;
this.gposition = gposition;
this.treeView = treeView;
this.stvClickEvent=stvClickEvent;
// this.secondList = secondList;
} @Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return firstList.get(gposition).getSecondItems().get(groupPosition)
.getThirdItems().get(childPosition);
} public long getChildId(int groupPosition, int childPosition) {
return childPosition;
} @Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ThirdViewHolder childViewHolder = null;
if (convertView == null) {
childViewHolder = new ThirdViewHolder();
convertView = LayoutInflater.from(context).inflate(
R.layout.third_lay, null);
childViewHolder.third_name = (TextView) convertView
.findViewById(R.id.third_name);
childViewHolder.third_image = (ImageView) convertView
.findViewById(R.id.third_image);
childViewHolder.third_tel = (TextView) convertView
.findViewById(R.id.third_tel);
convertView.setTag(childViewHolder);
} else {
childViewHolder = (ThirdViewHolder) convertView.getTag();
}
ThirdItem thirdItem = firstList.get(gposition).getSecondItems()
.get(groupPosition).getThirdItems().get(childPosition);
childViewHolder.third_name.setText(thirdItem.getName());
childViewHolder.third_tel.setText(thirdItem.getTel());
//获取选中的内容
treeView.setOnChildClickListener(new OnChildClickListener() { @Override
public boolean onChildClick(ExpandableListView arg0, View arg1, int groupPosition,
int childPosition, long arg4) {
// TODO Auto-generated method stub
String msg = "-ppp--"+gposition+"parent_id = " + groupPosition + " child_id = "
+ childPosition;
Toast.makeText(context, msg,
Toast.LENGTH_SHORT).show();
return false;
}
});
return convertView;
} @Override
public int getChildrenCount(int position) {
// TODO Auto-generated method stub
return firstList.get(gposition).getSecondItems().get(position)
.getThirdItems().size();
} @Override
public Object getGroup(int groupPosition) {
return firstList.get(gposition).getSecondItems().get(groupPosition);
} @Override
public int getGroupCount() {
// TODO Auto-generated method stub
return firstList.get(gposition).getSecondItems().size();
} @Override
public long getGroupId(int position) {
// TODO Auto-generated method stub
return position;
} @Override
public View getGroupView(int position, boolean arg1, View convertView,
ViewGroup arg3) {
SecondHolder childViewHolder = null;
if (convertView == null) {
childViewHolder = new SecondHolder();
convertView = LayoutInflater.from(context).inflate(
R.layout.second_lay, null);
childViewHolder.second_title = (TextView) convertView
.findViewById(R.id.second_title);
convertView.setTag(childViewHolder);
} else {
childViewHolder = (SecondHolder) convertView.getTag();
}
SecondItem secondItem = firstList.get(gposition).getSecondItems()
.get(position);
childViewHolder.second_title.setText(secondItem.getTitle());
/***
* 展开监听
*/
treeView.setOnGroupExpandListener(new OnGroupExpandListener() {
@Override
public void onGroupExpand(int position) {
// TODO Auto-generated method stub if (treeView.getChildCount() == firstList.get(gposition)
.getSecondItems().size()) {
if (secondlength > 0) {
secondlength += firstList.get(gposition)
.getSecondItems().get(position).getThirdItems()
.size()
* Constants.THIRD_ITEM_HEIGHT;
} else {
secondlength += firstList.get(gposition)
.getSecondItems().size()
* Constants.SECOND_ITEM_HEIGHT
+ firstList.get(gposition).getSecondItems()
.get(position).getThirdItems().size()
* Constants.THIRD_ITEM_HEIGHT;
}
} else {
secondlength += firstList.get(gposition).getSecondItems()
.get(position).getThirdItems().size()
* Constants.THIRD_ITEM_HEIGHT;
}
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, secondlength);
treeView.setLayoutParams(lp);
}
});
// treeView.setOnGroupClickListener(new OnGroupClickListener() {
// @Override
// public boolean onGroupClick(ExpandableListView arg0, View arg1,
// int position, long arg3) {
// // TODO Auto-generated method stub
// return false;
// }
// });
/***
* 缩放监听
*/
treeView.setOnGroupCollapseListener(new OnGroupCollapseListener() { @Override
public void onGroupCollapse(int position) {
// TODO Auto-generated method stub secondlength -= firstList.get(gposition).getSecondItems()
.get(position).getThirdItems().size()
* Constants.THIRD_ITEM_HEIGHT;
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, secondlength);
treeView.setLayoutParams(lp);
}
});
return convertView;
} @Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
} @Override
public boolean isChildSelectable(int arg0, int arg1) {
// TODO Auto-generated method stub
return true;
} class ThirdViewHolder {
ImageView third_image;
TextView third_name;
TextView third_tel;
} class SecondViewHolder {
TextView second_title;
ImageView second_arrow;
} }

以下时三个实体类:

package com.zkq.model;

import java.util.List;

public class FirstItem {
private int id;
private String title;
private String image;
private List<SecondItem> secondItems; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getImage() {
return image;
} public void setImage(String image) {
this.image = image;
} public List<SecondItem> getSecondItems() {
return secondItems;
} public void setSecondItems(List<SecondItem> secondItems) {
this.secondItems = secondItems;
} }
package com.zkq.model;

import java.util.List;

public class SecondItem {
private int id;
private String title;
private List<ThirdItem> thirdItems; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public List<ThirdItem> getThirdItems() {
return thirdItems;
} public void setThirdItems(List<ThirdItem> thirdItems) {
this.thirdItems = thirdItems;
} }
package com.zkq.model;

public class ThirdItem {
private int id;
private String name;
private String tel;
private String image;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
} }

常量

package com.zkq.util;

public class Constants {
/**
* 第二级和第三级菜单的高度
*/
public static final int SECOND_ITEM_HEIGHT=115;
public static final int THIRD_ITEM_HEIGHT=120;
}

android 三级菜单 BaseExpandableListAdapter的更多相关文章

  1. Android自己定义控件:老版优酷的三级菜单(效果图 + Demo)

    效果图: 制作思路: 1.先分析这个效果,事实上能够理解为把三级菜单分成level1,level2,level3,level1是始终显示的. 点击level1后,level2会出现:点击level2后 ...

  2. Android--简单的三级菜单

      关于这个菜单应该在很多播放器应用里面可以看见,直接先上两张效果图吧,一张是该Demo的效果图,一张是优酷手机客户端的效果图.                                     ...

  3. python学习笔记(字符串操作、字典操作、三级菜单实例)

    字符串操作 name = "alex" print(name.capitalize()) #首字母大写 name = "my name is alex" pri ...

  4. css三级菜单效果

    一个简单实用的css三级菜单效果 <!doctype html> <html> <head> <meta charset="utf-8"& ...

  5. python成长之路-----day1-----作业(登录程序和三级菜单)

    作业: 作业1:用户登录 1)程序说明: a.用户输入密码验证成功然后打印欢迎信息 b.如果密码错误,用户登录失败,提示用户,密码错误 c.用户输入密码错误3次,则用户锁定 d.当用户多次输入不存在的 ...

  6. Python之路 day2 字典练习题之 三级菜单

    #Author:ersa ''' 程序: 三级菜单 要求: 打印省.市.县三级菜单 可返回上一级 可随时退出程序 ''' menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{ ...

  7. python3 三级菜单

    python版本3.5 功能: 1.程序执行显示一级菜单,输入内容进入二级菜单: 2.进入二级菜单后,输入二级菜单内容,进入三级菜单:输入b返回一级菜单: 3.进入三级菜单后,输入b返回二级菜单. # ...

  8. 用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示。

    用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示. 原因:在为一个元素绑定hover事件之后,用户把光标移入元素 ...

  9. Android侧滑菜单代码实现

    前两天学习了hyman老师讲的Android侧滑菜单的实现,经过自己的整理分享出来给大家学习一下 现在很多APP都有菜单侧滑的功能,本篇文章主要讲解使用自定义的HorizontalScrollView ...

随机推荐

  1. [Backbone.js]如何处理Model里面嵌入的Collection?

    写了近半个月的backbone.js代码,从一开始的todo到现在做仿微信的网页聊天,其中最大的困惑就在于如何处理比较复杂的Model,其内嵌了一个或者多个Collections. 假设我们有一个Pe ...

  2. [转]Hibernate中property-ref的应用,常用来解决遗留数据库One To Many关系

    [转]Hibernate中property-ref的使用,常用来解决遗留数据库One To Many关系 1.如表Class(ClassID,Class_No,ClassName)与Student(S ...

  3. 浅析document.createDocumentFragment()与js效率

    对于循环批量操作页面的DOM有很大帮助!利用文档碎片处理,然后一次性append,并且使用原生的javascript语句操作 document.createDocumentFragment()说白了就 ...

  4. Java - 字符串和Unicode互转 - 解析小米pm.min.js

    小米JS地址: http://p.www.xiaomi.com/zt/20130313/huodong/pm.min.js 上面这个JS是小米抢手机页面的代码.和抢手机有直接关联.. 虽然我3次都没抢 ...

  5. linux学习之(四)-用户、组的操作,给文件文件夹设置组,更改目录权限、文件权限

    命令帮助查看: man 命令(查看一个命令的详细帮助信息) 例:man useradd 或者用  -h   格式   命令 -h(查看一个命令的简要帮助) 例:useradd -h 用户: 在user ...

  6. vim简单命令教程-firstblood

    你想以最快的速度学习人类史上最好的文本编辑器VIM吗?你先得懂得如何在VIM幸存下来,然后一点一点地学习各种戏法. Vim the Six Billion Dollar editor Better, ...

  7. 自动添加注释—VS2010宏的使用

    在敲代码的过程中类和函数都需要进行注释,但总是一遍一遍的复制粘贴觉得很是麻烦,终于找到了一个不错的解决方法:使用宏. 所谓宏,就是一些命令组织在一起,作为一个单独命令完成一个特定任务.在日常的办公环境 ...

  8. sql server操作2:查询数据库语句大全【转】

    注:以下操作均建立在上篇文章sql Server操作1的数据基础之上 一.实验目的 熟悉SQL语句的基本使用方法,学习如何编写SQL语句来实现查询 二.实验内容和要求 使用SQL查询分析器查询数据,练 ...

  9. Cocos2d-x官方在线视频-Cocos2d-x3.2《2048》手游开发揭秘

    Cocoachina 官方在线视频 http://cn.cocos2d-x.org/tutorial/lists?id=58 一.游戏介绍 2048游戏是一款风靡全球的休闲类游戏,通过控制4X4范围内 ...

  10. java于23设计模式

    详情请参阅23设计模式 版权声明:本文博主原创文章,博客,未经同意不得转载.