项目中经常会使用到popupwindow做菜单选项,这个类在使用中有一些经常被遗忘的细节,今天用一个实例来总结一个popupwindow较常用的用法。
效果图:
MainActivity.java:
- public class MainActivity extends Activity {
- private ImageButton ibOperationMore;
- List<Map<String, String>> moreList;
- private PopupWindow pwMyPopWindow;// popupwindow
- private ListView lvPopupList;// popupwindow中的ListView
- private int NUM_OF_VISIBLE_LIST_ROWS = 3;// 指定popupwindow中Item的数量
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- iniData();
- iniPopupWindow();
- // 更多操作按钮
- ibOperationMore = (ImageButton) findViewById(R.id.ib_operate_more);
- ibOperationMore.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (pwMyPopWindow.isShowing()) {
- pwMyPopWindow.dismiss();// 关闭
- } else {
- pwMyPopWindow.showAsDropDown(ibOperationMore);// 显示
- }
- }
- });
- }
- private void iniData() {
- moreList = new ArrayList<Map<String, String>>();
- Map<String, String> map;
- map = new HashMap<String, String>();
- map.put("share_key", "复制");
- moreList.add(map);
- map = new HashMap<String, String>();
- map.put("share_key", "删除");
- moreList.add(map);
- map = new HashMap<String, String>();
- map.put("share_key", "修改");
- moreList.add(map);
- }
- private void iniPopupWindow() {
- LayoutInflater inflater = (LayoutInflater) this
- .getSystemService(LAYOUT_INFLATER_SERVICE);
- View layout = inflater.inflate(R.layout.task_detail_popupwindow, null);
- lvPopupList = (ListView) layout.findViewById(R.id.lv_popup_list);
- pwMyPopWindow = new PopupWindow(layout);
- pwMyPopWindow.setFocusable(true);// 加上这个popupwindow中的ListView才可以接收点击事件
- lvPopupList.setAdapter(new SimpleAdapter(MainActivity.this, moreList,
- R.layout.list_item_popupwindow, new String[] { "share_key" },
- new int[] { R.id.tv_list_item }));
- lvPopupList.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- Toast.makeText(MainActivity.this,
- moreList.get(position).get("share_key"),
- Toast.LENGTH_LONG).show();
- }
- });
- // 控制popupwindow的宽度和高度自适应
- lvPopupList.measure(View.MeasureSpec.UNSPECIFIED,
- View.MeasureSpec.UNSPECIFIED);
- pwMyPopWindow.setWidth(lvPopupList.getMeasuredWidth());
- pwMyPopWindow.setHeight((lvPopupList.getMeasuredHeight() + 20)
- * NUM_OF_VISIBLE_LIST_ROWS);
- // 控制popupwindow点击屏幕其他地方消失
- pwMyPopWindow.setBackgroundDrawable(this.getResources().getDrawable(
- R.drawable.bg_popupwindow));// 设置背景图片,不能在布局中设置,要通过代码来设置
- pwMyPopWindow.setOutsideTouchable(true);// 触摸popupwindow外部,popupwindow消失。这个要求你的popupwindow要有背景图片才可以成功,如上
- }
- }
activity_main.xml:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity"
- android:background="#ffffff" >
- <LinearLayout
- android:id="@+id/ll_head_bar"
- style="@style/header_linear_layout"
- android:layout_alignParentTop="true" >
- <Button
- android:id="@+id/btn_back"
- style="@style/header_button_back"
- android:layout_marginLeft="8dip" />
- <TextView
- style="@style/header_text_view"
- android:visibility="invisible" />
- <ImageButton
- android:id="@+id/ib_operate_more"
- style="@style/header_button_operate"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="10dip"
- android:src="@drawable/ico_headbar_more" />
- </LinearLayout>
- </RelativeLayout>
list_item_popupwindow.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="match_parent"
- android:gravity="center"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/tv_list_item"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:minHeight="40dp"
- android:minWidth="120dp"
- android:textSize="20sp"
- android:textColor="@color/popupwindow_list_item_text_selector"
- />
- </LinearLayout>
task_detail_popupwindow.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:orientation="vertical"
- >"
- <ListView
- android:id="@+id/lv_popup_list"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:listSelector="#00000000"
- android:divider="@drawable/ico_list_item_line_popupwindow"
- android:focusableInTouchMode="true"
- />
- </LinearLayout>
注意:如果你想让自己的popupwindow在Activity启动的时候就显示的话,不能放在onCreate方法中,因为这个时候,界面组件还未加载好,所以会提示你你的Activity是否已经启动了,你可以放在onAttachedToWindow方法中。
关于显示的位置还有一个方法showAtLocation(parent, gravity, x, y)
这里的参数parent指的是这个popupwindow相对的是哪个父类,比如你想要让这个popupwindow相对于整个屏幕那么你的parent可以是
- View parent = this.getWindow().getDecorView();
parent.getHeight()得到的值是你的屏幕的高度(像素)。
这个时候,x,y就是它在这个parent中的相对位置了。Gravity默认是左上Left,Top
例如:下面的代码设置了popupwindow在屏幕的左下角的位置。
- View parent = this.getWindow().getDecorView();//高度为手机实际的像素高度
- pwMyPopWindow.showAtLocation(parent, Gravity.NO_GRAVITY, (int)(parent.getWidth()/18), parent.getHeight() - btnAddTask.getHeight() - (int)(parent.getHeight()/9));
还有一些style,color之类的属性这里就不贴出来了。有兴趣的同学可以下载实例下来看看
项目地址:
https://github.com/michaelye/PopupwindowDemo.git