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

原生的菜单如下图:

e04f270e8382f7d6cc9a4aa7f9e02c63.png

自定义之后的效果图:

9d6744e20f432bcac211e8d4af1b2c35.png

1ea0920bf870c629866aee54cee551d3.png

49f1cb51c203a53e8d7542955a9d700a.png

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

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 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 items) {

return new PopMenuMoreAdapter(context, items);

}

/**

* 添加菜单项

*

* @param item

*/

public void addItem(PopMenuMoreItem item) {

mItemList.add(item);

mAdapter.notifyDataSetChanged();

}

public void addItems(List 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 items;

private Context context;

public PopMenuMoreAdapter(Context context, ArrayList 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;

}

}

3、菜单项中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

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:paddingBottom="10dip"

android:paddingLeft="20dip"

android:paddingRight="20dip"

android:paddingTop="10dip">

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" />

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" />

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

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:paddingRight="5dip">

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" />

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" />

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 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

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">

android:id="@+id/hello_tv"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello World!" />

9、所需资源文件:

3ec30cca276d5b951a801885152c0ed3.png

04c20d6152c1e068c81ff88440a4066b.png

e34f8bfa1d9a095755d5119ee91ed284.png

参考:

以上所述是小编给大家介绍的Android 使用PopupWindow实现弹出更多的菜单实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