【Android学习】使用popupWindow模拟menu
2014-06-18 00:08
369 查看
刚开始学习android,下了个apk,发现它的menu很帅气,而android自带的menu非常丑,特别是4.0之后,menu变成了垂直的list,更丑,于是花了点时间模仿了一个
效果图如下:
源码下载地址:http://download.csdn.net/detail/cbxjj/7513471
点击更多按钮来进行换页操作
代码如下:
1.Activity
2.MyMenu_1
3.slide_menu.xml
4.my_menu_item.xml
很顺利的做出来了。效果和效果图一致,基本和apk里面的差不多,但是我觉得分页操作不是很方便,觉得android的滚屏左右滑动效果不错,
用到这个上面也还不错,于是开始查资料,发现viewPager和viewgroup都可以做,先用viewgroup做了一晚上,各种bug,快崩溃了。
于是换viewPager,中间虽然出了很多次问题,但是还是做出来了,效果如下:
直接上代码:
1.PopupMenuActivity
2.Mymenu.java
3.MySimpleAdapter 不用SimpleAdapter 而是自己写一个,因为报了一个The observer is null.查了下问题,应该是关闭window的时候setAdapter的时候unregisterDataSetObserver没判断mDataSetObserver是否为空,据说是因为嵌套控件导致,这里直接判断下就完了
4.MyViewPager 继承了android.support.v4.view.ViewPager,因为这个控件高度自动全屏了 设置wrap_content也没用,这里集成了ViewPager重新设置了以下高度
5.MyViewPagerAdapter重写了PagerAdapter
6.my_menu.xml 注意这里最外层必须用LinearLayout,否则会报一个android.support.v4.view.ViewPager canot be cast to。。。。
转换异常,用RelativeLayout狂报错。
源码下载地址:http://download.csdn.net/detail/cbxjj/7513471
效果图如下:
源码下载地址:http://download.csdn.net/detail/cbxjj/7513471
点击更多按钮来进行换页操作
代码如下:
1.Activity
public class SlideActivity extends Activity { private MyMenu_1 myMenu; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onResume() { super.onResume(); myMenu = new MyMenu_1(SlideActivity.this); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_MENU: if (myMenu.isShowing()) { myMenu.dismiss(); } else { //将弹出menu显示到底部 myMenu.showAtLocation(findViewById(R.id.main_layout), Gravity.BOTTOM, 0, 0); } break; case KeyEvent.KEYCODE_BACK: myMenu.dismiss(); break; } return super.onKeyDown(keyCode, event); } }
2.MyMenu_1
public class MyMenu_1 extends PopupWindow { private static int menuSize = 1; private Context mContext; private RelativeLayout mLinearLayout; private GridView mGridView; private String[] titles = { "添加收藏夹", "查找短信", "新增短信", "定时任务", "发送报告", "更多", "设置", "关于", "帮助", "反馈", "返回" }; private int[] images = { R.drawable.icon_menu_favorite, R.drawable.icon_menu_search, R.drawable.icon_menu_add,R.drawable.icon_menu_schedule_task, R.drawable.icon_menu_view_sent_status,R.drawable.icon_menu_more,R.drawable.icon_menu_setting, R.drawable.icon_menu_info,R.drawable.icon_menu_help,R.drawable.icon_menu_feedback,R.drawable.icon_menu_back}; private List<HashMap<String,Object>> itemList = new ArrayList<HashMap<String,Object>>(); private SimpleAdapter adapter; private LayoutInflater inflater; public MyMenu_1(Context context){ super(context); mContext = context; initDatas(); initViewInWin(); this.setWidth(LayoutParams.FILL_PARENT); this.setHeight(LayoutParams.WRAP_CONTENT); //这里用上了我们在popupWindow中定义的animation了 this.setAnimationStyle(android.R.style.Animation_Dialog); this.setContentView(mLinearLayout); ColorDrawable dw = new ColorDrawable(-00000); this.setBackgroundDrawable(dw); /*设置触摸外面时消失*/ this.setOutsideTouchable(true); //这里要设置为true,否则将无法响应popupWindow中控件的点击事件。 this.setFocusable(true); // this.update(); this.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { menuSize = 1; itemList.clear(); initDatas(); } }); } /** * 初始化popupWindow中的内容 */ public void initViewInWin(){ inflater = (LayoutInflater)mContext.getSystemService(mContext.LAYOUT_INFLATER_SERVICE); mLinearLayout = (RelativeLayout)inflater.inflate(R.layout.slide_menu, null); //这里需要设置成可以获取焦点,否则无法响应OnKey事件 mLinearLayout.setFocusable(true); mLinearLayout.setFocusableInTouchMode(true); //在这里设置,即可实现关闭的效果。 mLinearLayout.setOnKeyListener(new LayouOnKeyEvent()); mGridView = (GridView)mLinearLayout.findViewById(R.id.menu_gridView); //设置item点击响应的时间 mGridView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(menuSize == 1 && position == 5){ MyMenu_1.this.dismiss(); menuSize = 2; itemList.clear(); initDatas(); MyMenu_1.this.showAtLocation(mGridView.findViewById(R.id.menu_item_layout), Gravity.BOTTOM, 0, 0); } if(menuSize == 2 && position == 4){ MyMenu_1.this.dismiss(); MyMenu_1.this.showAtLocation(mGridView.findViewById(R.id.menu_item_layout), Gravity.BOTTOM, 0, 0); } } }); mGridView.setAdapter(adapter); } /** * 初始化数据内容 */ public void initDatas(){ int forStart = 0; int forEnd = 5; if(menuSize==1){ forStart = 0; forEnd = 5; } if(menuSize==2){ forStart = 6; forEnd = 6*2-1>titles.length-1?titles.length-1:6*2-1; } for(int i = forStart; i<=forEnd; i++){ HashMap<String,Object> map = new HashMap<String, Object>(); map.put("image", images[i]); map.put("title", titles[i]); itemList.add(map); } adapter = new SimpleAdapter(mContext, itemList, R.layout.my_menu_item, new String[]{"image","title"}, new int[]{R.id.item_image,R.id.item_title}); } class LayouOnKeyEvent implements OnKeyListener{ @Override public boolean onKey(View v, int keyCode, KeyEvent event) { menuSize = 1; itemList.clear(); initDatas(); MyMenu_1.this.showAtLocation(mGridView.findViewById(R.id.menu_item_layout), Gravity.BOTTOM, 0, 0); //判断事件为menu按钮按下时,将popupWindow关闭 if(event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_MENU){ if(MyMenu_1.this.isShowing()){ MyMenu_1.this.dismiss(); } } return true; } } }
3.slide_menu.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/gdi_arrow_up" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <FrameLayout android:id="@+id/gdi_header" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@id/gdi_arrow_up" android:background="@drawable/quick_action_top_frame" /> <GridView android:id="@+id/menu_gridView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:fadingEdgeLength="0.0dip" android:background="@drawable/quick_action_grid_bg" android:horizontalSpacing="10dip" android:listSelector="@drawable/quick_action_grid_selector" android:numColumns="3" android:padding="10dip" android:stretchMode="columnWidth" android:layout_below="@id/gdi_header" android:verticalSpacing="10dip" > </GridView> <FrameLayout android:id="@+id/gdi_footer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@id/menu_gridView" android:background="@drawable/quick_action_grid_bottom_frame" /> <ImageView android:id="@+id/gdi_arrow_down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/gdi_footer" /> </RelativeLayout>
4.my_menu_item.xml
<?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/menu_item_layout" android:layout_width="fill_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/item_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/item_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false" android:layout_below="@id/item_image" android:layout_centerHorizontal="true" /> </RelativeLayout>
很顺利的做出来了。效果和效果图一致,基本和apk里面的差不多,但是我觉得分页操作不是很方便,觉得android的滚屏左右滑动效果不错,
用到这个上面也还不错,于是开始查资料,发现viewPager和viewgroup都可以做,先用viewgroup做了一晚上,各种bug,快崩溃了。
于是换viewPager,中间虽然出了很多次问题,但是还是做出来了,效果如下:
直接上代码:
1.PopupMenuActivity
public class PopupMenuActivity extends Activity { private MyMenu myMenu; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onResume() { super.onResume(); myMenu = new MyMenu(PopupMenuActivity.this); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_MENU: if (myMenu.isShowing()) { myMenu.dismiss(); } else { myMenu.showAtLocation(findViewById(R.id.main_layout), Gravity.BOTTOM, 0, 0); } break; case KeyEvent.KEYCODE_BACK: myMenu.dismiss(); break; } return super.onKeyDown(keyCode, event); } }
2.Mymenu.java
public class MyMenu extends PopupWindow { private Context mContext; private LinearLayout mLinearLayout; private LinearLayout pointLLayout; private GridView mGridView1; private GridView mGridView2; private String[] titles = { "添加收藏夹", "查找短信", "新增短信", "定时任务", "发送报告", "更多", "设置", "关于", "帮助", "反馈", "返回" }; private int[] images = { R.drawable.icon_menu_favorite, R.drawable.icon_menu_search, R.drawable.icon_menu_add, R.drawable.icon_menu_schedule_task, R.drawable.icon_menu_view_sent_status, R.drawable.icon_menu_more, R.drawable.icon_menu_setting, R.drawable.icon_menu_info, R.drawable.icon_menu_help, R.drawable.icon_menu_feedback, R.drawable.icon_menu_back }; private List<HashMap<String, Object>> itemList1 = new ArrayList<HashMap<String, Object>>(); private List<HashMap<String, Object>> itemList2 = new ArrayList<HashMap<String, Object>>(); private MySimpleAdapter adapter1; private MySimpleAdapter adapter2; private LayoutInflater inflater; private ImageView[] imgs; private int count; private int currentItem; private MyViewPagerAdapter adapter; private MyViewPager viewPager; private ArrayList<GridView> array = new ArrayList<GridView>(); public MyMenu(Context context) { super(context); mContext = context; initDatas(); initViewInWin(); this.setWidth(LayoutParams.FILL_PARENT); this.setHeight(LayoutParams.WRAP_CONTENT); // 这里用上了我们在popupWindow中定义的animation了 this.setAnimationStyle(android.R.style.Animation_Dialog); this.setContentView(mLinearLayout); //必须设置背景色为透明,不然弹出窗口宽度不全屏 ColorDrawable dw = new ColorDrawable(-00000); this.setBackgroundDrawable(dw); /* 设置触摸外面时消失 */ this.setOutsideTouchable(true); // 这里要设置为true,否则将无法响应popupWindow中控件的点击事件。 this.setFocusable(true); this.update(); this.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { itemList1.clear(); itemList2.clear(); initDatas(); } }); pointLLayout = (LinearLayout) mLinearLayout.findViewById(R.id.llayout); viewPager = (MyViewPager) mLinearLayout.findViewById(R.id.myviewpager); count = viewPager.getChildCount(); imgs = new ImageView[count]; for (int i = 0; i < count; i++) { imgs[i] = (ImageView) pointLLayout.getChildAt(i); imgs[i].setEnabled(true); imgs[i].setTag(i); } currentItem = 0; imgs[currentItem].setEnabled(false); viewPager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int point) { setcurrentPoint(point); } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int point) { } }); adapter = new MyViewPagerAdapter(mContext, array); viewPager.setAdapter(adapter); } protected void setcurrentPoint(int position) { if (position < 0 || position > count - 1 || currentItem == position) { return; } imgs[currentItem].setEnabled(true); imgs[position].setEnabled(false); currentItem = position; } public void initViewInWin() { inflater = (LayoutInflater) mContext .getSystemService(mContext.LAYOUT_INFLATER_SERVICE); mLinearLayout = (LinearLayout) inflater.inflate(R.layout.my_menu, null); mLinearLayout.setFocusable(true); mLinearLayout.setFocusableInTouchMode(true); mLinearLayout.setOnKeyListener(new LayouOnKeyEvent()); mGridView1 = (GridView) mLinearLayout.findViewById(R.id.menu_gridView1); mGridView2 = (GridView) mLinearLayout.findViewById(R.id.menu_gridView2); mGridView1.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { System.out.println("点击第一个第" + position + "个按钮"); } }); mGridView1.setAdapter(adapter1); mGridView2.setAdapter(adapter2); array.add(mGridView1); array.add(mGridView2); } public void initDatas() { int forStart = 0; int forEnd = 5; for (int i = forStart; i <= forEnd; i++) { HashMap<String, Object> map = new HashMap<String, Object>(); map.put("image", images[i]); map.put("title", titles[i]); itemList1.add(map); } adapter1 = new MySimpleAdapter(mContext, itemList1, R.layout.my_menu_item, new String[] { "image", "title" }, new int[] { R.id.item_image, R.id.item_title }); forStart = 6; forEnd = 6 * 2 - 1 > titles.length - 1 ? titles.length - 1 : 6 * 2 - 1; for (int i = forStart; i <= forEnd; i++) { HashMap<String, Object> map = new HashMap<String, Object>(); map.put("image", images[i]); map.put("title", titles[i]); itemList2.add(map); } adapter2 = new MySimpleAdapter(mContext, itemList2, R.layout.my_menu_item, new String[] { "image", "title" }, new int[] { R.id.item_image, R.id.item_title }); } class LayouOnKeyEvent implements OnKeyListener { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { itemList1.clear(); itemList2.clear(); initDatas(); MyMenu.this.showAtLocation( mLinearLayout.findViewById(R.id.menu_item_layout), Gravity.BOTTOM, 0, 0); // 判断事件为menu按钮按下时,将popupWindow关闭 if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_MENU) { if (MyMenu.this.isShowing()) { MyMenu.this.dismiss(); } } return true; } } }
3.MySimpleAdapter 不用SimpleAdapter 而是自己写一个,因为报了一个The observer is null.查了下问题,应该是关闭window的时候setAdapter的时候unregisterDataSetObserver没判断mDataSetObserver是否为空,据说是因为嵌套控件导致,这里直接判断下就完了
public class MySimpleAdapter extends SimpleAdapter { public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) { super(context, data, resource, from, to); } @Override public void unregisterDataSetObserver(DataSetObserver observer) { if (observer != null) { super.unregisterDataSetObserver(observer); } } }
4.MyViewPager 继承了android.support.v4.view.ViewPager,因为这个控件高度自动全屏了 设置wrap_content也没用,这里集成了ViewPager重新设置了以下高度
public class MyViewPager extends ViewPager { public MyViewPager(Context context) { super(context); } public MyViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int height = 0; for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); int h = child.getMeasuredHeight(); if (h > height) height = h; } heightMeasureSpec = MeasureSpec.makeMeasureSpec(height*2, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
5.MyViewPagerAdapter重写了PagerAdapter
public class MyViewPagerAdapter extends PagerAdapter { private List<GridView> array; /** * 供外部调用(new)的方法 * * @param context * 上下�? * @param imageViews * 添加的序列对�? */ public MyViewPagerAdapter(Context context, List<GridView> array) { this.array = array; } @Override public int getCount() { // TODO Auto-generated method stub return array.size(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { // TODO Auto-generated method stub return arg0 == arg1; } @Override public Object instantiateItem(View arg0, int arg1) { ((ViewPager) arg0).addView(array.get(arg1)); return array.get(arg1); } @Override public void destroyItem(View arg0, int arg1, Object arg2) { ((ViewPager) arg0).removeView((View) arg2); } @Override public void unregisterDataSetObserver(DataSetObserver observer) { if (observer != null) { super.unregisterDataSetObserver(observer); } } }
6.my_menu.xml 注意这里最外层必须用LinearLayout,否则会报一个android.support.v4.view.ViewPager canot be cast to。。。。
转换异常,用RelativeLayout狂报错。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:id="@+id/gdi_arrow_up" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <FrameLayout android:id="@+id/gdi_header" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/quick_action_top_frame" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/renlayout" android:background="@drawable/quick_action_grid_bg" > <com.cbxjj.myplugins.MyViewPager android:layout_height="wrap_content" android:layout_width="match_parent" android:scaleType="fitXY" android:layout_gravity="center" android:id="@+id/myviewpager"> <GridView android:id="@+id/menu_gridView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:fadingEdgeLength="0.0dip" android:gravity="center" android:horizontalSpacing="10dip" android:listSelector="@drawable/quick_action_grid_selector" android:numColumns="3" android:padding="10dip" android:stretchMode="columnWidth" android:verticalSpacing="10dip" > </GridView> <GridView android:id="@+id/menu_gridView2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:fadingEdgeLength="0.0dip" android:gravity="center" android:horizontalSpacing="10dip" android:listSelector="@drawable/quick_action_grid_selector" android:numColumns="3" android:padding="10dip" android:stretchMode="columnWidth" android:verticalSpacing="10dip" > </GridView> </com.cbxjj.myplugins.MyViewPager> <LinearLayout android:orientation="horizontal" android:id="@+id/llayout" android:layout_width="fill_parent" android:layout_height="15dp" android:layout_below="@id/myviewpager" android:layout_centerHorizontal="true" android:gravity="center" android:visibility="visible"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:clickable="true" android:padding="5.0dip" android:src="@drawable/page_indicator_bg" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:clickable="true" android:padding="5.0dip" android:src="@drawable/page_indicator_bg" /> </LinearLayout> </RelativeLayout> <FrameLayout android:id="@+id/gdi_footer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/quick_action_grid_bottom_frame" > </FrameLayout> </LinearLayout>以上。
源码下载地址:http://download.csdn.net/detail/cbxjj/7513471
相关文章推荐
- Android学习小Demo(14)Android中关于PopupWindow的使用
- Android(java)学习笔记196:Android中Menu的使用(静态和动态)
- Android学习小Demo(14)Android中关于PopupWindow的使用
- Android的自定义Menu使用PopupWindow实现
- android 成长日记 1.学习使用menu
- android学习----(二)android模拟的使用
- Android学习之menu菜单使用与用户自定义View
- Android,安卓,toolbar,menu显示位置,及样式调整,及使用PopupWindow 实现menu下拉菜单gong
- Android学习小Demo(14)Android中关于PopupWindow的使用
- Android学习之Tab控件(使用TabHost和与Tab对应的Menu,动态更改Tabhost的Tab的背景图标,用到Ratingbar控件)
- android学习:菜单(Menu)的使用
- 【学习笔记】Android PopupWindow使用
- Android高手进阶教程(十)之----Android PopupWindow的使用!!!
- Android高手进阶教程(十)之----Android PopupWindow的使用!
- VS Feature Pack学习之使用CMFCMenuBar自定义菜单栏
- Android中使用硬盘模拟SD卡
- Android下Button/TextView/EditText/Menu的使用
- Android学习之menu
- Android学习之menu
- Android(OPhone) 学习笔记2 - Home API 的使用