您的位置:首页 > 移动开发 > Android开发

【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

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: