android4.0之前的菜单使用非常广泛,但是在android4.0之后,很少使用先前的菜单样式了。那如何实现下图的样式了?
我们简单模拟一下。
(1)屏蔽系统弹出的菜单:
1、首先创建至少一个系统的菜单选项
[java]
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("menu");// 必须创建一项
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("menu");// 必须创建一项
return super.onCreateOptionsMenu(menu);
}2、在onMenuOpened方法里显示自己的菜单视图,并返回FALSE。 注意必须返回false,不然会出现menu选项
[java]
@Override
public boolean onMenuOpened(int featureId, Menu menu){
switchSysMenuShow();
return false;// 返回为true 则显示系统menu
}
@Override
public boolean onMenuOpened(int featureId, Menu menu){
switchSysMenuShow();
return false;// 返回为true 则显示系统menu
}
3、从图片中可以看出,弹出的是一个listview,所以要按照listview的标准来实现布局,给出布局文件。
[html]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingLeft="20dip"
android:gravity="right"
android:id="@+id/hotalk_menu_view_layout" >
<!-- 显示的listview -->
<ListView android:id="@+id/hotalk_menu_listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="7.6dip"
android:paddingRight="7.6dip"
android:fadingEdge="none"
android:focusable="true"
android:longClickable="true"
android:scrollbarSize="0sp"
android:scrollbarStyle="insideOverlay"
android:background="@drawable/menu_bg_popup"
android:divider="@drawable/menu_bg_line"
android:dividerHeight="1px"
android:cacheColorHint="#00000000">
</ListView>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingLeft="20dip"
android:gravity="right"
android:id="@+id/hotalk_menu_view_layout" >
<!-- 显示的listview -->
<ListView android:id="@+id/hotalk_menu_listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="7.6dip"
android:paddingRight="7.6dip"
android:fadingEdge="none"
android:focusable="true"
android:longClickable="true"
android:scrollbarSize="0sp"
android:scrollbarStyle="insideOverlay"
android:background="@drawable/menu_bg_popup"
android:divider="@drawable/menu_bg_line"
android:dividerHeight="1px"
android:cacheColorHint="#00000000">
</ListView>
</RelativeLayout>4、listview的显示其实就是个textview,给出该布局文件。
[html]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="@drawable/menu_item_bg"
android:orientation="vertical" >
<!-- 显示内容 -->
<TextView
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="40dip"
android:layout_marginLeft="12dip"
android:layout_marginRight="12dip"
android:paddingTop="6dip"
android:paddingBottom="6dip"
android:textSize="14.7sp"
android:gravity="center_vertical"
android:textColor="#CCCCCC"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="@drawable/menu_item_bg"
android:orientation="vertical" >
<!-- 显示内容 -->
<TextView
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="40dip"
android:layout_marginLeft="12dip"
android:layout_marginRight="12dip"
android:paddingTop="6dip"
android:paddingBottom="6dip"
android:textSize="14.7sp"
android:gravity="center_vertical"
android:textColor="#CCCCCC"/>
</LinearLayout>
下面给出实现这个的工具类HotalkMenuView,该类继承view[java]
package com.jindegege.demo;
import java.util.ArrayList;
import java.util.Collections;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Paint;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class HotalkMenuView extends View
{
/**
* 发送短信的模式 hotalk或者短信
*/
public final static int MENU_SEND_MSG_FORMULAR = 0;
/**
* 查看联系人
*/
public final static int MENU_VIEW_CONTACT = 1;
/**
* 添加联系人
*/
public final static int MENU_ADD_CONTACT = 2;
/**
* 群成员管理
*/
public final static int MENU_MEMBER_MANAGER = 3;
/**
* 批量收藏
*/
public final static int MENU_ADD_TO_FAVORITES = 4;
/**
* 批量删除
*/
public final static int MENU_DELETE_MULTI_MSG = 5;
/**
* 上下文
*/
private Context mContext;
/**
* PopupWindow
*/
private PopupWindow popWindow;
/**
* 显示View
*/
private View popview;
/**
* listview
*/
public ListView listview;
/**
* 填充数据集
*/
public ArrayList<MenuItem> mitems = null;
/**
* 设置显示位置
*/
RelativeLayout layout;
/**
* 横屏菜单距离最大高度
*/
private int bottomLenght_h = 77;
/**
* 竖屏菜单距离最大高度
*/
private int bottomLenght_v = 173;
/**
* 屏幕密度
*/
private Display display;
/**
* 画板用于测字符宽度
*/
private Paint paint = null;
/**
* 菜单中最在的字符宽度
*/
private float maxWeith = 0;
/**
* 显示靠左边菜单的左边距
*/
private int rightMenuLeft = 45;
/**
* 显示靠左边菜单的最大右边距
*/
private int maxRightWeith = 44;
/**
* 显示靠左边菜单的最小右边距
*/
private int minRightWeith = 140;
/**
* 菜单的最小左边距
*/
private int maxLeftWeith = 88;
/**
* 菜单的最小左边距
*/
private int minLeftWeith = 188;
/**
* 横屏菜单最小左边距
*/
private int maxLeftWeith_h = 282;
/**
* 横屏菜单最小左边距
*/
private int minLeftWeith_h = 371;
/**
* 菜单的背景和文字两边占间距
*/
private int contentSpaceWeith = 38;
/**
* 打开Menu动画
*/
private TranslateAnimation myMenuOpen;
/**
* 关闭Menu动画
*/
private TranslateAnimation myMenuClose;
/**
* 打开Menu动画所用时间
*/
private int menuOpenMillis = 500;
/**
* 关闭Menu动画 所用时间
*/
private int menuCloseMillis = 400;
/**
* 弹出窗口播放Menu的动画
*/
private final int MENU_OPEN_ANIM = 1;
/**
* 关闭Menu动画 后关闭窗口
*/
private final int MENU_CLOSE_ANIM = 2;
/**
* 当前窗口handler
*/
private MyHandler myHandler = new MyHandler();
/**
* 正在进行关闭Menu操作
*/
private boolean isDismissing = false;
class MyHandler extends Handler
{
@Override
public void handleMessage(Message msg)
{
if (msg == null)
{
return;
}
super.handleMessage(msg);
switch (msg.what)
{
case MENU_OPEN_ANIM:
startMenuOpenAnimation();
break;
case MENU_CLOSE_ANIM:
if(popWindow!=null){
popWindow.dismiss();
}
isDismissing = false;
break;
}
}
}
public HotalkMenuView(Context context)
{
super(context);
mContext = context;
mitems = new ArrayList<MenuItem>();
LayoutInflater layoutInflater = (LayoutInflater) (mContext).getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
// 获取自定义布局文件的视图
popview = layoutInflater.inflate(R.layout.hotalk_menu_view, null);
listview = (ListView) popview.findViewById(R.id.hotalk_menu_listview);
layout = (RelativeLayout) popview.findViewById(R.id.hotalk_menu_view_layout);
adapter = new ItemTextListAdapter(mContext);
popWindow = new PopupWindow(popview, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);//以PopupWindow弹出
display = ((WindowManager) mContext.getSystemService(mContext.WINDOW_SERVICE)).getDefaultDisplay();
initValue();
layout.setOnClickListener(onclick);
listview.setFocusable(false);
listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listview.setAdapter(adapter);
listview.setFocusableInTouchMode(true);
listview.setMinimumHeight(200);
listview.setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
// 正执行关闭Menu菜单操作将不重复操作
if (!isDismissing)
{
isDismissing = true;
if ((keyCode == KeyEvent.KEYCODE_MENU) && (popWindow.isShowing()))
{
close();
}
else if (((keyCode == KeyEvent.KEYCODE_BACK) && (popWindow.isShowing())))
{
close();
}
}
return false;
}
});
}
/**
* 初始设置Menu位置参数
*/
private void initValue()
{
paint = new Paint();
rightMenuLeft = (int) (rightMenuLeft * FusionField.currentDensity);
maxLeftWeith = (int) (maxLeftWeith * FusionField.currentDensity);
minLeftWeith = (int) (minLeftWeith * FusionField.currentDensity);
maxRightWeith = (int) (maxRightWeith * FusionField.currentDensity);
minRightWeith = (int) (minRightWeith * FusionField.currentDensity);
bottomLenght_h = (int) (bottomLenght_h * FusionField.currentDensity);
bottomLenght_v = (int) (bottomLenght_v * FusionField.currentDensity);
contentSpaceWeith = (int) (contentSpaceWeith * FusionField.currentDensity);
maxLeftWeith_h = (int) (maxLeftWeith_h * FusionField.currentDensity);
minLeftWeith_h = (int) (minLeftWeith_h * FusionField.currentDensity);
}
/**
* 添加菜单项
*
* @param key
* @param value
*/
public void add(int key, String value)
{
remove(key);
MenuItem item = new MenuItem(key, value);
mitems.add(item);
adapter.notifyDataSetChanged();
}
/**
* 添加 菜单项
*
* @param position 位置(必须是按0~n)添加
* @param key
* @param value
*/
public void add(int position, int key, String value)
{
MenuItem item = new MenuItem(key, value);
if (position == mitems.size())
{
mitems.add(position, item);
adapter.notifyDataSetChanged();
}
}
/**
* 获取文本最大长度
*/
private void getContextMaxLength()
{
adapter.notifyDataSetChanged();
if (mitems != null && mitems.size() > 0)
{
maxWeith = 0;
if (Build.VERSION.SDK_INT >= 14)
{
// android 4.0手机当前字体大小自适
TextView tv = new TextView(mContext);
tv.setTextSize(FusionField.SET_TYPE_TEXT_SIZE);
float size = tv.getTextSize() / FusionField.SET_TYPE_TEXT_SIZE;
paint.setTextSize((int) ((size * 12) * FusionField.currentDensity));
}
else
{
paint.setTextSize((int) ((FusionField.SET_TYPE_TEXT_SIZE + 1) * FusionField.currentDensity));
}
for (int i = 0; i < mitems.size(); i++)
{
if (paint.measureText(mitems.get(i).MenuValue) > maxWeith)
{
maxWeith = paint.measureText(mitems.get(i).MenuValue);
}
}
}
}
/**
* 更新菜单项按位置更新
*
* @param position
* @param key
* @param value
*/
public void updateItem(int position, int key, String value)
{
if (mitems.size() > position)
{
remover(position);
MenuItem item = new MenuItem(key, value);
mitems.add(position, item);
}
}
/**
* 删除菜单项
*
* @param position
*/
public void remover(int position)
{
if (mitems.size() > position)
{
mitems.remove(position);
}
}
/**
* 删除菜单项 add by shaxinajun
*
* @param position
*/
public void remove(int key)
{
MenuItem item = null;
for (int i = 0; i < mitems.size(); i++)
{
item = mitems.get(i);
if (item.MenuKey == key)
{
mitems.remove(i);
break;
}
}
}
/**
* 清空菜单项
*/
public void clear()
{
mitems.clear();
maxWeith = 0;
}
ItemTextListAdapter adapter;
/**
* 设置Menu显示位置,不可以自适应屏幕 密度 方法表述
*
* @param left
* @param top
* @param right
* @param bottom void
*/
public void setMenuPosition(int left, int top, int right, int bottom)
{
layout.setPadding(left, (int) (46 * FusionField.currentDensity), right, bottom);
}
/**
* 单击事件
*/
private OnClickListener onclick = new OnClickListener()
{
@Override
public void onClick(View v)
{
switch (v.getId())
{
// 点击空白外让其消失
case R.id.hotalk_menu_view_layout:
close();
break;
default:
break;
}
}
};
/**
* 重新设置菜单项
*
* @param list
*/
public void setItems(ArrayList<String> items)
{
mitems.clear();
if (items != null && items.size() > 0)
{
for (int i = 0; i < items.size(); i++)
{
MenuItem item = new MenuItem(0, items.get(i));
mitems.add(item);
}
}
}
public void setPositionShow()
{
try
{
if (popWindow != null && popview != null)
{
if (popWindow.isShowing())
{
startMenuCloseAnimation();
}
else
{
getContextMaxLength();
int right = (int) ((320 * FusionField.currentDensity) - (maxWeith + rightMenuLeft + contentSpaceWeith));
if (right < maxRightWeith)
{
right = maxRightWeith;
}
else if (right > minRightWeith)
{
right = minRightWeith;
}
//setMenuPosition(rightMenuLeft, 10, right, bottomLenght_v);
setMenuPosition(rightMenuLeft, 0, 0, bottomLenght_v);
Collections.sort(mitems);
// 规定弹窗的位置
popWindow.setFocusable(true);
popWindow.update();
popWindow.showAtLocation(popview, Gravity.FILL, 0, 0);
myHandler.sendEmptyMessage(MENU_OPEN_ANIM);
}
}
}
catch (Exception e)
{
Log.i("HotalkMenuView", "e:" + e.toString());
close();
}
}
/**
* 显示
*/
public void show()
{
try
{
if (popWindow != null && popview != null)
{
if (popWindow.isShowing())
{
startMenuCloseAnimation();
}
else
{
if (mitems != null && mitems.size() > 0)
{
int orientation = display.getOrientation();
if (orientation == 0)
{// 竖屏
if (FusionField.currentActivity != null
&& FusionField.currentActivity.getCurrentFocus() != null
&& FusionField.currentActivity.getCurrentFocus().getWindowToken() != null)
{
((InputMethodManager) FusionField.currentActivity
.getSystemService(FusionField.currentActivity.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(FusionField.currentActivity.getCurrentFocus()
.getWindowToken(), 0);
}
getContextMaxLength();
int left = (int) ((320 * FusionField.currentDensity) - (maxWeith + contentSpaceWeith));
if (left < maxLeftWeith)
{
left = maxLeftWeith;
}
else if (left > minLeftWeith)
{
left = minLeftWeith;
}
setMenuPosition(left, 0, 0, bottomLenght_v);
}
else
// 横屏
{
getContextMaxLength();
int left = (int) ((533 * FusionField.currentDensity) - (maxWeith + contentSpaceWeith));
Log.i("jindegege", "left:" + left + " rightMenuLeft:"
+ (480 * FusionField.currentDensity));
if (left < maxLeftWeith_h)
{
left = maxLeftWeith_h;
}
else if (left > minLeftWeith_h)
{
left = minLeftWeith_h;
}
setMenuPosition(left, 0, 0, bottomLenght_h);
}
Collections.sort(mitems);
// 规定弹窗的位置
popWindow.setFocusable(true);
popWindow.update();
popWindow.showAtLocation(listview, Gravity.FILL, 0, (int) (46 * FusionField.currentDensity));
myHandler.sendEmptyMessage(MENU_OPEN_ANIM);
}
}
}
}
catch (Exception e)
{
Log.i("HotalkMenuView", "show() e:" + e.toString());
close();
}
}
/**
* 判读是否显示
*
* @return boolean
*/
public boolean getIsShow()
{
return popWindow.isShowing();
}
/**
* 关闭
*/
public void close()
{
if (popWindow != null && popWindow.isShowing())
{
startMenuCloseAnimation();
}
}
/**
* 打开menu菜单窗口动画
*/
private void startMenuOpenAnimation()
{
// 由于打开菜单高度不一至所以根据菜单的高度来设置打开菜单时间
menuOpenMillis = (mitems.size() * 100) + 100;
if (menuOpenMillis > 500)
{
menuOpenMillis = 500;
}
myMenuOpen = new TranslateAnimation(0f, 0f, -(listview.getHeight() + 1), 0f);
myMenuOpen.setDuration(menuOpenMillis);
listview.startAnimation(myMenuOpen);
}
/**
* 关闭menu菜单窗口动画
*/
private void startMenuCloseAnimation()
{
myMenuClose = new TranslateAnimation(0f, 0f, 0f, -(listview.getHeight() + 1));
myMenuClose.setDuration(menuCloseMillis);
listview.startAnimation(myMenuClose);
myHandler.sendEmptyMessageDelayed(MENU_CLOSE_ANIM, menuCloseMillis);
}
public class ItemTextListAdapter extends SimpleAdapter
{
public ItemTextListAdapter(Context context)
{
super(context, null, 0, null, null);
}
@Override
public int getCount()
{
return mitems.size();
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ItemHolder holder;
if (convertView == null || convertView.getTag() == null || !(convertView.getTag() instanceof ItemHolder))
{
convertView = LayoutInflater.from(mContext).inflate(R.layout.hotalk_menu_item_view, null, true);
holder = new ItemHolder();
holder.menuName = (TextView) convertView.findViewById(R.id.textview);
}
else
{
holder = (ItemHolder) convertView.getTag(R.layout.hotalk_menu_item_view);
}
convertView.setTag(holder);
convertView.setTag(R.layout.hotalk_menu_item_view, holder);
MenuItem item = mitems.get(position);
holder.menuName.setText(item.MenuValue);
holder.menuName.setTextSize(FusionField.SET_TYPE_TEXT_SIZE);
convertView.setTag(item.MenuKey);
return convertView;
}
}
public static class ItemHolder
{
TextView menuName;
}
public class MenuItem implements Comparable
{
int MenuKey;
String MenuValue;
public MenuItem(int key, String value)
{
MenuKey = key;
MenuValue = value;
}
@Override
public int compareTo(Object o)
{
// TODO Auto-generated method stub
return this.MenuKey - ((MenuItem) o).MenuKey;
}
}
}
package com.jindegege.demo;
import java.util.ArrayList;
import java.util.Collections;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Paint;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class HotalkMenuView extends View
{
/**
* 发送短信的模式 hotalk或者短信
*/
public final static int MENU_SEND_MSG_FORMULAR = 0;
/**
* 查看联系人
*/
public final static int MENU_VIEW_CONTACT = 1;
/**
* 添加联系人
*/
public final static int MENU_ADD_CONTACT = 2;
/**
* 群成员管理
*/
public final static int MENU_MEMBER_MANAGER = 3;
/**
* 批量收藏
*/
public final static int MENU_ADD_TO_FAVORITES = 4;
/**
* 批量删除
*/
public final static int MENU_DELETE_MULTI_MSG = 5;
/**
* 上下文
*/
private Context mContext;
/**
* PopupWindow
*/
private PopupWindow popWindow;
/**
* 显示View
*/
private View popview;
/**
* listview
*/
public ListView listview;
/**
* 填充数据集
*/
public ArrayList<MenuItem> mitems = null;
/**
* 设置显示位置
*/
RelativeLayout layout;
/**
* 横屏菜单距离最大高度
*/
private int bottomLenght_h = 77;
/**
* 竖屏菜单距离最大高度
*/
private int bottomLenght_v = 173;
/**
* 屏幕密度
*/
private Display display;
/**
* 画板用于测字符宽度
*/
private Paint paint = null;
/**
* 菜单中最在的字符宽度
*/
private float maxWeith = 0;
/**
* 显示靠左边菜单的左边距
*/
private int rightMenuLeft = 45;
/**
* 显示靠左边菜单的最大右边距
*/
private int maxRightWeith = 44;
/**
* 显示靠左边菜单的最小右边距
*/
private int minRightWeith = 140;
/**
* 菜单的最小左边距
*/
private int maxLeftWeith = 88;
/**
* 菜单的最小左边距
*/
private int minLeftWeith = 188;
/**
* 横屏菜单最小左边距
*/
private int maxLeftWeith_h = 282;
/**
* 横屏菜单最小左边距
*/
private int minLeftWeith_h = 371;
/**
* 菜单的背景和文字两边占间距
*/
private int contentSpaceWeith = 38;
/**
* 打开Menu动画
*/
private TranslateAnimation myMenuOpen;
/**
* 关闭Menu动画
*/
private TranslateAnimation myMenuClose;
/**
* 打开Menu动画所用时间
*/
private int menuOpenMillis = 500;
/**
* 关闭Menu动画 所用时间
*/
private int menuCloseMillis = 400;
/**
* 弹出窗口播放Menu的动画
*/
private final int MENU_OPEN_ANIM = 1;
/**
* 关闭Menu动画 后关闭窗口
*/
private final int MENU_CLOSE_ANIM = 2;
/**
* 当前窗口handler
*/
private MyHandler myHandler = new MyHandler();
/**
* 正在进行关闭Menu操作
*/
private boolean isDismissing = false;
class MyHandler extends Handler
{
@Override
public void handleMessage(Message msg)
{
if (msg == null)
{
return;
}
super.handleMessage(msg);
switch (msg.what)
{
case MENU_OPEN_ANIM:
startMenuOpenAnimation();
break;
case MENU_CLOSE_ANIM:
if(popWindow!=null){
popWindow.dismiss();
}
isDismissing = false;
break;
}
}
}
public HotalkMenuView(Context context)
{
super(context);
mContext = context;
mitems = new ArrayList<MenuItem>();
LayoutInflater layoutInflater = (LayoutInflater) (mContext).getSystemService(mContext.LAYOUT_INFLATER_SERVICE);
// 获取自定义布局文件的视图
popview = layoutInflater.inflate(R.layout.hotalk_menu_view, null);
listview = (ListView) popview.findViewById(R.id.hotalk_menu_listview);
layout = (RelativeLayout) popview.findViewById(R.id.hotalk_menu_view_layout);
adapter = new ItemTextListAdapter(mContext);
popWindow = new PopupWindow(popview, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);//以PopupWindow弹出
display = ((WindowManager) mContext.getSystemService(mContext.WINDOW_SERVICE)).getDefaultDisplay();
initValue();
layout.setOnClickListener(onclick);
listview.setFocusable(false);
listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listview.setAdapter(adapter);
listview.setFocusableInTouchMode(true);
listview.setMinimumHeight(200);
listview.setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
// 正执行关闭Menu菜单操作将不重复操作
if (!isDismissing)
{
isDismissing = true;
if ((keyCode == KeyEvent.KEYCODE_MENU) && (popWindow.isShowing()))
{
close();
}
else if (((keyCode == KeyEvent.KEYCODE_BACK) && (popWindow.isShowing())))
{
close();
}
}
return false;
}
});
}
/**
* 初始设置Menu位置参数
*/
private void initValue()
{
paint = new Paint();
rightMenuLeft = (int) (rightMenuLeft * FusionField.currentDensity);
maxLeftWeith = (int) (maxLeftWeith * FusionField.currentDensity);
minLeftWeith = (int) (minLeftWeith * FusionField.currentDensity);
maxRightWeith = (int) (maxRightWeith * FusionField.currentDensity);
minRightWeith = (int) (minRightWeith * FusionField.currentDensity);
bottomLenght_h = (int) (bottomLenght_h * FusionField.currentDensity);
bottomLenght_v = (int) (bottomLenght_v * FusionField.currentDensity);
contentSpaceWeith = (int) (contentSpaceWeith * FusionField.currentDensity);
maxLeftWeith_h = (int) (maxLeftWeith_h * FusionField.currentDensity);
minLeftWeith_h = (int) (minLeftWeith_h * FusionField.currentDensity);
}
/**
* 添加菜单项
*
* @param key
* @param value
*/
public void add(int key, String value)
{
remove(key);
MenuItem item = new MenuItem(key, value);
mitems.add(item);
adapter.notifyDataSetChanged();
}
/**
* 添加 菜单项
*
* @param position 位置(必须是按0~n)添加
* @param key
* @param value
*/
public void add(int position, int key, String value)
{
MenuItem item = new MenuItem(key, value);
if (position == mitems.size())
{
mitems.add(position, item);
adapter.notifyDataSetChanged();
}
}
/**
* 获取文本最大长度
*/
private void getContextMaxLength()
{
adapter.notifyDataSetChanged();
if (mitems != null && mitems.size() > 0)
{
maxWeith = 0;
if (Build.VERSION.SDK_INT >= 14)
{
// android 4.0手机当前字体大小自适
TextView tv = new TextView(mContext);
tv.setTextSize(FusionField.SET_TYPE_TEXT_SIZE);
float size = tv.getTextSize() / FusionField.SET_TYPE_TEXT_SIZE;
paint.setTextSize((int) ((size * 12) * FusionField.currentDensity));
}
else
{
paint.setTextSize((int) ((FusionField.SET_TYPE_TEXT_SIZE + 1) * FusionField.currentDensity));
}
for (int i = 0; i < mitems.size(); i++)
{
if (paint.measureText(mitems.get(i).MenuValue) > maxWeith)
{
maxWeith = paint.measureText(mitems.get(i).MenuValue);
}
}
}
}
/**
* 更新菜单项按位置更新
*
* @param position
* @param key
* @param value
*/
public void updateItem(int position, int key, String value)
{
if (mitems.size() > position)
{
remover(position);
MenuItem item = new MenuItem(key, value);
mitems.add(position, item);
}
}
/**
* 删除菜单项
*
* @param position
*/
public void remover(int position)
{
if (mitems.size() > position)
{
mitems.remove(position);
}
}
/**
* 删除菜单项 add by shaxinajun
*
* @param position
*/
public void remove(int key)
{
MenuItem item = null;
for (int i = 0; i < mitems.size(); i++)
{
item = mitems.get(i);
if (item.MenuKey == key)
{
mitems.remove(i);
break;
}
}
}
/**
* 清空菜单项
*/
public void clear()
{
mitems.clear();
maxWeith = 0;
}
ItemTextListAdapter adapter;
/**
* 设置Menu显示位置,不可以自适应屏幕 密度 方法表述
*
* @param left
* @param top
* @param right
* @param bottom void
*/
public void setMenuPosition(int left, int top, int right, int bottom)
{
layout.setPadding(left, (int) (46 * FusionField.currentDensity), right, bottom);
}
/**
* 单击事件
*/
private OnClickListener onclick = new OnClickListener()
{
@Override
public void onClick(View v)
{
switch (v.getId())
{
// 点击空白外让其消失
case R.id.hotalk_menu_view_layout:
close();
break;
default:
break;
}
}
};
/**
* 重新设置菜单项
*
* @param list
*/
public void setItems(ArrayList<String> items)
{
mitems.clear();
if (items != null && items.size() > 0)
{
for (int i = 0; i < items.size(); i++)
{
MenuItem item = new MenuItem(0, items.get(i));
mitems.add(item);
}
}
}
public void setPositionShow()
{
try
{
if (popWindow != null && popview != null)
{
if (popWindow.isShowing())
{
startMenuCloseAnimation();
}
else
{
getContextMaxLength();
int right = (int) ((320 * FusionField.currentDensity) - (maxWeith + rightMenuLeft + contentSpaceWeith));
if (right < maxRightWeith)
{
right = maxRightWeith;
}
else if (right > minRightWeith)
{
right = minRightWeith;
}
//setMenuPosition(rightMenuLeft, 10, right, bottomLenght_v);
setMenuPosition(rightMenuLeft, 0, 0, bottomLenght_v);
Collections.sort(mitems);
// 规定弹窗的位置
popWindow.setFocusable(true);
popWindow.update();
popWindow.showAtLocation(popview, Gravity.FILL, 0, 0);
myHandler.sendEmptyMessage(MENU_OPEN_ANIM);
}
}
}
catch (Exception e)
{
Log.i("HotalkMenuView", "e:" + e.toString());
close();
}
}
/**
* 显示
*/
public void show()
{
try
{
if (popWindow != null && popview != null)
{
if (popWindow.isShowing())
{
startMenuCloseAnimation();
}
else
{
if (mitems != null && mitems.size() > 0)
{
int orientation = display.getOrientation();
if (orientation == 0)
{// 竖屏
if (FusionField.currentActivity != null
&& FusionField.currentActivity.getCurrentFocus() != null
&& FusionField.currentActivity.getCurrentFocus().getWindowToken() != null)
{
((InputMethodManager) FusionField.currentActivity
.getSystemService(FusionField.currentActivity.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(FusionField.currentActivity.getCurrentFocus()
.getWindowToken(), 0);
}
getContextMaxLength();
int left = (int) ((320 * FusionField.currentDensity) - (maxWeith + contentSpaceWeith));
if (left < maxLeftWeith)
{
left = maxLeftWeith;
}
else if (left > minLeftWeith)
{
left = minLeftWeith;
}
setMenuPosition(left, 0, 0, bottomLenght_v);
}
else
// 横屏
{
getContextMaxLength();
int left = (int) ((533 * FusionField.currentDensity) - (maxWeith + contentSpaceWeith));
Log.i("jindegege", "left:" + left + " rightMenuLeft:"
+ (480 * FusionField.currentDensity));
if (left < maxLeftWeith_h)
{
left = maxLeftWeith_h;
}
else if (left > minLeftWeith_h)
{
left = minLeftWeith_h;
}
setMenuPosition(left, 0, 0, bottomLenght_h);
}
Collections.sort(mitems);
// 规定弹窗的位置
popWindow.setFocusable(true);
popWindow.update();
popWindow.showAtLocation(listview, Gravity.FILL, 0, (int) (46 * FusionField.currentDensity));
myHandler.sendEmptyMessage(MENU_OPEN_ANIM);
}
}
}
}
catch (Exception e)
{
Log.i("HotalkMenuView", "show() e:" + e.toString());
close();
}
}
/**
* 判读是否显示
*
* @return boolean
*/
public boolean getIsShow()
{
return popWindow.isShowing();
}
/**
* 关闭
*/
public void close()
{
if (popWindow != null && popWindow.isShowing())
{
startMenuCloseAnimation();
}
}
/**
* 打开menu菜单窗口动画
*/
private void startMenuOpenAnimation()
{
// 由于打开菜单高度不一至所以根据菜单的高度来设置打开菜单时间
menuOpenMillis = (mitems.size() * 100) + 100;
if (menuOpenMillis > 500)
{
menuOpenMillis = 500;
}
myMenuOpen = new TranslateAnimation(0f, 0f, -(listview.getHeight() + 1), 0f);
myMenuOpen.setDuration(menuOpenMillis);
listview.startAnimation(myMenuOpen);
}
/**
* 关闭menu菜单窗口动画
*/
private void startMenuCloseAnimation()
{
myMenuClose = new TranslateAnimation(0f, 0f, 0f, -(listview.getHeight() + 1));
myMenuClose.setDuration(menuCloseMillis);
listview.startAnimation(myMenuClose);
myHandler.sendEmptyMessageDelayed(MENU_CLOSE_ANIM, menuCloseMillis);
}
public class ItemTextListAdapter extends SimpleAdapter
{
public ItemTextListAdapter(Context context)
{
super(context, null, 0, null, null);
}
@Override
public int getCount()
{
return mitems.size();
}
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ItemHolder holder;
if (convertView == null || convertView.getTag() == null || !(convertView.getTag() instanceof ItemHolder))
{
convertView = LayoutInflater.from(mContext).inflate(R.layout.hotalk_menu_item_view, null, true);
holder = new ItemHolder();
holder.menuName = (TextView) convertView.findViewById(R.id.textview);
}
else
{
holder = (ItemHolder) convertView.getTag(R.layout.hotalk_menu_item_view);
}
convertView.setTag(holder);
convertView.setTag(R.layout.hotalk_menu_item_view, holder);
MenuItem item = mitems.get(position);
holder.menuName.setText(item.MenuValue);
holder.menuName.setTextSize(FusionField.SET_TYPE_TEXT_SIZE);
convertView.setTag(item.MenuKey);
return convertView;
}
}
public static class ItemHolder
{
TextView menuName;
}
public class MenuItem implements Comparable
{
int MenuKey;
String MenuValue;
public MenuItem(int key, String value)
{
MenuKey = key;
MenuValue = value;
}
@Override
public int compareTo(Object o)
{
// TODO Auto-generated method stub
return this.MenuKey - ((MenuItem) o).MenuKey;
}
}
}
在这个工具类中,构造方法是关键,在这里新建了一个adapter对象有用填充listview中的数据,
adapter = new ItemTextListAdapter(mContext);
构造了一个popupWindow对象,传入的三个对象依次表示,popview这个listview对象,弹出的宽、高都是
[java]
FILL_PARENT,
FILL_PARENT,[java]
popWindow = new PopupWindow(popview, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);//以PopupWindow弹出
popWindow = new PopupWindow(popview, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);//以PopupWindow弹出[java]
5、下面就给出activity类
5、下面就给出activity类[java]
<pre name="code" class="java">package com.jindegege.demo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
public class MenudemoActivity extends Activity {
/**
* 系统菜单定制控件
*/
public HotalkMenuView menuListView = null;
/**
* 原来系统menu菜单全部移到这里操作
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
/**
* 系统菜单初始化 void
*/
private void initSysMenu()
{
if (menuListView == null)
{
menuListView = new HotalkMenuView(this);
}
menuListView.listview.setOnItemClickListener(listClickListener);
menuListView.clear();
// 添加按位置添加
menuListView.add(HotalkMenuView.MENU_SEND_MSG_FORMULAR, getString(R.string.currFormularStr));
menuListView.add(HotalkMenuView.MENU_VIEW_CONTACT, getString(R.string.chat_search_card));
menuListView.add(HotalkMenuView.MENU_ADD_CONTACT, getString(R.string.chat_menu_addtocontact));
menuListView.add(HotalkMenuView.MENU_DELETE_MULTI_MSG, getString(R.string.chat_menu_delete_msg));
menuListView.add(HotalkMenuView.MENU_ADD_TO_FAVORITES, getString(R.string.multi_favorites));
}
protected void switchSysMenuShow()
{
// 初始化系统菜单
initSysMenu();
if (!menuListView.getIsShow())
{
menuListView.show();
}
else
{
menuListView.close();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("menu");// 必须创建一项
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onMenuOpened(int featureId, Menu menu){
switchSysMenuShow();
return false;// 返回为true 则显示系统menu
}
/**
* 菜单点击事件处理
*/
OnItemClickListener listClickListener = new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3)
{
// 获取key唯一标识
int key = Integer.parseInt(view.getTag().toString());
// 跳转
switch (key)
{
case HotalkMenuView.MENU_SEND_MSG_FORMULAR:
//editFormular();
break;
case HotalkMenuView.MENU_VIEW_CONTACT:
break;
case HotalkMenuView.MENU_ADD_CONTACT:
break;
case HotalkMenuView.MENU_DELETE_MULTI_MSG:
break;
case HotalkMenuView.MENU_ADD_TO_FAVORITES:
break;
default:
break;
}
// 关闭
menuListView.close();
}
};
}
<pre name="code" class="java">package com.jindegege.demo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
public class MenudemoActivity extends Activity {
/**
* 系统菜单定制控件
*/
public HotalkMenuView menuListView = null;
/**
* 原来系统menu菜单全部移到这里操作
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
/**
* 系统菜单初始化 void
*/
private void initSysMenu()
{
if (menuListView == null)
{
menuListView = new HotalkMenuView(this);
}
menuListView.listview.setOnItemClickListener(listClickListener);
menuListView.clear();
// 添加按位置添加
menuListView.add(HotalkMenuView.MENU_SEND_MSG_FORMULAR, getString(R.string.currFormularStr));
menuListView.add(HotalkMenuView.MENU_VIEW_CONTACT, getString(R.string.chat_search_card));
menuListView.add(HotalkMenuView.MENU_ADD_CONTACT, getString(R.string.chat_menu_addtocontact));
menuListView.add(HotalkMenuView.MENU_DELETE_MULTI_MSG, getString(R.string.chat_menu_delete_msg));
menuListView.add(HotalkMenuView.MENU_ADD_TO_FAVORITES, getString(R.string.multi_favorites));
}
protected void switchSysMenuShow()
{
// 初始化系统菜单
initSysMenu();
if (!menuListView.getIsShow())
{
menuListView.show();
}
else
{
menuListView.close();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add("menu");// 必须创建一项
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onMenuOpened(int featureId, Menu menu){
switchSysMenuShow();
return false;// 返回为true 则显示系统menu
}
/**
* 菜单点击事件处理
*/
OnItemClickListener listClickListener = new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3)
{
// 获取key唯一标识
int key = Integer.parseInt(view.getTag().toString());
// 跳转
switch (key)
{
case HotalkMenuView.MENU_SEND_MSG_FORMULAR:
//editFormular();
break;
case HotalkMenuView.MENU_VIEW_CONTACT:
break;
case HotalkMenuView.MENU_ADD_CONTACT:
break;
case HotalkMenuView.MENU_DELETE_MULTI_MSG:
break;
case HotalkMenuView.MENU_ADD_TO_FAVORITES:
break;
default:
break;
}
// 关闭
menuListView.close();
}
};
}
要实现项目中的效果,还必须有其他许多东西,在这里无法演示,大家可以自行去研究,然后补充设计更好的效果
[java]
给出demo的下载地址供大家研究
给出demo的下载地址供大家研究[java]
<a href="http://download.csdn.net/detail/jindegegesun/4339121">http://download.csdn.net/detail/jindegegesun/4339121</a>
<a href="http://download.csdn.net/detail/jindegegesun/4339121">http://download.csdn.net/detail/jindegegesun/4339121</a>
摘自 jindegegesun的专栏