Android 弹出式菜单

最近在写安卓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;
    /**有switch视图*/
    private boolean switchItem=false;
    /**switch状态*/
    private boolean switchChecked=false;
    /**项目状态*/
    private boolean selected=false;
    /**项目可视状态*/
    private boolean visibility=true;
    /**启用*/
    private boolean enabled=true;

    public interface OnMenuItemChange{
   
        /**
         * 项目属性改变时触发
         * @param item 发送改变的菜单项
         * @param attributeName 改变的属性名称
         * @param value 对应改变的值
         */
        void onChange(MenuItem item,String attributeName,Object value);
    }
    /**菜单项改变事件侦听接口*/
    private OnMenuItemChange onMenuItemChange=null;
    /**
     * 构建一个仅有关键字的实体
     * @param key 关键字
     */
    public MenuItem(String key){
   
        this.itemKey=key;
    }
    /**
     * 构建一个仅有分隔线的实体
     * @param key 关键字
     * @param splitLine 是否分割线
     */
    public MenuItem(String key,boolean splitLine){
   
        this.itemKey=key;
        this.splitLine=splitLine;
        this.selected=false;
    }
    /**
     * 构建含标题的实体
     * @param key 关键字
     * @param title
     */
    public MenuItem(String key,String title){
   
        this(key,title,null);
    }
    /**
     * 构建一个包含标题及图标的实体
     * @param key 关键字
     * @param title 标题
     * @param icon 图标
     */
    public MenuItem(String key,String title,Drawable icon){
   
        this(key,title,icon,false);
    }
    /**
     * 构建一个包含标题,图标及切换视图的实体
     * @param key 关键字
     * @param title 标题
     * @param icon 图标
     * @param switchItem 含有切换视图?
     */
    public MenuItem(String key,String title,Drawable icon,boolean switchItem){
   
        this(key,title,icon,switchItem,false);
    }
    /**
     * 构建一个包含标题,图标及切换视图的实体
     * @param key 关键字
     * @param title 标题
     * @param icon 图标
     * @param switchItem 含有切换视图?
     * @param selected 选择状态
     */
    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;
    }
    /**
     * 设置项目标题
     * @param itemTitle
     */
    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", itemTitle);
                    }
                }
            }else if(this.itemTitle!=null||this.itemTitle.length()>0){
   
                if(!this.itemTitle.equals(itemTitle)){
   
                    this.itemTitle = itemTitle;
                    if (onMenuItemChange != null) {
   
                        onMenuItemChange.onChange(this, "itemTitle", itemTitle);
                    }
                }
            }
        }
    }
    /**获取项目标题*/
    public String getItemTitle() {
   
        return itemTitle;
    }
    /**
     * 设置项目图标
     * @param itemIcon
     */
    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);
                }
            }
        }
    }
    /**
     * 获取项目图标
     * @return
     */
    public Drawable getItemIcon() {
   
        return itemIcon;
    }

    /**
     * 设置项目包含Switch
     * @param switchItem
     */
    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);
                }
            }
        }
    }
    /**项目包含witch*/
    public boolean isSwitchItem() {
   
        return switchItem;
    }

    /**
     * Switch选择状态
     * @param switchChecked
     */
    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);
//                }
            }
        }
    }
    /**witch选择状态*/
    public boolean isSwitchChecked() {
   
        return switchChecked;
    }

    /**
     * 设置项目选择状态
     * @param selected
     */
    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;
    }
    /**
     * 设置菜单改变侦听接口
     * @param onMenuItemChange
     */
    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{
   
        /**
         * 菜单项单击事件
         * @param item 单击的菜单项
         * @param view 单击的视图
         */
        void onMenuItemClick(MenuItem item,View view);
    }
    public interface OnSwitchCheckedChangeListener{
   
        /**
         * 当复合按钮的选中状态更改时调用。
         * @param item 复选按钮所在的菜单项
         * @param buttonView 状态已更改的复合按钮视图。
         * @param isChecked 按钮视图的新选中状态。
         */
        void onCheckedChanged(MenuItem item,CompoundButton buttonView, boolean isChecked);
    }
    /**当用户从菜单中选择项目时将收到通知的侦听器。*/
    private OnMenuItemClickListener menuItemClickListener=null;
    /**当用户改变复选按钮状态时将收到的通知的侦听器*/
    private OnSwitchCheckedChangeListener switchCheckedChangeListener=null;

    /**
     * 构造函数创建带有定位视图的新弹出菜单。
     * @param context 弹出菜单运行在上下文中,通过它可以访问当前主题、资源等。
     * @param anchor 此弹出窗口的锚定视图。如果有空间,弹出窗口将显示在锚点下方,如果没有空间,弹出窗口将显示在锚点上方。
     */
    public DropMenu(@NonNull Context context, @NonNull View anchor){
   
        this(context,anchor,Gravity.NO_GRAVITY);
    }
    /**
     * 造函数创建带有定位视图的新弹出菜单。
     * @param context 弹出菜单运行在上下文中,通过它可以访问当前主题、资源等。
     * @param anchor 此弹出窗口的锚定视图。
     * @param gravity 弹出窗口相对于锚定的对齐
     */
    public DropMenu(@NonNull Context context, @NonNull View anchor,int gravity){
   
      this(context,anchor,0,0,gravity);
    }
    /**
     * 造函数创建带有定位视图的新弹出菜单。
     * @param context 弹出菜单运行在上下文中,通过它可以访问当前主题、资源等。
     * @param anchor 此弹出窗口的锚定视图。
     * @param xoff 相对于定位点的水平偏移(以像素为单位)
     * @param yoff 相对于定位点的垂直偏移(以像素为单位)
     */
    public DropMenu(@NonNull Context context, @NonNull View anchor,int xoff,int yoff){
   
        this(context,anchor,0,0,Gravity.NO_GRAVITY);
    }
    /**
     * 造函数创建带有定位视图的新弹出菜单。
     * @param context 弹出菜单运行在上下文中,通过它可以访问当前主题、资源等。
     * @param anchor 此弹出窗口的锚定视图。
     * @param xoff 相对于定位点的水平偏移(以像素为单位)
     * @param yoff 相对于定位点的垂直偏移(以像素为单位)
     * @param gravity 弹出窗口相对于锚定的对齐
     */
    public DropMenu(@NonNull Context
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值