首页 > 系统 > Android > 正文

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

2019-12-12 03:06: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;  } } 

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

<?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、所需资源文件:

参考:

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

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表