最近在写安卓APP时需要用到弹出式菜单,系统内置的弹出式菜单有些不和谐,原本的导航菜单都有图标和复选按钮,但是变成弹出式菜单后都没有了,网上找了一个部分解决图标问题,但是这仅能解决图标问题,复选按钮,分割条这些都美没有的,看起来一堆,不爽,后来参考了一些自定义弹出式菜单,自己写了一个弹出式菜单类,个人感觉用起来还不错,这里将源码分享出来。主要用了弹窗类的实现吗,共两个类文件。完整代码如下:
MenuItem.java文件
package com.xmks.Intelligent.lighting.menu; //这里的包名称根据自己的包进行修改
import android.graphics.drawable.Drawable;
public class MenuItem {
private String itemKey;
private String itemTitle=null;
private Drawable itemIcon=null;
private boolean splitLine=false;
private boolean switchItem=false;
private boolean switchChecked=false;
private boolean selected=false;
private boolean visibility=true;
private boolean enabled=true;
public interface OnMenuItemChange{
void onChange(MenuItem item,String attributeName,Object value);
}
private OnMenuItemChange onMenuItemChange=null;
public MenuItem(String key){
this.itemKey=key;
}
public MenuItem(String key,boolean splitLine){
this.itemKey=key;
this.splitLine=splitLine;
this.selected=false;
}
public MenuItem(String key,String title){
this(key,title,null);
}
public MenuItem(String key,String title,Drawable icon){
this(key,title,icon,false);
}
public MenuItem(String key,String title,Drawable icon,boolean switchItem){
this(key,title,icon,switchItem,false);
}
public MenuItem(String key,String title,Drawable icon,boolean switchItem,boolean selected){
this.itemKey=key;
this.itemTitle=title;
this.itemIcon=icon;
this.switchItem=switchItem;
this.selected=selected;
}
public void setItemTitle(String itemTitle) {
if(this.isSplitLine()) {
this.itemTitle = null;
}else{
if(this.itemTitle==null||this.itemTitle.length()==0) {
if(itemTitle!=null && itemTitle.length()>0) {
this.itemTitle = itemTitle;
if (onMenuItemChange != null) {
onMenuItemChange.onChange(this, "itemTitle", itemIcon);
}
}
}else if(this.itemTitle!=null||this.itemTitle.length()>0){
if(!this.itemTitle.equals(itemTitle)){
this.itemTitle = itemTitle;
if (onMenuItemChange != null) {
onMenuItemChange.onChange(this, "itemTitle", itemIcon);
}
}
}
}
}
public String getItemTitle() {
return itemTitle;
}
public void setItemIcon(Drawable itemIcon) {
if(this.isSplitLine()){
this.itemIcon = null;
}else {
if(this.itemIcon==null && itemIcon!=null){
this.itemIcon = itemIcon;
if (onMenuItemChange != null) {
onMenuItemChange.onChange(this, "itemIcon", itemIcon);
}
}else if(this.itemIcon!=null && !this.itemIcon.equals(itemIcon)){
this.itemIcon = itemIcon;
if (onMenuItemChange != null) {
onMenuItemChange.onChange(this, "itemIcon", itemIcon);
}
}
}
}
public Drawable getItemIcon() {
return itemIcon;
}
public void setSwitchItem(boolean switchItem) {
if(this.isSplitLine()){
this.switchItem =false; //项目为分割线是禁止拥有Switch
}else {
if( this.switchItem != switchItem) {
this.switchItem = switchItem;
if (onMenuItemChange != null) {
onMenuItemChange.onChange(this, "switchItem", switchItem);
}
}
}
}
public boolean isSwitchItem() {
return switchItem;
}
public void setSwitchChecked(boolean switchChecked) {
if(!this.isSwitchItem()){
this.switchChecked =false;
}else {
if(this.switchChecked != switchChecked) {
this.switchChecked = switchChecked;
// if (onMenuItemChange != null) {
// onMenuItemChange.onChange(this, "switchChecked", switchChecked);
// }
}
}
}
public boolean isSwitchChecked() {
return switchChecked;
}
public void setSelected(boolean selected) {
if(this.isSplitLine()){
this.selected = false; //项目为分割线是禁止选择
}else{
if(this.selected!=selected) {
this.selected = selected;
if (onMenuItemChange != null) {
onMenuItemChange.onChange(this, "selected", selected);
}
}
}
}
public boolean isSelected() {
return selected;
}
public boolean isSplitLine() {
return splitLine;
}
public void setItemKey(String key) {
this.itemKey = key;
}
public String getItemKey() {
return itemKey;
}
public void setVisibility(boolean visibility) {
if(this.visibility!=visibility) {
this.visibility = visibility;
if (onMenuItemChange != null) {
onMenuItemChange.onChange(this, "visibility", visibility);
}
}
}
public boolean isVisibility() {
return visibility;
}
public void setEnabled(boolean enabled) {
if(this.isSplitLine()) {
this.enabled=true;
}else{
if (this.enabled != enabled) {
this.enabled = enabled;
if (onMenuItemChange != null) {
onMenuItemChange.onChange(this, "enabled", enabled);
}
}
}
}
public boolean isEnabled() {
return enabled;
}
public void setOnMenuItemChange(OnMenuItemChange onMenuItemChange) {
this.onMenuItemChange = onMenuItemChange;
}
}
DropMenu.java
package com.xmks.Intelligent.lighting.menu;//这里的包名称根据自己的包进行修改
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.Space;
import android.widget.Switch;
import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;
import static android.widget.ListPopupWindow.MATCH_PARENT;
import static android.widget.ListPopupWindow.WRAP_CONTENT;
public class DropMenu {
private final static String TAG="DropMenu";
private PopupWindow mPopupWindow=null;
private View mAnchor=null;
private int mGravity=Gravity.NO_GRAVITY;
private int xOffset=0,yOffset=0;
private LinearLayout mContainerLayout =null;
private Context mContext;
private float menuWidth;
private float menuHeight;
private float offset;
private float iconSize;
private float spaceWidth;
private float itemHeight;
public interface OnMenuItemClickListener{
void onMenuItemClick(MenuItem item,View view);
}
public interface OnSwitchCheckedChangeListener{
void onCheckedChanged(MenuItem item,CompoundButton buttonView, boolean isChecked);
}
private OnMenuItemClickListener menuItemClickListener=null;
private OnSwitchCheckedChangeListener switchCheckedChangeListener=null;
public DropMenu(@NonNull Context context, @NonNull View anchor){
this(context,anchor,Gravity.NO_GRAVITY);
}
public DropMenu(@NonNull Context context, @NonNull View anchor,int gravity){
this(context,anchor,0,0,gravity);
}
public DropMenu(@NonNull Context context, @NonNull View anchor,int xoff,int yoff){
this(context,anchor,0,0,Gravity.NO_GRAVITY);
}
public DropMenu(@NonNull Context context, @NonNull View anchor,int xoff,int yoff,int gravity){
this.mContext=context;
this.mAnchor=anchor;
this.xOffset=xoff;
this.yOffset=yoff;
this.mGravity=gravity;
this.menuWidth=dp2px(context,100);
//预留阴影区域
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
this.menuHeight = dp2px(context, 5);
}else{
this.menuHeight = dp2px(context, 1.5f);
}
this.itemHeight=dp2px(context,32);
this.offset=dp2px(context,5);
this.iconSize=dp2px(context,24);
this.spaceWidth=dp2px(context,32);
createPopup();
}
public boolean addMenuItem(String key,@StringRes int titleResId){
return addMenuItem(key,titleResId,0);
}
public boolean addMenuItem(String key,@StringRes int titleResId,@DrawableRes int resIconId){
return addMenuItem(key,titleResId,resIconId,false,false);
}
public boolean addMenuItem(String key,@StringRes int titleResId,@DrawableRes int resIconId,boolean switchItem,boolean switchItemChecked){
return addMenuItem(key,titleResId,resIconId,switchItem,switchItemChecked,false);
}
public boolean addMenuItem(String key,@StringRes int titleResId, @DrawableRes int resIconId, boolean switchItem, boolean switchItemChecked, boolean selectedItem){
return addMenuItem(key,mContext.getResources().getString(titleResId),mContext.getResources().getDrawable(resIconId),switchItem,switchItemChecked,selectedItem);
}
public boolean addMenuItem(String key,String title,@DrawableRes int resIconId){
return addMenuItem(key,title,resIconId,false,false);
}
public boolean addMenuItem(String key,String title,@DrawableRes int resIconId,boolean switchItem,boolean switchItemChecked){
return addMenuItem(key,title,resIconId,switchItem,switchItemChecked,false);
}
public boolean addMenuItem(String key,String title,@DrawableRes int resIconId,boolean switchItem,boolean switchItemChecked,boolean selectedItem){
return addMenuItem(key,title,mContext.getResources().getDrawable(resIconId),switchItem,switchItemChecked,selectedItem);
}
public boolean addMenuItem(String key,String title){
return addMenuItem(key,title,null);
}
public boolean addMenuItem(String key,String title,Drawable icon){
return addMenuItem(key,title,icon,false,false);
}
public boolean addMenuItem(String key,String title,Drawable icon,boolean switchItem,boolean switchItemChecked){
return addMenuItem(key,title,icon,switchItem,switchItemChecked,false);
}
public boolean addMenuItem(String key,String title,Drawable icon,boolean switchItem,
boolean switchItemChecked,boolean selectedItem){
return addMenuItem(-1,key,title,icon,switchItem,switchItemChecked,selectedItem);
}
public boolean addMenuItem(int index,String key,String title,@DrawableRes int resIconId){
return addMenuItem(index,key,title,resIconId,false,false);
}
public boolean addMenuItem(int index,String key,String title,@DrawableRes int resIconId,boolean switchItem,boolean switchItemChecked){
return addMenuItem(index,key,title,resIconId,switchItem,switchItemChecked,false);
}
public boolean addMenuItem(int index,String key,String title,@DrawableRes int resIconId,
boolean switchItem,boolean switchItemChecked,boolean selectedItem){
return addMenuItem(index,key,title,mContext.getResources().getDrawable(resIconId),
switchItem,switchItemChecked,selectedItem);
}
public boolean addMenuItem(int index,String key,String title){
return addMenuItem(index,key,title,null);
}
public boolean addMenuItem(int index,String key,String title,Drawable icon){
return addMenuItem(index,key,title,icon,false,false);
}
public boolean addMenuItem(int index,String key,String title,Drawable icon,boolean switchItem,boolean switchItemChecked){
return addMenuItem(index,key,title,icon,switchItem,switchItemChecked,false);
}
public boolean addMenuItem(int index,String key,String title,Drawable icon,boolean switchItem,
boolean switchItemChecked,boolean selectedItem){
MenuItem menuItem=new MenuItem(key,title,icon,switchItem,selectedItem);
menuItem.setSwitchChecked(switchItemChecked);
return addMenuItem(index,menuItem);
}
public boolean addMenuItem(MenuItem menuItem){
return addMenuItem(-1,menuItem);
}
public boolean addMenuItem(int index,MenuItem menuItem){
if(isMenuItemKeyOnly(menuItem.getItemKey())) {
if(menuItem.isSelected()){
for(int pos=0;pos
MenuItem item= (MenuItem)mContainerLayout.getChildAt(pos).getTag();
if(item!=null){
item.setSelected(false);
}
}
}
createMenuItemView(index, menuItem);
menuItem.setOnMenuItemChange(menuItemChange); //设置菜单改变事件侦听
return true;
}else{
return false;
}
}
public boolean addSplitLine(){
return addSplitLine(-1);
}
public boolean addSplitLine(int index){
String key="splitLine";
int id=0;
//生成唯一关键字
do{
id++;
}while (!isMenuItemKeyOnly(key+id));
return addSplitLine(key+id,index);
}
public boolean addSplitLine(String key){
return addSplitLine(key,-1);
}
public boolean addSplitLine(String key,int index){
if(isMenuItemKeyOnly(key)) { //检测关键字是否唯一
MenuItem menuItem = new MenuItem(key, true);
menuItem.setVisibility(true);
menuItem.setEnabled(false);
createMenuItemView(index, menuItem);
return true;
}else{
return false;
}
}
public boolean removeMenuItem(int index){
if(index>=0 && index
MenuItem item=(MenuItem)mContainerLayout.getChildAt(index).getTag();
if(item!=null) {
//调整项目删除后菜单的整体高度
if (item.isSplitLine()) {
menuHeight -= 2 + offset * 2;
} else {
menuHeight -= itemHeight + offset * 2;
}
mContainerLayout.removeViewAt(index);
return true;
}
}
return false;
}
public boolean removeMenuItem(MenuItem menuItem){
if(menuItem!=null){
for(int i=0;i
if(menuItem.equals(mContainerLayout.getChildAt(i).getTag())){
return removeMenuItem(i);
}
}
}
return false;
}
public boolean setMenuItemVisibility(int index,boolean visibility){
if(index>=0 && index
MenuItem menuItem = (MenuItem)mContainerLayout.getChildAt(index).getTag();
if(menuItem!=null) {
if (menuItem.isVisibility() != visibility) {
menuItem.setVisibility(visibility);
return true;
}
}
}
return false;
}
public boolean setMenuItemEnabled(int index,boolean enabled){
if(index>=0 && index
MenuItem menuItem = (MenuItem)mContainerLayout.getChildAt(index).getTag();
if(menuItem!=null) {
if (!menuItem.isSplitLine()) {
if (menuItem.isEnabled() != enabled) {
menuItem.setEnabled(enabled);
return true;
}
}
}
}
return false;
}
public boolean setMenuItemSelected(int index,boolean selected){
if(index>=0 && index
MenuItem menuItem = (MenuItem)mContainerLayout.getChildAt(index).getTag();
if(menuItem!=null) {
if (!menuItem.isSplitLine()) {
if (menuItem.isSelected() != selected) {
menuItem.setSelected(selected);
return true;
}
}
}
}
return false;
}
public boolean setMenuItemIcon(int index,@DrawableRes int resId){
return setMenuItemIcon(index,mContext.getResources().getDrawable(resId));
}
public boolean setMenuItemIcon(int index,Drawable icon){
if(index>=0 && index
MenuItem menuItem = (MenuItem)mContainerLayout.getChildAt(index).getTag();
if(menuItem!=null) {
if (!menuItem.isSplitLine()) {
if (!menuItem.getItemIcon().equals(icon)) {
menuItem.setItemIcon(icon);
return true;
}
}
}
}
return false;
}
public boolean setMenuItemTitle(int index,String title){
if(index>=0 && index
MenuItem menuItem = (MenuItem)mContainerLayout.getChildAt(index).getTag();
if(menuItem!=null) {
if (!menuItem.isSplitLine()) {
if (!menuItem.getItemTitle().equals(title)) {
menuItem.setItemTitle(title);
return true;
}
}
}
}
return false;
}
public boolean setMenuItemSwitch(int index,boolean _switch){
if(index>=0 && index
MenuItem menuItem = (MenuItem)mContainerLayout.getChildAt(index).getTag();
if(menuItem!=null) {
if (!menuItem.isSplitLine()) {
if (menuItem.isSwitchItem() != _switch) {
menuItem.setSwitchItem(_switch);
return true;
}
}
}
}
return false;
}
public void setMenuItemBackgroundResource(@DrawableRes int resid){
for(int index=0;index
mContainerLayout.getChildAt(index).setBackgroundResource(resid);
}
}
public void setMenuItemBackgroundResource(@DrawableRes int resid,int index){
mContainerLayout.getChildAt(index).setBackgroundResource(resid);
}
public void setMenuItemBackgroundDrawable(Drawable background){
for(int index=0;index
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mContainerLayout.getChildAt(index).setBackground(background);
}else{
mContainerLayout.getChildAt(index).setBackgroundDrawable(background);
}
}
}
public void setMenuItemBackgroundDrawable(Drawable background,int index){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mContainerLayout.getChildAt(index).setBackground(background);
}else{
mContainerLayout.getChildAt(index).setBackgroundDrawable(background);
}
}
public void setMenuItemBackgroundColor(@ColorInt int color){
for(int index=0;index
mContainerLayout.getChildAt(index).setBackgroundColor(color);
}
}
public void setMenuItemBackgroundColor(@ColorInt int color,int index){
mContainerLayout.getChildAt(index).setBackgroundColor(color);
}
public void setSplitLineResource(@DrawableRes int resid){
for(int index=0;index
LinearLayout menuItemView= (LinearLayout) mContainerLayout.getChildAt(index);
MenuItem item=(MenuItem)menuItemView.getTag();
if(item!=null) {
if (item.isSplitLine() && menuItemView.getChildCount()>0) {
menuItemView.getChildAt(0).setBackgroundResource(resid);
}
}
}
}
public void setSplitLineDrawable(Drawable drawable){
for(int index=0;index
LinearLayout menuItemView= (LinearLayout) mContainerLayout.getChildAt(index);
MenuItem item=(MenuItem)menuItemView.getTag();
if(item!=null) {
if (item.isSplitLine() && menuItemView.getChildCount()>0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
menuItemView.getChildAt(0).setBackground(drawable);
}else{
menuItemView.getChildAt(0).setBackgroundDrawable(drawable);
}
}
}
}
}
public void setSplitLineColor(@ColorInt int color){
for(int index=0;index
LinearLayout menuItemView= (LinearLayout) mContainerLayout.getChildAt(index);
MenuItem item=(MenuItem)menuItemView.getTag();
if(item!=null) {
if (item.isSplitLine() && menuItemView.getChildCount()>0) {
menuItemView.getChildAt(0).setBackgroundColor(color);
}
}
}
}
public void setMenuItemTextColor(@ColorInt int color){
for(int index=0;index
LinearLayout menuItemView= (LinearLayout) mContainerLayout.getChildAt(index);
MenuItem item=(MenuItem)menuItemView.getTag();
if(item!=null) {
if (!item.isSplitLine() && menuItemView.getChildCount()>0) {
for(int i=0;i
if(menuItemView.getChildAt(i)instanceof TextView){
((TextView) menuItemView.getChildAt(i)).setTextColor(color);
}
}
}
}
}
}
public void setMenuItemTextColor(ColorStateList colors){
for(int index=0;index
LinearLayout menuItemView= (LinearLayout) mContainerLayout.getChildAt(index);
MenuItem item=(MenuItem)menuItemView.getTag();
if(item!=null) {
if (!item.isSplitLine() && menuItemView.getChildCount()>0) {
for(int i=0;i
if(menuItemView.getChildAt(i)instanceof TextView){
((TextView) menuItemView.getChildAt(i)).setTextColor(colors);
}
}
}
}
}
}
public float getMenuWidth(){
return menuWidth;
}
public float getMenuHeight() {
return menuHeight;
}
public float getItemHeight() {
return itemHeight;
}
public void show(){
if(mPopupWindow!=null) {
mPopupWindow.setHeight((int) menuHeight);
mPopupWindow.setWidth((int) menuWidth);
if(xOffset==0 && yOffset==0 && mGravity==Gravity.NO_GRAVITY){
mPopupWindow.showAsDropDown(mAnchor);
}else{
int xoff,yoff;
if(mGravity==Gravity.LEFT||mGravity==Gravity.START
||mGravity==(Gravity.LEFT|Gravity.BOTTOM)
||mGravity==(Gravity.START|Gravity.BOTTOM)){ //锚定左下
mPopupWindow.showAsDropDown(mAnchor,xOffset,yOffset);
}else if(mGravity==Gravity.RIGHT||mGravity==Gravity.END
||mGravity==(Gravity.RIGHT|Gravity.BOTTOM)
||mGravity==(Gravity.END|Gravity.BOTTOM)) { //锚定右下
xoff=(xOffset+-(int)(menuWidth-mAnchor.getWidth()));
mPopupWindow.showAsDropDown(mAnchor, xoff, yOffset);
}else if(mGravity==(Gravity.LEFT|Gravity.TOP)
||mGravity==(Gravity.START|Gravity.TOP)){ //左上
yoff=yOffset+-(int)( menuHeight+mAnchor.getHeight());
mPopupWindow.showAsDropDown(mAnchor, xOffset, yoff);
}else if(mGravity==(Gravity.RIGHT|Gravity.TOP)
||mGravity==(Gravity.END|Gravity.TOP)){ //右上
xoff=(xOffset+-(int)(menuWidth-mAnchor.getWidth()));
yoff=yOffset+-(int)( menuHeight+mAnchor.getHeight());
mPopupWindow.showAsDropDown(mAnchor, xoff,yoff);
}else{
mPopupWindow.showAsDropDown(mAnchor,xOffset,yOffset);
}
}
}
}
public void dismiss(){
if(mPopupWindow!=null)
mPopupWindow.dismiss();
}
private void createPopup(){
mPopupWindow=new PopupWindow();
ColorDrawable dw = new ColorDrawable(Color.parseColor("#70aa00bc"));
mPopupWindow.setBackgroundDrawable(dw);
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setFocusable(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mPopupWindow.setElevation(0f);
}
mPopupWindow.setTouchable(true);
mContainerLayout =new LinearLayout(mContext);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(MATCH_PARENT,WRAP_CONTENT);
mContainerLayout.setLayoutParams(params);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mContainerLayout.setElevation(dp2px(mContext,5));
}else{
mContainerLayout.setTranslationX(dp2px(mContext,-0.5f));
mContainerLayout.setTranslationY(dp2px(mContext,-1.5f));
}
mContainerLayout.setBackgroundColor(Color.WHITE);
mContainerLayout.setOrientation(LinearLayout.VERTICAL);
mContainerLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
mContainerLayout.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
//布局位于状态栏下⽅
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
//全屏
View.SYSTEM_UI_FLAG_FULLSCREEN |
//隐藏导航栏
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
uiOptions |= 0x00001000;
mContainerLayout.setSystemUiVisibility(uiOptions);
}
});
mPopupWindow.setContentView(mContainerLayout);
}
private void createMenuItemView(int index,MenuItem menuItem){
LinearLayout menuItemView=new LinearLayout(mContext);
menuItemView.setOrientation(LinearLayout.HORIZONTAL);
if(menuItem.isSplitLine()){
View view=new View(mContext);
view.setBackgroundColor(0x60888888); //默认分割线颜色
LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(MATCH_PARENT, 2, 0);
layoutParams.setMargins((int)offset*2,(int)offset,(int)offset*2,(int)offset);
view.setLayoutParams(layoutParams);
menuItemView.setTag(menuItem); //将菜单项目内容包含在tag
menuItemView.addView(view);
if(menuItem.isVisibility()) {
menuItemView.setVisibility(View.VISIBLE);
menuHeight+=2+offset*2;
}else{
menuItemView.setVisibility(View.GONE);
}
if(index>=0){
mContainerLayout.addView(menuItemView,index);
}else {
mContainerLayout.addView(menuItemView);
}
}else {
menuItemView.setClickable(true);
menuItemView.setFocusable(true);
menuItemView.setBackgroundResource(android.R.drawable.menuitem_background);
menuItemView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT, 0));
menuItemView.setPadding(0, (int)offset, 0, (int)offset);
menuItemView.setGravity(Gravity.CENTER_VERTICAL); //子视图垂直居中对齐
ImageView iconView=null;
LinearLayout.LayoutParams iconParams=null;
if(menuItem.getItemIcon()!=null) {
iconView = new ImageView(mContext); //创建菜单项图标
iconView.setImageDrawable(menuItem.getItemIcon());
iconParams = new LinearLayout.LayoutParams((int) iconSize, (int) iconSize, 0);
iconParams.leftMargin = (int) offset;
iconParams.rightMargin = (int) offset / 2;
iconView.setLayoutParams(iconParams);
}
TextView titleView = new TextView(mContext); //创建菜单项标签
titleView.setText(menuItem.getItemTitle());
titleView.setGravity(Gravity.CENTER_VERTICAL); //标签垂直居中对齐
titleView.setSingleLine(true); //单行文本
titleView.setEllipsize(TextUtils.TruncateAt.END); //结尾省略
LinearLayout.LayoutParams titleParams = new LinearLayout.LayoutParams(MATCH_PARENT, (int) itemHeight, 1);
titleParams.leftMargin = (int)(iconView!=null?(offset / 2):offset);
titleParams.rightMargin = (int)offset;
titleView.setLayoutParams(titleParams);
TextPaint textPaint = titleView.getPaint();
float textWidth = textPaint.measureText(menuItem.getItemTitle()); //得到文本宽度
//因为文本框单行间隔3dp所有这里将文本高度保留3dp
//float textHeight=textPaint.descent()-textPaint.ascent()+dp2px(mContext,3);
Log.e(TAG, "标题宽度:" + textWidth);
Space space = new Space(mContext);
space.setLayoutParams(new LinearLayout.LayoutParams((int)spaceWidth, 0));
if(iconView!=null)
menuItemView.addView(iconView);
menuItemView.addView(titleView);
menuItemView.addView(space);
int switchWidth=0;
Switch mSwidth=null;
if(menuItem.isSwitchItem()){
mSwidth=new Switch(mContext);
int w=(int)dp2px(mContext,50);
LinearLayout.LayoutParams switchParams = new LinearLayout.LayoutParams(w, (int) itemHeight, 0);
switchParams.rightMargin= (int) offset;
mSwidth.setLayoutParams(switchParams);
mSwidth.setChecked(menuItem.isSwitchChecked()); //设置选中状态
switchWidth=switchParams.rightMargin+w;
menuItemView.addView(mSwidth);
// mSwidth.setChecked();
}
menuItemView.setSelected(menuItem.isSelected()); //选中状态
menuItemView.setTag(menuItem); //将菜单项目内容包含在tag
menuItemView.setEnabled(menuItem.isEnabled());
if(menuItem.isVisibility()){
menuItemView.setVisibility(View.VISIBLE);
//当前所需宽度=文本宽度+文本视图左右保留位置+图标宽度+图标左右保留位置+占位视图宽度+切换开关宽度
float tempWidth = textWidth +titleParams.leftMargin + titleParams.rightMargin +
(iconParams!=null?iconSize + iconParams.leftMargin + iconParams.rightMargin:0) +
spaceWidth+switchWidth;
if (tempWidth > menuWidth) {
menuWidth = (int) tempWidth;
}
menuHeight+=itemHeight+offset*2; //固定项目高度
}else{
menuItemView.setVisibility(View.GONE);
}
if(index<0 ||index>=mContainerLayout.getChildCount()){
mContainerLayout.addView(menuItemView);
}else {
mContainerLayout.addView(menuItemView,index);
}
if(mSwidth!=null)
mSwidth.setOnCheckedChangeListener(switchChangeListener); //侦听侦听改变
menuItemView.setOnClickListener(clickListener); //设置菜单项视图单击事件
}
}
private boolean isMenuItemKeyOnly(String key){
for(int pos=0;pos
MenuItem item=(MenuItem) mContainerLayout.getChildAt(pos).getTag();
if(item!=null){
if(item.getItemKey().equals(key)){
return false;
}
}
}
return true;
}
private float getMenuItemWidth(LinearLayout currentMenuItemView){
float textWidth=0,imgWidth=0,switchWidth=0;
for(int i=0;i
View view=currentMenuItemView.getChildAt(i);
LinearLayout.LayoutParams params= (LinearLayout.LayoutParams) view.getLayoutParams();
if(view instanceof TextView) {
TextPaint textPaint = ((TextView) view).getPaint();
textWidth = textPaint.measureText(((TextView) view).getText().toString()); //得到文本宽度
textWidth += params.leftMargin + params.rightMargin;
}else if(view instanceof ImageView){
imgWidth=iconSize+params.leftMargin+params.rightMargin;
}else if(view instanceof Switch){
float w= dp2px(mContext,50);
switchWidth=w+params.rightMargin;
}
}
return textWidth+imgWidth+switchWidth;
}
private void setMenuWidth(){
float mWidth=0;
for(int index=0;index
float tempWidth=getMenuItemWidth((LinearLayout) mContainerLayout.getChildAt(index));
if(tempWidth>mWidth)
mWidth=tempWidth;
}
menuWidth= mWidth;
}
private float sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return spValue * fontScale ;
}
private float dp2px(Context context, float dpValue) {
final float fontScale = context.getResources().getDisplayMetrics().density;
return dpValue * fontScale ;
}
private MenuItem.OnMenuItemChange menuItemChange=new MenuItem.OnMenuItemChange() {
@Override
public void onChange(MenuItem item, String attributeName, Object value) {
for(int id=0;id
LinearLayout menuItemView=(LinearLayout) mContainerLayout.getChildAt(id);
MenuItem menuItem=(MenuItem)menuItemView.getTag();
if(item.equals(menuItem)){
//Log.e(TAG,attributeName+"改变");
if(attributeName.equals("selected")) {
menuItemView.setSelected((boolean) value);
}else if(attributeName.equals("enabled")){
boolean enabled=(boolean)value;
menuItemView.setEnabled(enabled);
if(!item.isSplitLine() && item.isSwitchItem()){
if(menuItemView.getChildAt(menuItemView.getChildCount()-1)instanceof Switch){
menuItemView.getChildAt(menuItemView.getChildCount()-1).setEnabled(enabled);
}
}
}else if(attributeName.equals("visibility")){
boolean visibility=(boolean)value;
if(visibility){
if(menuItemView.getVisibility()==View.GONE){
if(item.isSplitLine()){
menuHeight-=2+offset*2;
}else{
menuHeight-=itemHeight+offset*2;
}
menuItemView.setVisibility(View.VISIBLE);
}
}else{
if(menuItemView.getVisibility()!=View.GONE){
if(item.isSplitLine()){
menuHeight+=2+offset*2;
}else{
menuHeight+=itemHeight+offset*2;
}
menuItemView.setVisibility(View.GONE);
}
}
}else if(attributeName.equals("switchItem")){
boolean val=(boolean)value;
if(val){
if(!(menuItemView.getChildAt(menuItemView.getChildCount()-1) instanceof Switch)){
Switch mSwidth=new Switch(mContext);
mSwidth.setChecked(item.isSwitchChecked());
menuItemView.addView(mSwidth);
mSwidth.setOnCheckedChangeListener(switchChangeListener); //设置侦听
}
//在项目中增加新控件时直接比对得到最大宽度即可
float itemWidth=getMenuItemWidth(menuItemView);
if(itemWidth>menuWidth)
menuWidth=itemWidth;
}else{
if((menuItemView.getChildAt(menuItemView.getChildCount()-1) instanceof Switch)){
menuItemView.removeViewAt(menuItemView.getChildCount()-1);
setMenuWidth(); //由于是减少视图,所以需要重新计算所有菜单项宽度来得到新宽度
}
}
}else if(attributeName.equals("itemIcon")){
Drawable icon= (Drawable) value;
if(icon==null){
if(menuItemView.getChildAt(0)instanceof ImageView){
menuItemView.removeViewAt(0);
setMenuWidth(); //由于是减少视图,所以需要重新计算所有菜单项宽度来得到新宽度
}
}else{
ImageView iconView;
if(menuItemView.getChildAt(0)instanceof ImageView){
iconView= (ImageView) menuItemView.getChildAt(0);
if(!iconView.getDrawable().equals(icon)){
iconView.setImageDrawable(icon);
}
}else{
iconView=new ImageView(mContext);
iconView.setImageDrawable(menuItem.getItemIcon());
LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams((int) iconSize, (int) iconSize, 0);
iconParams.leftMargin = (int) offset;
iconParams.rightMargin = (int) offset / 2;
iconView.setLayoutParams(iconParams);
menuItemView.addView(iconView,0);
//在项目中增加新控件时直接比对得到最大宽度即可
float itemWidth=getMenuItemWidth(menuItemView);
if(itemWidth>menuWidth)
menuWidth=itemWidth;
}
}
}else if(attributeName.equals("itemTitle")){
String title= (String) value;
if(title==null)
title="";
for(int i=0;i
if(menuItemView.getChildAt(i)instanceof TextView){
TextView textView= (TextView) menuItemView.getChildAt(i);
if(!textView.getText().equals(title)){
textView.setText(title);
setMenuWidth(); //由于标签内容长度不确定,所以直接重新计算整个菜单宽度
return;
}
}
}
}
return;
}
}
}
};
private OnCheckedChangeListener switchChangeListener=new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(switchCheckedChangeListener!=null){
LinearLayout menuItemView= (LinearLayout) buttonView.getParent();
if(menuItemView!=null){
MenuItem item=(MenuItem)menuItemView.getTag();
switchCheckedChangeListener.onCheckedChanged(item,buttonView,isChecked);
}
}
Log.e(TAG,((MenuItem) ((LinearLayout)buttonView.getParent()).getTag()).getItemKey()+"项菜单复选按钮改变");
}
};
private View.OnClickListener clickListener=new View.OnClickListener() {
@Override
public void onClick(View v) {
mPopupWindow.dismiss();
if(menuItemClickListener!=null){
menuItemClickListener.onMenuItemClick((MenuItem) v.getTag(),v);
}
Log.e(TAG,"按下"+((MenuItem) v.getTag()).getItemKey()+"项菜单");
}
};
}
主要调用DropMenu类下的构造方法构造实体,调用如下:
mDropMenu=new DropMenu(this,btnPopMenu); //this为河东窗体上下文;btnPopMenu需要将菜单弹出的定位视图(以该视图为圆点定位)
//添加菜单项
mDropMenu.addMenuItem("cshqx","初始化曲线",R.drawable.ic_timeline_black_24dp,true,true);
mDropMenu.addSplitLine();
mDropMenu.addMenuItem("gxzqd","更新主驱动",R.drawable.ic_play_for_work_black_24dp,false,false,true);
mDropMenu.addMenuItem("wd","我的",R.drawable.ic_account_circle_black_24dp,false,false,false);
调用DropMenu的show()方法弹出菜单。效果如下:



