在网上搜了非常长时间。没有找到合适的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. 使用plist的好处

    首先:帮助节省内存.OpenGL ES纹理要求宽和高都是2的n次幂的倍数.我们可以考虑将小的图片拼大图片,然后统一加载.  其次:提高渲染速度.OpenGL ES要求切换的纹理越少越好,将图片拼成大图 ...

  2. node.js 入门教程(beginnder guide

    非常好的教程: node入门: JavaScript与Node.js JavaScript与你 简短申明 服务器端JavaScript “Hello World” 一个完整的基于Node.js的web ...

  3. POJ——放苹果

    4:放苹果 查看 提交 统计 提问 总时间限制:  1000ms  内存限制:  65536kB 描述 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示) ...

  4. mit java open course assignment #4

    package come; public class Library { // Add the missing implementation to this class String realLoca ...

  5. HDU Today(dijskra)

    HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. Eclipse和PyDev搭建python开发环境

                   Eclipse和PyDev搭建python开发环境 1.1整体目标 本文档作为python学习者的新手教程,通过本教程能够了解python用途.语法.在实际工作中的应 ...

  7. 【插队问题-线段树-思维巧妙】【poj2828】Buy Tickets

    可耻的看了题解 巧妙的思维 逆序插入,pos 代表的意义为前面要有pos个空格才OK: 证明:仔细思考一下就觉得是正确的,但是要想到这种方式还是要很聪明,空格是前面的几个数字所形成的,所以要特地留出来 ...

  8. 兼容 CommonJS 和 CommonJS-like规范(1~38)

    CommonJS是服务器端模块的规范,Node.js采用了这个规范. 根据CommonJS规范,一个单独的文件就是一个模块.每一个模块都是一个单独的作用域,也就是说,在该模块内部定义的变量,无法被其他 ...

  9. JavaScript 字符串实用常用操作

    字符串截取1. substring()xString.substring(start,end)substring()是最常用到的字符串截取方法,它可以接收两个参数(参数不能为负值),分别是要截取的开始 ...

  10. nutch2.3中nutch-site.xml设置说明

    nutch-site.xml是运行nutch的非必须设置文件,也就是说你不设置,nutch照样可以运行. nutch-site.xml是nutch-default.xml的一个客制化文件. nutch ...