二级横向菜单实现——ListView
实现类似于大众点评客户端的横向listview二级列表

这种横向的listview二级列表在手机软件上还不太常见,但是使用过平板的都应该知道,在平板上市比较常见的。可能是因为平板屏幕比较大,而且也能展现更多的内容。
下面来看一下我的实现步骤。
首先自定义一个listview,代码如下:
- public class MyListView extends ListView implements Runnable {
- private float mLastDownY = 0f;
- private int mDistance = 0;
- private int mStep = 10;
- private boolean mPositive = false;
- public MyListView (Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public MyListView (Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- public MyListView (Context context) {
- super(context);
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- if (mLastDownY == 0f && mDistance == 0) {
- mLastDownY = event.getY();
- return true;
- }
- break;
- case MotionEvent.ACTION_CANCEL:
- break;
- case MotionEvent.ACTION_UP:
- if (mDistance != 0) {
- mStep = 1;
- mPositive = (mDistance >= 0);
- this.post(this);
- return true;
- }
- mLastDownY = 0f;
- mDistance = 0;
- break;
- case MotionEvent.ACTION_MOVE:
- if (mLastDownY != 0f) {
- mDistance = (int) (mLastDownY - event.getY());
- if ((mDistance < 0 && getFirstVisiblePosition() == 0 && getChildAt(0).getTop() == 0) || (mDistance > 0 && getLastVisiblePosition() == getCount() - 1)) {
- mDistance /= 2;
- scrollTo(0, mDistance);
- return true;
- }
- }
- mDistance = 0;
- break;
- }
- return super.onTouchEvent(event);
- }
- public void run() {
- mDistance += mDistance > 0 ? -mStep : mStep;
- scrollTo(0, mDistance);
- if ((mPositive && mDistance <= 0) || (!mPositive && mDistance >= 0)) {
- scrollTo(0, 0);
- mDistance = 0;
- mLastDownY = 0f;
- return;
- }
- mStep += 1;
- this.postDelayed(this, 10);
- }
- }
然后看一下xml的布局:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- <com.example.multilistview.MyListView
- android:id="@+id/listView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:choiceMode="singleChoice"
- android:scrollbars="none"
- android:divider="@drawable/listitem_divide"
- android:listSelector="#00000000"
- android:background="#e4e3de"
- >
- </com.example.multilistview.MyListView>
- <com.example.multilistview.MyListView
- android:id="@+id/subListView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:background="#e4e3de"
- >
- </com.example.multilistview.MyListView>
- </LinearLayout>
两个自定义的listview 横向布局,然后是父listview的适配器
- public class MyAdapter extends BaseAdapter {
- Context context;
- LayoutInflater inflater;
- String [] foods;
- int last_item;
- int [] images;
- private int selectedPosition = -1;
- public MyAdapter(Context context,String [] foods,int[] images){
- this.context = context;
- this.foods = foods;
- this.images = images;
- inflater=LayoutInflater.from(context);
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return foods.length;
- }
- @Override
- public Object getItem(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- ViewHolder holder = null;
- if(convertView==null){
- convertView = inflater.inflate(R.layout.mylist_item, null);
- holder = new ViewHolder();
- holder.textView =(TextView)convertView.findViewById(R.id.textview);
- holder.imageView =(ImageView)convertView.findViewById(R.id.imageview);
- holder.layout=(LinearLayout)convertView.findViewById(R.id.colorlayout);
- convertView.setTag(holder);
- }
- else{
- holder=(ViewHolder)convertView.getTag();
- }
- // 设置选中效果
- if(selectedPosition == position)
- {
- holder.textView.setTextColor(Color.BLUE);
- holder.layout.setBackgroundColor(Color.LTGRAY);
- } else {
- holder.textView.setTextColor(Color.WHITE);
- holder.layout.setBackgroundColor(Color.TRANSPARENT);
- }
- holder.textView.setText(foods[position]);
- holder.textView.setTextColor(Color.BLACK);
- holder.imageView.setBackgroundResource(images[position]);
- return convertView;
- }
- public static class ViewHolder{
- public TextView textView;
- public ImageView imageView;
- public LinearLayout layout;
- }
- public void setSelectedPosition(int position) {
- selectedPosition = position;
- }
- }
对应的 item布局:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/colorlayout"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- <ImageView
- android:id="@+id/imageview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="10dip"
- android:layout_marginTop="5dip"
- />
- <TextView
- android:id="@+id/textview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text=""
- android:textSize="16dip"
- android:layout_marginTop="8dip"
- android:layout_marginLeft="8dip"
- android:layout_marginBottom="8dip"/>
- <!-- android:background="@drawable/selector" 自定义listview 样式-->
- </LinearLayout>
然后是子适配器代码:
- public class SubAdapter extends BaseAdapter {
- Context context;
- LayoutInflater layoutInflater;
- String[][] cities;
- public int foodpoition;
- public SubAdapter(Context context, String[][] cities,int position) {
- this.context = context;
- this.cities = cities;
- layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- this.foodpoition = position;
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return cities.length;
- }
- @Override
- public Object getItem(int position) {
- // TODO Auto-generated method stub
- return getItem(position);
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- ViewHolder viewHolder = null;
- final int location=position;
- if (convertView == null) {
- convertView = layoutInflater.inflate(R.layout.sublist_item, null);
- viewHolder = new ViewHolder();
- viewHolder.textView = (TextView) convertView
- .findViewById(R.id.textview1);
- convertView.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) convertView.getTag();
- }
- viewHolder.textView.setText(cities[foodpoition][position]);
- viewHolder.textView.setTextColor(Color.BLACK);
- return convertView;
- }
- public static class ViewHolder {
- public TextView textView;
- }
- }
对应的xml布局:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- >
- <TextView
- android:id="@+id/textview1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="aaaaa"
- android:textSize="16dip"
- android:layout_marginTop="10dip"
- android:layout_marginLeft="8dip"
- android:layout_marginBottom="8dip"/>
- </LinearLayout>
最后看下主activity的实现代码
- public class MainActivity extends Activity {
- private MyListView listView;
- private MyListView subListView;
- private MyAdapter myAdapter;
- private SubAdapter subAdapter;
- String cities[][] = new String[][] {
- new String[] {"全部美食", "本帮江浙菜", "川菜", "粤菜", "湘菜","东北菜","台湾菜","新疆/清真","素菜","火锅","自助餐","小吃快餐","日本","韩国料理",
- "东南亚菜","西餐","面包甜点","其他"},
- new String[] {"全部休闲娱乐","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",
- "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},
- new String[] {"全部购物", "综合商场", "服饰鞋包", "运动户外","珠宝饰品","化妆品","数码家电","亲子购物","家居建材"
- ,"书店","书店","眼镜店","特色集市","更多购物场所","食品茶酒","超市/便利店","药店"},
- new String[] {"全部休闲娱乐","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",
- "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},
- new String[] {"全","咖啡厅","酒吧","茶馆","KTV","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",
- "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},
- new String[] {"全部","咖啡厅","酒吧","茶馆","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",
- "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},
- new String[] {"全部休","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",
- "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},
- new String[] {"全部休闲","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",
- "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},
- new String[] {"全部休闲娱","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",
- "DIY手工坊","桌球馆","桌面游戏"},
- new String[] {"全部休闲娱乐","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",
- "DIY手工坊","桌球馆","桌面游戏","更多休闲娱乐"},
- new String[] {"全部休闲aaa","咖啡厅","酒吧","茶馆","KTV","电影院","游乐游艺","公园","景点/郊游","洗浴","足浴按摩","文化艺术",
- "DIY手工坊","桌球馆","桌面游戏"},
- };
- String foods[] =new String []{"全部频道","美食","休闲娱乐","购物","酒店","丽人","运动健身","结婚","亲子","爱车","生活服务"};
- int images[] = new int[]{R.drawable.ic_category_0,R.drawable.ic_category_10,R.drawable.ic_category_30,R.drawable.ic_category_20
- ,R.drawable.ic_category_60,R.drawable.ic_category_50,R.drawable.ic_category_45,R.drawable.ic_category_50,R.drawable.ic_category_70,
- R.drawable.ic_category_65,R.drawable.ic_category_80};
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- init();
- myAdapter=new MyAdapter(getApplicationContext(), foods, images);
- listView.setAdapter(myAdapter);
- selectDefult();
- listView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int position,
- long arg3) {
- // TODO Auto-generated method stub
- final int location=position;
- myAdapter.setSelectedPosition(position);
- myAdapter.notifyDataSetInvalidated();
- subAdapter=new SubAdapter(getApplicationContext(), cities, position);
- subListView.setAdapter(subAdapter);
- subListView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1,
- int position, long arg3) {
- // TODO Auto-generated method stub
- Toast.makeText(getApplicationContext(), cities[location][position], Toast.LENGTH_SHORT).show();
- }
- });
- }
- });
- }
- private void init(){
- listView=(MyListView) findViewById(R.id.listView);
- subListView=(MyListView) findViewById(R.id.subListView);
- }
- private void selectDefult(){
- final int location=0;
- myAdapter.setSelectedPosition(0);
- myAdapter.notifyDataSetInvalidated();
- subAdapter=new SubAdapter(getApplicationContext(), cities, 0);
- subListView.setAdapter(subAdapter);
- subListView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1,
- int position, long arg3) {
- // TODO Auto-generated method stub
- Toast.makeText(getApplicationContext(), cities[location][position], Toast.LENGTH_SHORT).show();
- }
- });
- }
- }
默认我选中了第0个,下面看一下运行效果:

