最近想要做一個彈出更多的菜單,而原生的彈出菜單卻不是我們想要的效果,所以必然要自定義菜單咯。本人也是借鑒網上的資料進行封裝的,感覺還蠻不錯的。
原生的菜單如下圖:

自定義之后的效果圖:



是不是看到這里之后,對比可知,原生的效果不太理想,所以還是再自己定義吧!
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實現彈出更多的菜單實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。