Android自定义Dialogの仿ios系统底部菜单(自下而上弹出)
2016-05-28 12:22
731 查看
对于项目中经常用到的组件,进行了封装,方便他人及自己的调用和管理,减少代码的冗余,提高开发的效率我们项目中,减少重复制造轮子。
我的项目中,经常用到底部自下而上弹出菜单选项,跟ios系统的底部菜单一样的样式,由于之前开发中,没有对其进行封装,因此,在与他人合作时,他自己也写了一套去实现,导致重复制造轮子,同时代码也难看,无法复用
因此,我对其进行封装,采用自定义Dialog方式,需要提供他人方法有:
ArrayList menuItem菜单选项
MenuItemOnClickListener onClickListener
菜单选项点击事件监听回调
/** * 设置菜单item数据 * * @param menuItem */ public void setMenuItem(ArrayList<String> menuItem) { mMenuItem = menuItem; if (mMenuItemOnClickListener != null) { mMenuItemOnClickListener.dialog = this; mMenuItemOnClickListener.mMenuItem = menuItem; } mAdapter = new MenuItemAdapter(mContext, menuItem); mListview.setAdapter(mAdapter); } /** * 设置菜单item点击事件 * * @param menuItemOnClickListener */ public void setmMenuItemOnClickListener(MenuItemOnClickListener menuItemOnClickListener) { this.mMenuItemOnClickListener = menuItemOnClickListener; if (menuItemOnClickListener != null) { menuItemOnClickListener.dialog = this; if (menuItemOnClickListener.mMenuItem == null || menuItemOnClickListener.mMenuItem.isEmpty()) { menuItemOnClickListener.mMenuItem = mMenuItem; } } }
这是需要调用者传递的参数,接下来是里面的实现
继承Dialog,同时初始化参数public DialogBottomMenu(Context context) { this(context, null); } public DialogBottomMenu(Context context, ArrayList<String> menuItem) { this(context, menuItem, null); } public DialogBottomMenu(Context context, ArrayList<String> menuItem, MenuItemOnClickListener menuItemOnClickListener) { super(context); mContext = context; mMenuItem = menuItem; mMenuItemOnClickListener = menuItemOnClickListener; init(); } private void init() { initWindow(); View contentView = View.inflate(mContext, R.layout.layout_dialog_bottom_menu, null); setCanceledOnTouchOutside(true); setContentView(contentView); mListview = (NoScrollListView) contentView.findViewById(R.id.lv); TextView tvCancel = (TextView) contentView.findViewById(R.id.tv_cancel); tvCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); setMenuItem(mMenuItem); }
由于是Dialog,需要自定义window参数,取消标题,宽度为屏幕宽度,高为包裹高度,同时设置好动画,自下而上弹出,
注意!!!window的动画需要写在style里面,才能调用;
/** * 初始化window参数 */ private void initWindow() { requestWindowFeature(Window.FEATURE_NO_TITLE); // 取消标题 Window dialogWindow = getWindow(); dialogWindow.getDecorView().setPadding(0, 0, 0, 0); dialogWindow.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); dialogWindow.setBackgroundDrawableResource(android.R.color.transparent); dialogWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); WindowManager.LayoutParams lp = dialogWindow.getAttributes(); DisplayMetrics d = mContext.getResources().getDisplayMetrics(); lp.width = WindowManager.LayoutParams.MATCH_PARENT; lp.height = WindowManager.LayoutParams.WRAP_CONTENT; lp.gravity = Gravity.BOTTOM; dialogWindow.setAttributes(lp); // 设置显示动画 dialogWindow.setWindowAnimations(R.style.main_menu_animstyle); }
接着实现菜单,我采用的导入布局文件方式实现的,同时菜单选项为一个不能滑动listview列表,这样扩展就高了,你数据有多少我就现实多少项
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" < 4000 span class="hljs-attribute">android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:paddingRight="10dp" android:paddingLeft="10dp" android:orientation="vertical"> <com.kingpeng.common_lib.view.NoScrollListView android:id="@+id/lv" style="@style/list_common_style" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_cancel" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginBottom="10dp" android:layout_marginTop="15dp" android:background="@drawable/bottom_menu_item_dialog_bg" android:gravity="center" android:text="取消" android:textColor="#5b729a" android:textSize="18dp" tools:text="取消" /> </LinearLayout>
listview 的 item布局
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:id="@+id/ly_item" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bottom_menu_item_dialog_bg2" android:orientation="vertical"> <TextView android:id="@+id/tv_item" android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center" android:textColor="#5b729a" android:textSize="18sp" tools:text="呵呵" /> <View android:id="@+id/view_line" android:layout_width="match_parent" android:layout_height="0.5dp" android:background="#e2e3e5" /> </LinearLayout> </FrameLayout>
listview 的adapter实现;根据不同下标,加载不同style,实现仿照ios的UI
private class MenuItemAdapter extends BaseAdapter<String> { public MenuItemAdapter(Context context) { super(context); } public MenuItemAdapter(Context context, List<String> list) { super(context, list); } @Override public int getContentView() { return R.layout.layout_dialog_bottom_menu_item; } @Override public void onInitView(View view, int position) { View ly_item = get(view, R.id.ly_item); TextView tv_item = get(view, R.id.tv_item); View view_line = get(view, R.id.view_line); view_line.setVisibility(View.VISIBLE); if (getCount() == 1 && position == 0) { ly_item.setBackgroundResource(R.drawable.bottom_menu_item_dialog_bg); view_line.setVisibility(View.GONE); } else if (position == 0) { ly_item.setBackgroundResource(R.drawable.bottom_menu_item_dialog_bg3); } else if (position == getCount() - 1) { ly_item.setBackgroundResource(R.drawable.bottom_menu_item_dialog_bg4); view_line.setVisibility(View.GONE); } else { ly_item.setBackgroundResource(R.drawable.bottom_menu_item_dialog_bg2); } List<String> list = getList(); tv_item.setText(list.get(position)); ly_item.setTag(position); if (mMenuItemOnClickListener != null) { ly_item.setOnClickListener(mMenuItemOnClickListener); } } }
自定义一个点击事件监听回调,传递view,item_index,item;
public static abstract class MenuItemOnClickListener implements View.OnClickListener { public Dialog dialog; public ArrayList<String> mMenuItem; @Override public void onClick(View v) { if (dialog != null && dialog.isShowing()) { dialog.dismiss(); } int index = -1; String item = ""; if (mMenuItem != null && !mMenuItem.isEmpty()) { index = (int) v.getTag(); item = mMenuItem.get(index); } onClickMenuItem(v, index, item); } /** * 菜单点击事件回调 * * @param v * @param item_index 点击item的下标 * @param item 点击item的字符串 */ public abstract void onClickMenuItem(View v, int item_index, String item); }
至于style文件,我就不提供了,你们自己根据自己需求进行设计即可,在此写这个目的,仅仅是提供自定义Dialog的思路
我们为什么要重复制造轮子?
很简单啊,因为现有的轮子不够用啊。
开源的世界很精彩,开源的世界很无奈。
花了一个星期,分析了四个轮子,没有一个合格的!
时间紧迫,先攒一个可用的轮子再说。
因为有现成的“半成品“轮子,不用从头生产了。
从每个轮子身上拿点可用的零件,最后,一个新轮子就出来了。
后来,慢慢地, 这个轮子越来越适用。
再后来,我们生产了所有的轮子用的零件。
它成了我们专用的轮子了。
原来的临时轮子怎么办?
代码整理一下,文档完善一下,放出去吧,万一有人和我们的需求差不多呢?
慢慢地,网上类似的轮子也越来越多。
半成品也越来越多。
有时候感觉可用的轮子挺多的,到最后发现都最假象。
不感慨了,依旧感谢开源。
这样起码,我们在做一个”网站“时,不用从”沙子“开始。
虽然,很多程序员都这么想过。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件