今天是分享一个android实现三级菜单联动效果,到了第三级菜单有点复杂,下面带着大家看下代码。

项目结构:
Android 多级菜单联动操作_第1张图片

为了让大家更有的耐心的阅读, 我先从简单的开始说起,我们先看下demo实现的效果吧!这样可以让大家更好的理解后面的思路。

我们来看下整体的布局,主页面无非就只有两个TextView控件,可点击。我把代码贴出来,xml如下:

"http://schemas.android.com/apk/res/android"    android:id="@+id/rootview"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    id="@+id/textview1"        android:layout_width="fill_parent"        android:layout_height="30dp"        android:text="Activity Demo"        android:textColor="@color/black"        android:layout_margin="20dp"/>    id="@+id/textview2"        android:layout_width="fill_parent"        android:layout_height="30dp"        android:textColor="@color/black"        android:text="Dialog Demo"        android:layout_margin="20dp"/>                    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

然后从Activity Demo进去,我们可以看到先是出来半边的menu列表,效果如下:

Android 多级菜单联动操作_第2张图片

这个布局大家都知道,就是一个简单的ListView,以下是code:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/menudialog_divider_color"    android:orientation="vertical">    <ListView        android:id="@+id/listview"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:background="@color/white"        android:cacheColorHint="@android:color/transparent"        android:divider="@null"        android:scrollbars="none" />LinearLayout>                    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

那么第二个menu列表是什么出来的呢?布局是一样的,这里三个列表菜单的ListView,我都用同一个xml实现,这并不矛盾,都是ListView列表。这里两个ListView都在同一个屏幕,其实道理很简单,一个ListView占整个屏幕的1/2。第二listView自然可以在同一个屏幕上显示,是不是顿时明白了?哈哈。。。

好,接下来我我们看一下ListView的item布局,代码如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/menu_item_ly"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:gravity="center_vertical"    android:minHeight="43dp"    android:orientation="vertical">    <TextView        android:id="@+id/menu_item_textview"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_marginLeft="16dp"        android:layout_weight="1"        android:gravity="center_vertical"        android:text="title"        android:textColor="#000000"        android:textSize="17sp"/>    <TextView        android:id="@+id/menu_item_divider"        android:layout_width="match_parent"        android:layout_height="1px"        android:layout_marginLeft="16dp"        android:layout_marginRight="16dp"        android:textColor="@color/black"        android:background="@color/menudialog_divider_color"/>LinearLayout>                    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

也很简单,两个TextView控件,第一个是我们要显示的title文本,第二个是title下方的线,以上效果图不太清楚,我这边把颜色加深点,方便大家理解查看。
Android 多级菜单联动操作_第3张图片

左右滑动是ViewPager,讲到这里,大致就知道这个结构了,没错,就是在ViewPager里面放入三个ListView,实现三个列表可以左右滑动,我也把这份布局贴出来吧!请看以下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/rootview"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal">    <com.lai.threemenudemo.view.MyViewPager        android:id="@+id/viewpager"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:overScrollMode="never"/>LinearLayout>                    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这个ViewPager是自定义的,里面很简单,如下:

