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

来源:互联网 发布:科比详细身体数据 编辑:程序博客网 时间:2024/05/22 10:53

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

原生的菜单如下图:


自定义之后的效果图:


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

源码下载

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

/** * 对弹出菜单的封装. * http://blog.csdn.net/maosidiaoxian/article/details/39178167 * Author: msdx (645079761@qq.com) * 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 (645079761@qq.com) * 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

0 0
原创粉丝点击