【转】http://blog.csdn.net/wangkuifeng0118/article/details/8446661
二级横向菜单实现——ListView的更多相关文章
- DIV+CSS制作二级横向弹出菜单,略简单
没有使用JavaScript控制二级菜单的显示,结果如上图所示. 代码如下: <!DOCTYPE html> <html> <head> <meta char ...
- 一款jquery编写图文下拉二级导航菜单特效
一款jquery编写图文下拉二级导航菜单特效,效果非常简洁大气,很不错的一款jquery导航菜单特效. 这款jquery特效适用于很多的个人和门户网站. 适用浏览器:IE8.360.FireFox.C ...
- Ajax实现动态的二级级联菜单
今天花了点时间用Ajax实现了一个二级级联菜单.整理总结一下.为了把重点放在Ajax和级联菜单的实现上,本文省略了数据库建表语句和操作数据库的代码! 数据库建表语句就不帖出来了.主要有两张表,区域表: ...
- jQuery制作右侧边垂直二级导航菜单
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 纯CSS二级纵向菜单
纯CSS二级纵向菜单 <body> <div class="divda"> <div class="nav"> <ul ...
- RDIFramework.NET V3.3 Web框架主界面新增横向菜单功能
功能描述 响应重多客户的要求与心声,RDIFramework.NET框架Web版本主界面新增横向菜单功能.横向菜单更加直观,用户可操作与展示的空间更多,符合实际应用要求. 一.效果展示 最终界面效果: ...
- [转载] ul li css 做横向菜单
原文地址: http://www.cnblogs.com/amylis_chen/archive/2011/09/24/2188398.html 第一步:建立一个无序列表 我们先建立一个无序列表,来建 ...
- jQuery垂直二级导航菜单代码
http://www.sucaihuo.com/js/395.html 分享一个简单的垂直二级菜单导航. HTML <div id="my_menu" class=&qu ...
- 利用JS实现一个简单的二级联动菜单
前几天在看js的相关内容,所以就简单写了一个二级联动菜单.分享一下. <!DOCTYPE html> <html lang="en"> <head&g ...
随机推荐
- PAT (Advanced Level) 1100. Mars Numbers (20)
简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #in ...
- JavaScript判断数组是否存在key
JS中复合数组associative array和对象是等同的,判断一个key是否存在于数组中(或对象是否包含某个属性),不能使用ary[key] == undefined,因为可能存在ary = { ...
- nodejs实践-MongoDB
nodejs实践-MongoDB laiqun@msn.cn Contents 1. 特点: 2. 开始使用 3. 使用Mongoose操作MongoDB 4. 在express中使用,组织数据库相关 ...
- 把MSSQL的表数据查询成 insert into格式的函数
USE [db] GO /****** Object: StoredProcedure [dbo].[proc_insert] Script Date: 12/05/2012 17:18:31 *** ...
- css div11
text-indent:30em; 缩进 font-family:"sans serif"文字的字体 border-width:1px; border-style:solid; ...
- angularJs中ngModel的坑
angular中指令被用的最多的除了ng-repeat之外就非他莫属了吧,由于各种业务的需求,我们经常需要去写一些继承ngModel的指令,来满足各种奇葩需求,最多的莫过于表单的验证啦,另外你在封装一 ...
- 一个int类型引发的bug
一.引言 今天我在项目开发中,遭遇了一个莫名其妙的问题,概括加抽象后形成如下问题:在使用MyBatis的XML语句实现Dao层接口 List<Person> selectBySome(@P ...
- 创建mysql数据库的时候指定编码
CREATE DATABASE xxx DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
- JAVA基础--继承中的构造方法
1. 子类的构造方法必须调用父类的构造方法 2. 子类在自己的构造方法中使用super(argument_list)调用父类的构造方法, 使用this(argument_list)调用自己的其他的构造 ...
- 【HighCharts系列教程】十、图例属性——legend
一.legend属性说明 Legend是HighCharts图表的图例属性,如图 默认情况下,HighCharts都会有图例,无特殊情况,默认即可满足需求,所以一般不用配置Legend属性. 二.la ...