package com.lai.threemenudemo.view;import android.content.Context;import android.support.v4.view.ViewPager;import android.util.AttributeSet;/** * Created by LaiYingtang on 2016/5/22. * 主页面左右滑动 */public class MyViewPager extends ViewPager{    public MyViewPager(Context context, AttributeSet attrs) {        super(context, attrs);    }    public MyViewPager(Context context) {        super(context);    }    //判断menu在x,y的位置    public void scrollTo(int x,int y){        if(getAdapter()==null||x>getWidth()*(getAdapter().getCount()-2)){            return;        }        super.scrollTo(x,y);    }}                    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

以下说重点,我们在第一个ListView中点击某一个item,出来第二个ListView列表,我们是怎么做到的呢?思路跟我们的数据库一样,每个菜单的联动必须要关联另个菜单,这样触动一个item的时候,跟它所关联的item便随之出现,我把这些数据写在一个txt文本里面,我们要读取的时候,直接将这些数据封装到SparseArray集合里面遍历出来即可。这里用到的SparseArray是为了节省内存,提高性能。

我们看下数据是怎么关联起来的,我就不全部贴出来了,贴两个item的数据,后面以此类推。

310000,IT/互联网/软件/通信,0;310100,产品,310000;310101,产品专员/产品助理,310100;310102,产品经理/高级产品经理,310100;310103,产品总监/副总监,310100;310104,产品VP/首席产品官,310100;310105,其他产品类职位,310100;310200,设计,310000;310201,网页设计/网站美工,310200;310202,APP设计,310200;310203,UI/UE/交互设计,310200;310204,Flash/多媒体设计,310200;310205,游戏设计,310200;310206,设计经理/主美,310200;310207,设计总监/副总监,310200;310208,其他设计类职位,310200;                    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

我们来看下这些数据到底如何理解,学过mysql的很容易理解,使用id关联数据表的每一个对应的字段,这个也一样,我贴张图讲述就明白了。
Android 多级菜单联动操作_第4张图片

看红色框部门,点击左栏产品子菜单,包含了右栏多个item的效果,我们来看下这组数据:

Android 多级菜单联动操作_第5张图片

我们可以理解为,在多条数据中,一条数据有三个字段,第一条的titleName为“产品”,用它的id关联了以下多个titleName,得出了产品包含多个item的结果。下面的设计选项也是一样,不妨去试着理解,看如下:

Android 多级菜单联动操作_第6张图片Android 多级菜单联动操作_第7张图片

是不是?。。。。。
前面一级菜单到二级菜单也是如此,我们看看效果图:
Android 多级菜单联动操作_第8张图片
Android 多级菜单联动操作_第9张图片

后面以此类推。结构就这么简单,但是代码有点小复杂。我们一起看看:

这里我贴出dialog这部分的代码,这部分写了注解:
package com.lai.threemenudemo.dialog;import android.content.Context;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.widget.AdapterView;import android.widget.LinearLayout;import android.widget.ListView;import com.lai.threemenudemo.R;import com.lai.threemenudemo.adapter.MenuDialogAdapter;import com.lai.threemenudemo.adapter.MyPagerAdapter;import com.lai.threemenudemo.bean.MenuData;import com.lai.threemenudemo.utils.MenuDataManager;import com.lai.threemenudemo.view.MyViewPager;import java.util.ArrayList;import java.util.List;/** * 三级菜单列表 * Created by LaiYingtang on 2016/5/25. */public class ThreeMenuDialog extends SecondMenuDialog{    private  int mWidth;    //宽度    private MyViewPager mViewPager; //滑动viewPager    private LinearLayout mRootView;    //需要显示的layout    private View view1,view2,view3;    //三个菜单级view    private ListView mListView1,mListView2,mListView3;  //每个菜单列表都是一个listView    private MenuDialogAdapter mListView1Adapter, mListView2Adapter, mListView3Adapter; //列表显示数据必须要的adapter    private List views = new ArrayList(); //数据集合    public MenuDataManager mDictDataManager = MenuDataManager.getInstance(); //全部数据    private MenuItemClickListener menuItemClickListener;   //接口,点击监听    public ThreeMenuDialog(Context context) {        super(context);        mWidth = mContext.getResources().getDisplayMetrics().widthPixels;//获取屏幕参数        mContentView = LayoutInflater.from(context).inflate(R.layout.three_menu_dialog,null);        //初始化控件及对控件操作        initViews();        setTitle("三级列表");//设置title    }    private void initViews() {        mRootView = (LinearLayout) findViewById(R.id.rootview);        mViewPager = (MyViewPager) findViewById(R.id.viewpager);        mViewPager.setOffscreenPageLimit(2);//显示2页        //为view加载layout,由于三个级的菜单都是只有一个listView,这里就只xie一个了        LayoutInflater inflater = LayoutInflater.from(mContext);        view1 = inflater.inflate(R.layout.pager_number, null);        view2 = inflater.inflate(R.layout.pager_number, null);        view3 = inflater.inflate(R.layout.pager_number, null);        //获取id        mListView1 = (ListView) view1.findViewById(R.id.listview);        mListView2 = (ListView) view2.findViewById(R.id.listview);        mListView3 = (ListView) view3.findViewById(R.id.listview);        //获取列表数据了        List list=mDictDataManager.getTripleColumnData(mContext, 0);        //关联adapter        mListView1Adapter = new MenuDialogAdapter(mContext, list);        mListView1Adapter.setSelectedBackgroundResource(R.drawable.select_white);//选中时的背景        mListView1Adapter.setHasDivider(false);        mListView1Adapter.setNormalBackgroundResource(R.color.menudialog_bg_gray);//未选中        mListView1.setAdapter(mListView1Adapter);        views.add(view1);        views.add(view2);//当前是第三级菜单,所以前面已经存在第一,第二菜单了        //关联        mViewPager.setAdapter(new MyPagerAdapter(views));        //触屏监听        mRootView.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                return mViewPager.dispatchTouchEvent(event);            }        });        //view1的listView的点击事件        //点击事件        mListView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                if (mListView1Adapter != null)                    mListView1Adapter.setSelectedPos(position);                if (mListView2Adapter != null)                    mListView2Adapter.setSelectedPos(-1);                if (views.contains(view3)) {                    views.remove(view3);                    mViewPager.getAdapter().notifyDataSetChanged();//立即更新adapter数据                }                MenuData menuData = (MenuData) parent.getItemAtPosition(position);//得到第position个menu子菜单                if (menuData.id == 0) {//不限                    if (mListView2Adapter != null) {                        mListView2Adapter.setData(new ArrayList());                        mListView2Adapter.notifyDataSetChanged();//刷新                    }                    setDictItemClickListener(menuData);                } else {                    List list2 = mDictDataManager.getTripleColumnData(mContext, menuData.id);                    if (mListView2Adapter == null) {                        mListView2Adapter = new MenuDialogAdapter(mContext, list2);                        mListView2Adapter.setNormalBackgroundResource(R.color.white);                        mListView2.setAdapter(mListView2Adapter);                    } else {                        mListView2Adapter.setData(list2);                        mListView2Adapter.notifyDataSetChanged();                    }                }            }        });        //view2的listView点击        mListView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                if (mListView2Adapter != null) {                    mListView2Adapter.setSelectedPos(position);                    mListView2Adapter.setSelectedBackgroundResource(R.drawable.select_gray);                }                if (views.contains(view3)) {                    views.remove(view3);                }                //从第二级菜单的基础上加载第三级菜单                MenuData menuData = (MenuData) parent.getItemAtPosition(position);                List list3 = mDictDataManager.getTripleColumnData(mContext, menuData.id);                if (mListView3Adapter == null) {                    mListView3Adapter = new MenuDialogAdapter(mContext, list3);                    mListView3Adapter.setHasDivider(false);                    mListView3Adapter.setNormalBackgroundResource(R.color.menudialog_bg_gray);                    mListView3.setAdapter(mListView3Adapter);                } else {                    mListView3Adapter.setData(list3);                    mListView3Adapter.notifyDataSetChanged();                }                //放入第三级菜单列表                views.add(view3);                mViewPager.getAdapter().notifyDataSetChanged();                if (mViewPager.getCurrentItem() != 1) {                    mViewPager.postDelayed(new Runnable() {                        @Override                        public void run() {                            mViewPager.setCurrentItem(1);//选一个                        }                    }, 300);                }            }        });        //最后就是第三级菜单的点击了        mListView3.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                MenuData menuData = (MenuData) parent.getItemAtPosition(position);                setDictItemClickListener(menuData);//选中点击的子菜单,去设置titleName            }        });    }    private void setDictItemClickListener(MenuData menuData) {        if (menuItemClickListener != null) {            menuItemClickListener.onMenuItemClick(menuData);        }        dismiss();    }    public final void setonItemClickListener(MenuItemClickListener listener) {        menuItemClickListener = listener;    }    public interface MenuItemClickListener {        public void onMenuItemClick(MenuData menuData);    }}                    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190

然后dialog的动画效果,我也贴出来:

package com.lai.threemenudemo.dialog;import android.app.Dialog;import android.content.Context;import android.view.Gravity;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.widget.LinearLayout;import android.widget.TextView;import com.lai.threemenudemo.R;/** * 菜单动画 * Created by LaiYingtang on 2016/5/25. */public class SecondMenuDialog extends Dialog{    public Context mContext;    public LinearLayout containerViewGroup;    public View mContentView;    public TextView titleView;    Window window = null;    //构造器    public SecondMenuDialog(Context context) {        super(context, R.style.dialog_change_card);//样式        mContext = context;        containerViewGroup = (LinearLayout) getLayoutInflater().inflate(R.layout.second_menu_dialog, null);        titleView = (TextView) containerViewGroup.findViewById(R.id.dictdialog_title_tv);    }    public View findViewById(int id) {        return mContentView.findViewById(id);    }    /**     * 设置窗口显示     */    public void windowDeploy() {        window = getWindow(); // 得到对话框        window.setWindowAnimations(R.style.RegDialogAnimation); // 设置窗口弹出动画效果        WindowManager.LayoutParams windowAttributes = window.getAttributes();        windowAttributes.x = 0; // x小于0左移,大于0右移        windowAttributes.y = 0; // y小于0上移,大于0下移        windowAttributes.height = 2 * mContext.getResources().getDisplayMetrics().heightPixels / 3;        windowAttributes.width = LinearLayout.LayoutParams.FILL_PARENT;        windowAttributes.alpha = 0.6f; //设置透明度        windowAttributes.gravity = Gravity.BOTTOM; // 设置重力,对齐方式        window.setAttributes(windowAttributes);    }    //显示到layout里面    @Override    public void show() {        if (mContentView != null) {            containerViewGroup.addView(mContentView);        }        setContentView(containerViewGroup);        setCanceledOnTouchOutside(true);        windowDeploy();        super.show();    }    //选中的title设置为title    @Override    public void setTitle(CharSequence title) {        if (titleView != null)            titleView.setText(title);    }}                    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

有一些注释提示大家去理解,我在这里也不能全部讲的那么详细,重要的是,还是要靠大家自己去理解,去参悟,这样才能真正学到东西。好了,大家自己慢慢去消化吧!最后我还是会把源码链接给共享出来,希望大家看了后对你们有所帮助,谢谢!

最后我附上demo的链接:
源码下载

更多相关文章

  1. Android魔术(第五弹)—— 一步步实现滑动折叠列表
  2. Android 弧形列表转盘的实现(三),View跟随RecyclerView做旋转动画;
  3. android列表收缩与展开仿QQ好友列表(非常详细,附源码)
  4. adb shell 命令详解 在Android中查看和管理sqlite数据库
  5. Android 数据库SQLite升级降级
  6. Android学习路线(二十六)Android数据存储
  7. Android中如何解析JSON数据

随机推荐

  1. android 签名验证
  2. Android(安卓)文件读写的例子
  3. [Android(安卓)Tools] Android(安卓)Reve
  4. 调用Android系统设置项
  5. android隐藏显示软键盘
  6. android:xml解析
  7. [转]ANDROID NOTIFICATIONS USING CORDOV
  8. android开关按钮,Switch,ToggleButton,Radio
  9. Android(安卓)判断是都联网状态
  10. Android之获取当前Activity名称