Android 使用PopupWindow实现弹出更多的菜单

最近想要做一个弹出更多的菜单,而原生的弹出菜单却不是我们想要的效果,所以必然要自定义菜单咯。本人也是借鉴网上的资料进行封装的,感觉还蛮不错的。

原生的菜单如下图:

自定义之后的效果图:

是不是看到这里之后,对比可知,原生的效果不太理想,所以还是再自己定义吧!

1、PopupWindow可以说是一个浮动在Activity之上的容器,通常用来显示自定义的视图。弹出菜单的封装PopMenuMore

/**
 * 对弹出菜单的封装.
 * http://blog.csdn.net/maosidiaoxian/article/details/39178167
 * Author: msdx ([email protected])
 * Time: 14-6-13 下午1:51
 */
public class PopMenuMore {
    /**
     * 上下文.
     */
    private Context mContext;
    /**
     * 菜单项
     */
    private ArrayList<PopMenuMoreItem> mItemList;
    /**
     * 列表适配器.
     */
    private BaseAdapter mAdapter;
    /**
     * 菜单选择监听.
     */
    private OnItemSelectedListener mListener;
    /**
     * 下角图标
     */
    private ImageView cornerIcon;
    /**
     * 列表.
     */
    private ListView mListView;
    /**
     * 弹出窗口.
     */
    private PopupWindow mPopupWindow;

    public PopMenuMore(Context context) {
        mContext = context;
        mItemList = new ArrayList<>();
        View view = onCreateView(context);
        view.setFocusableInTouchMode(true);
        mAdapter = onCreateAdapter(context, mItemList);
        cornerIcon = findCornerView(view);
        mListView = findListView(view);
        mListView.setAdapter(mAdapter);
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                PopMenuMoreItem item = (PopMenuMoreItem) mAdapter.getItem(position);
                if (mListener != null) {
                    mListener.selected(view, item, position);
                }
                mPopupWindow.dismiss();
            }
        });
        view.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_MENU && mPopupWindow.isShowing()) {
                    mPopupWindow.dismiss();
                    return true;
                }
                return false;
            }
        });
        mPopupWindow = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
        mPopupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));
        setBackgroundColor(Color.parseColor("#000000"));
        setCorner(R.mipmap.triangle);
    }

    /**
     * 设置ListView背景
     *
     * @param argb Color.parseColor("..")
     */
    public void setBackgroundColor(int argb) {
//        int strokeWidth = 5; // 3dp 边框宽度
        int roundRadius = 5; // 8dp 圆角半径
//        int strokeColor = Color.parseColor("#2E3135");//边框颜色
//        int fillColor = Color.parseColor("#DFDFE0");//内部填充颜色
        GradientDrawable gd = new GradientDrawable();//创建drawable
        gd.setColor(argb);
        gd.setCornerRadius(roundRadius);
//        gd.setStroke(strokeWidth, strokeColor);
        mListView.setBackgroundDrawable(gd);
    }

    /**
     * 设置下角图标
     *
     * @param resId
     */
    public void setCorner(int resId) {
        cornerIcon.setBackgroundResource(resId);
    }

    protected View onCreateView(Context context) {
        return LayoutInflater.from(context).inflate(R.layout.layout_popmenu_more, null);
    }

    protected ImageView findCornerView(View view) {
        return (ImageView) view.findViewById(R.id.corner_iv);
    }

    protected ListView findListView(View view) {
        return (ListView) view.findViewById(R.id.menu_listview);
    }

    /**
     * 菜单列表中的适配器.
     *
     * @param context
     * @param items   表示所有菜单项.
     * @return
     */
    protected BaseAdapter onCreateAdapter(Context context, ArrayList<PopMenuMoreItem> items) {
        return new PopMenuMoreAdapter(context, items);
    }

    /**
     * 添加菜单项
     *
     * @param item
     */
    public void addItem(PopMenuMoreItem item) {
        mItemList.add(item);
        mAdapter.notifyDataSetChanged();
    }

    public void addItems(List<PopMenuMoreItem> items) {
        if (items != null) {
            mItemList.clear();
        }
        for (PopMenuMoreItem item : items) {
            mItemList.add(item);
        }
        mAdapter.notifyDataSetChanged();
    }

    /**
     * 作为指定View的下拉控制显示.
     *
     * @param parent 所指定的View
     */
    public void showAsDropDown(View parent) {
        mPopupWindow.showAsDropDown(parent);
    }

    /**
     * 隐藏菜单.
     */
    public void dismiss() {
        mPopupWindow.dismiss();
    }

    /**
     * 设置菜单选择监听.
     *
     * @param listener 监听器.
     */
    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
        mListener = listener;
    }

    /**
     * 当前菜单是否正在显示.
     *
     * @return
     */
    public boolean isShowing() {
        return mPopupWindow.isShowing();
    }

    /**
     * 菜单项选择监听接口.
     */
    public interface OnItemSelectedListener {
        /**
         * 菜单被选择时的回调接口.
         *
         * @param view     被选择的内容的View.
         * @param item     被选择的菜单项.
         * @param position 被选择的位置.
         */
        void selected(View view, PopMenuMoreItem item, int position);
    }
}

