在网上搜了非常长时间。没有找到合适的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. winform制作自定义控件(入门)

    原文链接:http://blog.csdn.net/bychentufeiyang/article/details/7081402   与原文基本一致,只是例子变成VS2012环境,语言采用博主常用的 ...

  2. 三篇编译libcurl,附下载 good

    http://download.csdn.net/detail/flyliying/2982867 http://download.csdn.net/detail/wojiushiwo987/9113 ...

  3. WPF 路径和几何图形

    原文 http://www.cnblogs.com/laoyang999/archive/2012/11/23/2783734.html 继承自Shap类的形状有:Rectangle.Ellipse. ...

  4. How to change a product dropdown attribute to a multiselect in Magento

    First, update the attribute input type to multiselect: UPDATE eav_attribute SET entity_type_id ', at ...

  5. B/S状态(同步)AJAX技术(异步)

    同步(Synchronization).它是最常见的click-refresh状态,或提交一个表单,然后整个页面被刷新. 异步(Asynchrony).当前非常热的AJAX就是典型样例,提交请求返回对 ...

  6. JavaScript创建对象的模式

    /** * Created by W_YH on 2016/3/14. */ /* 对象的创建方式 */ //------->第一种创建方式------创建Object的实例 var perso ...

  7. 《Oracle Applications DBA 基础》- 9 - Concurrent Processing[Z]

    <Oracle Applications DBA 基础>- 9 - Concurrent Processing================================== 参考资料 ...

  8. C# - 重定义一个接口的实现

    using System;using System.Collections.Generic;using System.Text; namespace MyTester{    public inter ...

  9. Devpexpress 打印预览问题

    devexpress 12 之前报表打印: XtraReports rp1 = new XtraReports(); rp1.ShowPreview(): 即可预览报表: devexpress 13 ...

  10. C语言实现有序二叉树(1)

    在cpp中使用的C语言 头文件 /* 有序二叉树 BsTree */ #ifndef _BT_H #define _BT_H /*节点*/ typedef struct BsTreeNode { in ...