一个好用的多选菜单
来源:互联网 发布:优化最差的pc游戏 编辑:程序博客网 时间:2024/05/09 16:50
效果图
自定义属性
使用
注意:
menu_layout和content_view的父控件使用FrameLayout或RelativeLayout,content_view设置topmargin为menu_layout的高度。
<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="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="50dp" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="多选菜单" android:textSize="20sp" /> </LinearLayout> <com.beiing.library.MultipleMenu android:id="@+id/multiple_menu" android:layout_width="match_parent" android:layout_height="match_parent" app:mm_tabHolderHeight="50dp" app:mm_underLineHeight="2dp" app:mm_underLineColor="#FF09A63B" app:mm_tabTitleDefaultColor="#FF09A63B" app:mm_tabTitletSelectedColor="#dc0f57" app:mm_tabTitleDefaultSize="15sp" app:mm_tabTitleSelectedSize="16sp" app:mm_tabIconDefault="@mipmap/ic_default" app:mm_tabIconSelected="@mipmap/ic_selected" app:mm_tabIconLeftmargin="10dp" app:mm_dividerWidth="1dp" app:mm_dividerTopmargin="10dp" app:mm_dividerBottommargin="10dp" app:mm_dividerColor="#882DB91B" app:mm_maskColor="#889a9ae6" app:mm_menuAnimateIn="@anim/scale_in" app:mm_menuAnimateOut="@anim/scale_out"> </com.beiing.library.MultipleMenu></FrameLayout>
代码:
private List<MultipleMenu.MenuPage> initMenuPages(){ ListView timeMenu = new ListView(this); timeMenu.setBackgroundColor(Color.WHITE); ArrayAdapter<String> timeAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, times); timeMenu.setAdapter(timeAdapter); ListView kindMenu = new ListView(this); kindMenu.setBackgroundColor(Color.WHITE); ArrayAdapter<String> kindAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, kinds); kindMenu.setAdapter(kindAdapter); ListView priceMenu = new ListView(this); priceMenu.setBackgroundColor(Color.WHITE); ArrayAdapter<String> priceAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, prices); priceMenu.setAdapter(priceAdapter); List<MultipleMenu.MenuPage> menuPages = new ArrayList<>(3); menuPages.add(new MultipleMenu.MenuPage("时间", timeMenu)); menuPages.add(new MultipleMenu.MenuPage("户型", kindMenu)); menuPages.add(new MultipleMenu.MenuPage("价格", priceMenu)); return menuPages; }
multipleMenu.setMultipleMenu(initMenuPages());
其他方法
closeMenu();
: 关闭当前打开菜单
setTabTitle(String text)
:设置当前打开菜单tabtitle
setTbaTitle(int position, String text)
:设置指定位置tabtitle
实现
- 继承LinearLayout,竖直排列。
- 添加顶部tab布局(是一个横向的LinearLayout)tabHolderView。
- 添加menu布局(一个FrameLayout)menuHolderView。
初始化控件的方法:
private void initView(Context context) { //初始化view tabHolderView = new LinearLayout(context); tabHolderView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, config.tabHolderHeight)); tabHolderView.setOrientation(HORIZONTAL); tabHolderView.setGravity(Gravity.CENTER); tabHolderView.setBackgroundColor(config.tabHolderColor); View underLineView = new View(context); underLineView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, config.underLineHeight)); underLineView.setBackgroundColor(config.underLineColor); menuHolderView = new FrameLayout(context); menuHolderView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); //添加view addView(tabHolderView); addView(underLineView); addView(menuHolderView); maskView = new View(context); maskView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); maskView.setBackgroundColor(config.maskColor); }
当调用setMultipleMenu方法时,开始初始化各个tab和menu。
public void setMultipleMenu(List<MenuPage> menuPages){ if(menuPages.isEmpty()) return; this.menuPages = menuPages; tabList = new ArrayList<>(menuPages.size()); maskView.setOnClickListener(this); menuHolderView.addView(maskView); LayoutInflater inflater = LayoutInflater.from(getContext()); for (int i = 0, size = menuPages.size(); i < size; i++) { MenuPage mp = menuPages.get(i); addTab(mp.getMenuTitle(), inflater, i); if(i != size - 1){ addDivider(); } addMenuView(mp.getMenuView()); } maskView.setVisibility(GONE); menuHolderView.setVisibility(GONE); }
addTab方法便是添加一个tab,R.layout.item_tab_layout由一个TextView和一个ImageView组成,为了减少findviewbyid操作,添加了一个ItemTabHolder类。每个itemholder记录当前tab的index。
private void addTab(String menuTitle, LayoutInflater inflater, int position) { View itemTab = inflater.inflate(R.layout.item_tab_layout, tabHolderView, false); ItemTabHolder itemTabHolder = new ItemTabHolder(itemTab, position); itemTabHolder.setTitleText(menuTitle) .setTitleTextSize(config.tabTitleDefaultSize) .setTitleTextColor(config.tabTitleDefaultColor) .setIconResource(config.tabIconDefault); final LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.leftMargin = config.tabIconLeftmargin; itemTabHolder.tvIcon.setLayoutParams(lp); itemTab.setTag(itemTabHolder); itemTab.setOnClickListener(this); tabHolderView.addView(itemTab); tabList.add(itemTab); }
然后就是添加tab,添加divider,添加underline。在添加各个menuview和maskview…
最重要的操作是打开和关闭menu,menu打开关闭均以动画过渡,tabicon有旋转动画,当然,这些动画都可以自己设置。
/** * 关闭菜单 */ public void closeMenu() { if(currentPosition != INVALID_POSITION){ //tab状态改变 View itemTab = tabList.get(currentPosition); ItemTabHolder itemHolder = (ItemTabHolder) itemTab.getTag(); if (itemHolder != null) { itemHolder.setTitleTextSize(config.tabTitleDefaultSize) .setTitleTextColor(config.tabTitleDefaultColor) .setIconResource(config.tabIconDefault); //icon动画 itemHolder.tvIcon.startAnimation(iconOutAnimation); } //动画退出 final View menuView = menuHolderView.getChildAt(currentPosition + 1); menuOutAnimation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { menuView.setVisibility(GONE); maskView.setVisibility(GONE); menuHolderView.setVisibility(GONE); } @Override public void onAnimationRepeat(Animation animation) { } }); menuHolderView.startAnimation(menuOutAnimation); currentPosition = INVALID_POSITION; } }
/** * 打开指定位置menu * @param position */ private void openMenu(int position) { View itemTab = tabList.get(position); ItemTabHolder itemHolder = (ItemTabHolder) itemTab.getTag(); if (itemHolder != null) { itemHolder.setTitleTextSize(config.tabTitleSelectedSize) .setTitleTextColor(config.tabTitletSelectedColor) .setIconResource(config.tabIconSelected); //icon动画 itemHolder.tvIcon.startAnimation(iconInAnimation); } for (MenuPage page : menuPages) { page.getMenuView().setVisibility(GONE); } //动画进入 menuHolderView.setVisibility(VISIBLE); maskView.setVisibility(VISIBLE); menuHolderView.getChildAt(position + 1).setVisibility(VISIBLE); menuHolderView.startAnimation(menuInAnimation); currentPosition = position; }
说明:
MenuPage是为了让tabtitle和menuView一一对应而写的一个类。
public static class MenuPage{ private String menuTitle; private View menuView; public MenuPage(String menuTitle, View menuView) { this.menuTitle = menuTitle; this.menuView = menuView; } public MenuPage() { } public String getMenuTitle() { return menuTitle; } public void setMenuTitle(String menuTitle) { this.menuTitle = menuTitle; } public View getMenuView() { return menuView; } public void setMenuView(View menuView) { this.menuView = menuView; } }
实现比较简单,就不做过多解释了。
Github:MultipleMenu
1 0
- 一个好用的多选菜单
- 一个XML+JS的菜单,好用
- 一个好用的CSS下拉菜单源码
- 一个树形菜单的好类
- 一个树形菜单的好类
- [Tomcat]关于Tomcat8.0的调教以及一个好用的JQuery轮盘菜单插件
- Android 简单封装一个精美、好用的菜单型PopupWindow
- 分享一个Android封装精美、好用的菜单型PopupWindow
- 一个右建菜单,还没有写好的
- 一款好用的树形菜单
- 一个好用的电子地图
- 一个好用的DBGRID
- 一个好用的DBGRID
- 一个好用的套路
- 比较好的菜单滑动
- 多选下拉菜单的一个实现方案 by unifly
- 给大家推荐一个比较好的JS菜单制作工具
- 转载,JS 好用的侧边栏菜单
- iOS获取User-Agent(UA)信息的方法
- C语言 <time.h>
- hihocoder 1470 公平的游戏
- 枚举类来实现单例类
- 关于arm内核编译(基于tq2440)的一些问题
- 一个好用的多选菜单
- 您的设计模式——桥梁模式【Bridge Pattern】
- 线程(Linux)
- 【PTA 5-1 N个数求和 (20分)】+ gcd
- Hibernate多对一遍历对象的时候报 java.lang.StackOverflowError错误
- #ifndef #define #endif的使用
- 转自ellisonDon PHP定时执行任务的实现
- LeetCode 算法刷题(9)
- 如何理解HTTP协议的 “无连接,无状态” 特点?