2、菜单中ListView的适配器:PopMenuMoreAdapter

/**
 * @author SoBan
 * @create 2017/4/12 10:29.
 */

public class PopMenuMoreAdapter extends BaseAdapter {

    private ArrayList<PopMenuMoreItem> items;
    private Context context;

    public PopMenuMoreAdapter(Context context, ArrayList<PopMenuMoreItem> items) {
        this.context = context;
        this.items = items;
    }

    @Override
    public int getCount() {
        return items.size();
    }

    @Override
    public PopMenuMoreItem getItem(int position) {
        return items.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        if (view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.item_popmenu_more, null);
            ViewHolder holder = new ViewHolder();
            holder.icon = (ImageView) view.findViewById(R.id.menu_icon);
            holder.text = (TextView) view.findViewById(R.id.menu_text);
            view.setTag(holder);
        } else if (view.getParent() != null) {
            ((ViewGroup) view.getParent()).removeView(view);
        }
        ViewHolder holder = (ViewHolder) view.getTag();
        PopMenuMoreItem item = items.get(position);
        if (item.getResId() == 0) {
            holder.icon.setVisibility(View.GONE);
        }
        holder.text.setText(item.getText());
        return view;
    }

    private class ViewHolder {
        ImageView icon;
        TextView text;
    }
}

4、菜单项中item:  PopMenuMoreItem

/**
 * 菜单项.
 */
public class PopMenuMoreItem {
    public int id; //标识
    public int resId; //资源图标
    public String text;//文字

    public PopMenuMoreItem(int id, String text) {
        this.id = id;
        this.resId = 0;
        this.text = text;
    }

    public PopMenuMoreItem(int id, int resId, String text) {
        this.id = id;
        this.resId = resId;
        this.text = text;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getResId() {
        return resId;
    }

    public void setResId(int resId) {
        this.resId = resId;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

4、宽度适配内容、不滚动的ListView:PopMenuMoreListView

/**
 * 宽度适配内容的ListView.
 * Author: msdx ([email protected])
 * Time: 14-9-2 下午5:14
 */
public class PopMenuMoreListView extends ListView {

    public PopMenuMoreListView(Context context) {
        super(context);
    }

    public PopMenuMoreListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PopMenuMoreListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), heightMeasureSpec);
            int w = child.getMeasuredWidth();
            if (w > width) width = w;
        }

