二级横向菜单实现——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 ...
随机推荐
- 用cas来实现php的单点登陆
最近项目中需要做单点登录,客户端包含Java.ruby和PHP,java有几个应用程序,php是discuz+supesite+ucenter,配置步骤如下: 1.cas服务端:下载地址:http:/ ...
- Chapter 1 First Sight——16
I drove around the school, following the line of traffic. 我开车绕学校随着交通线. 我开车穿过校园,紧跟着大部队. I was glad to ...
- PHP递归算法的一个实例 帮助理解
递归函数为自调用函数,在函数体内直接或间接自己调用自己,但需要设置自调用的条件,若满足条件,则调用函数本身,若不满足则终止本函数的自调用,然后把目前流程的主控权交回给上一层函数来执行,可能这样给大家讲 ...
- Struts2 设置--Myelipse
1. Windows---preferrence---Myeclipse---Server----Tomcat 2. Windows---preferrence---Java---Installed ...
- Android Security
Android Security¶ 确认签名¶ Debug签名: $ jarsigner -verify -certs -verbose bin/TemplateGem.apk sm 2525 Sun ...
- stock 仓位
别胆大求多,不轻信盲从.抓住几只自己长期关注并看好的股票.将这几只股票选为自选股,而其他股,不管是机构推荐还是股评荐股,都要谨慎,不轻易听从. 巧用“三三制”,根据趋势控制仓位.当不知道是在涨还是在跌 ...
- 【栈】 poj 1363
poj1363,这道题是数据结构与算法中的经典问题,给定一组进栈顺序,问栈有多少种出去的顺序. #include<stdio.h> #include <stack> #incl ...
- Beautiful Subarrays
Beautiful Subarrays time limit per test 3 seconds memory limit per test 512 megabytes input standard ...
- 核心动画 CAAnimation 进阶
转载自:http://www.cofcool.net/development/2015/06/20/ios-study-note-nine-CoreAnimation/ Core Animation, ...
- SDAU课程练习--problemG(1006)
题目描述 Problem Description The highest building in our city has only one elevator. A request list is m ...