        widthMeasureSpec = MeasureSpec.makeMeasureSpec(width + getPaddingLeft() + getPaddingRight(), MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

5、item的布局:item_popmenu_more.xml

<?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:paddingBottom="10dip"
    android:paddingLeft="20dip"
    android:paddingRight="20dip"
    android:paddingTop="10dip">

    <ImageView
        android:id="@+id/menu_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="5dip"
        android:layout_marginRight="5dip"
        android:src="@mipmap/demand_icon_location" />

    <TextView
        android:id="@+id/menu_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:singleLine="true"
        android:textColor="#FFFFFF" />
</LinearLayout>

6、更多菜单的布局:layout_popmenu_more.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingRight="5dip">

    <ImageView
        android:id="@+id/corner_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:layout_marginRight="15dip"
        android:contentDescription="@null" />

    <soban.orderscroll.PopMenuMoreListView
        android:id="@+id/menu_listview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:cacheColorHint="@android:color/transparent"
        android:listSelector="@android:color/transparent"
        android:divider="#FFFFFF"
        android:dividerHeight="1px"
        android:focusable="true" />
</LinearLayout>

7、例子Activity: MainActivity

public class MainActivity extends Activity {

    private static final int USER_SEARCH = 0;
    private static final int USER_ADD = 1;
    private PopMenuMore mMenu;
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initMenu();
        mTextView = (TextView) findViewById(R.id.hello_tv);
        mTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mMenu.showAsDropDown(mTextView);
            }
        });
    }

    private void initMenu() {
        mMenu = new PopMenuMore(this);
       // mMenu.setCorner(R.mipmap.demand_icon_location);
       // mMenu.setBackgroundColor(Color.parseColor("#ff8800"));
        ArrayList<PopMenuMoreItem> items = new ArrayList<>();
        items.add(new PopMenuMoreItem(USER_SEARCH, "搜索"));
        items.add(new PopMenuMoreItem(USER_ADD, "添加"));
        items.add(new PopMenuMoreItem(USER_SEARCH, "搜索"));
        items.add(new PopMenuMoreItem(USER_ADD, "添加"));
        items.add(new PopMenuMoreItem(USER_SEARCH, "搜索"));
        items.add(new PopMenuMoreItem(USER_ADD, "添加"));
        /*items.add(new PopMenuMoreItem(USER_SEARCH, R.mipmap.demand_icon_number, "搜索"));
        items.add(new PopMenuMoreItem(USER_ADD, R.mipmap.demand_icon_location, "添加"));
        items.add(new PopMenuMoreItem(USER_SEARCH, R.mipmap.demand_icon_number, "搜索"));
        items.add(new PopMenuMoreItem(USER_ADD, R.mipmap.demand_icon_location, "添加"));
        items.add(new PopMenuMoreItem(USER_SEARCH, R.mipmap.demand_icon_number, "搜索"));
        items.add(new PopMenuMoreItem(USER_ADD, R.mipmap.demand_icon_location, "添加"));*/

        mMenu.addItems(items);
        mMenu.setOnItemSelectedListener(new PopMenuMore.OnItemSelectedListener() {
            @Override
            public void selected(View view, PopMenuMoreItem item, int position) {
                switch (item.id) {
                    case USER_SEARCH:
//                        startActivity(new Intent(this, UserSearchActivity.class));
                        break;
                    case USER_ADD:
//                        startActivity(new Intent(getActivity(), UserAddActivity.class));
                        break;
                }
            }
        });
    }
}

8、例子布局:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <TextView
        android:id="@+id/hello_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>

9、所需资源文件:

最近项目也蛮急的,这里写的有点匆忙,可能写的就没有那么具体,希望各位朋友看的懂

借鉴:http://blog.csdn.net/maosidiaoxian/article/details/39178167

代码设置背景圆角+边框+圆半径:http://blog.csdn.net/houshunwei/article/details/17392409

时间: 2024-08-24 20:59:03

Android 使用PopupWindow实现弹出更多的菜单的相关文章

android利用PopupWindow实现点击工具栏弹出下拉菜单

1.概述 本文将介绍如何利用PopupWindow实现点击屏幕顶部工具栏按钮弹出下拉菜单的功能.先上图: 2.代码实现 首先是activity_main.xml布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width=&qu

Android开发技巧——使用PopupWindow实现弹出菜单

在本文当中,我将会与大家分享一个封装了PopupWindow实现弹出菜单的类,并说明它的实现与使用. 因对界面的需求,android原生的弹出菜单已不能满足我们的需求,自定义菜单成了我们的唯一选择,在本文当中,我将与大家分享如何使用PopupWindow实现弹出菜单. 1.弹出菜单的封装PopMenu PopupWindow可以说是一个浮动在Activity之上的容器,通常用来显示自定义的视图.比如像自动完成输入框AutoCompleteTextView,它的提示列表就是使用PopupWindo

【android开发】使用PopupWindow实现页面点击顶部弹出下拉菜单

没有太多花样,也没有很复杂的技术,就是简单的PopupWindow的使用,可以实现点击弹出一个自定义的view,view里可以随便设计,常用的可以放一个listview. demo中我只是一个点击展示,简单的使用了fade in out的动画效果,也没有精美的图片资源,看着也丑,不过这么短的时间,让你掌握一个很好用的技术,可以自己扩展,不很好么? 废话不说了,直接上代码: MainActivity.java [java] view plaincopy public class MainActiv

用PopupWindow实现弹出菜单(弹出的菜单采用自定义布局)

     用PopupWindow实现弹出菜单是一个比较好的方式.当然我们还有一个类PopupMenu也能实现弹出菜单,但那个太过于局限了,所以不是很推荐. 这个实例的效果是这样的:点击按钮后,一个菜单从屏幕的右边滑入到屏幕中,点击按钮/空白处后菜单消失. 布局文件时一个按钮,我就不贴出代码了.下面是菜单的布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&

Android popwindow和fragment结合 左侧弹出下拉菜单 切换界面

延续上一篇文章Android 实现对话框圆角功能 ,在项目推进的过程当中,之前是已经用popwindow实现了点击按钮,在按钮下方弹出下拉菜单,实现了类似微信右上角加好友的功能,有兴趣的朋友,可以下载这个资源.回归主题,之前popwindow的使用,是固定在了登陆刚进去的界面,假设现在点击了左侧菜单的其他按钮,这就要求标题下方的内容必须更新所要显示的内容,一开始想都没想,就用了如下代码进行跳转: Intent intent = new Intent(Intent.ACTION_EDIT, nul

PopupWindow底部弹出

说明:从屏幕底部弹出PopupWindow,有弹出隐藏动画效果.背景设置透明度. 效果图例如以下: 1.MainActivity.java   显示popwindow,宽高跟屏幕大小一样,设置一个透明度背景 public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setCo

android中常用的弹出提示框

转自:http://blog.csdn.net/centralperk/article/details/7493731 我们在平时做开发的时候,免不了会用到各种各样的对话框,相信有过其他平台开发经验的朋友都会知道,大部分的平台都只提供了几个最简单的实现,如果我们想实现自己特定需求的对话框,大家可能首先会想到,通过继承等方式,重写我们自己的对话框.当然,这也是不失为一个不错的解决方式,但是一般的情况却是这样,我们重写的对话框,也许只在一个特定的地方会用到,为了这一次的使用,而去创建一个新类,往往有

通用的popupwindow底部弹出框

前段时间做项目的时候,有几个底部弹出框,当时因为忙着赶进度所有就单独写了好几个popupwindow.后来就想着怎么实现一个通用的PopupWindow工具类 就是在要用到的时候创建该工具类的对象,并传入相应的框体布局,就可以实现了. 先看看效果,下面的两是调用同一个PopupWindowUtils创建的:       ok,先看看popupWindow的具体实现 import android.app.Activity; import android.graphics.drawable.Colo

Android于popWindow写弹出菜单

1.什么是popWindow? popWindow这是对话的方式!文字解说android的方式来使用对话框,这就是所谓的popWindow. 2.popWindow特征 Android的对话框有两种:PopupWindow和Dialog.它们的不同点在于: Dialog的位置固定,而PopupWindow的位置能够任意. Dialog是非堵塞线程的,而PopupWindow是堵塞线程的. PopupWindow的位置依照有无偏移分,能够分为偏移和无偏移两种:依照參照物的不同,能够分为相对于某个控