PopupWindow 类位于android.widget 包下,API注释为:
PopupWindow 是一个浮于当前activity之上、用于显示任意 view 的容器。
使用PopupWindow 的大致步骤:
首先需要创建一个PopupWindow 对象,可以使用的构造函数有
其中,contentView为PopupWindow需要展现的内容,width为contentView 的宽度,height为contentView 的高度,可以是像素值,也可以是MATCHT_PARENT 和 WRAP_CONTENT。focusable代表能否获得焦点。
这几个参数还可以通过以下方法来设置:
public void setContentView(View contentView) {} // 设置显示内容 public void setWidth(int width) {} //设置宽度 public void setHeight(int height) {} //设置高度 public void setFocusable(boolean focusable) {} //设置获取焦点
可通过getWidth()和getHeight()方法获取显示内容的宽度和高度
拿public PopupWindow(View contentView, int width, int height, boolean focusable) {}这个构造函数举例,在设置好需要显示的内容、宽度和高度等属性之后,接下来需要做的就是确定PopupWindow的显示位置和方式。
public void setAnimationStyle(int animationStyle) {} //设置PopupWindow的动画效果
显示位置可以有如下几种选择:
public void showAsDropDown(View anchor) {} // 相对于anchor的左下角开始显示 public void showAsDropDown(View anchor, int xoff, int yoff) {} // 相对于anchor的左下角一定的偏移量开始显示 public void showAtLocation(View parent, int gravity, int x, int y) {} // 相对于parent 一定的偏移量开始显示
到此,展示内容、宽度、高度、展示位置和动画效果都确定了,可以说简单的实现已经完成。另外
public void dismiss() {} // 收起PopupWindow
想要在PopupWindow之外的地方点击屏幕收起PopupWindow需要使用如下两个方法(必须同时使用):
statePopupwindow.setOutsideTouchable(true); statePopupwindow.setBackgroundDrawable(new BitmapDrawable()); // 必须使用该方法的原因,网上已有比较详细的答案
下边是Demo部分代码:
MainActivity.java:
public class MainActivity extends Activity implements OnClickListener { private TextView tvStateLimited; private TextView tvTimeLimited; private View stateWindowView; private LinearLayout llBackgroundGray; private PopupWindow statePopupwindow; private CompeteTitleAdapter titleAdapter; private List<String> listState = null; private int loc_state = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); findView(); initData(); setListener(); } private void initData() { listState = new ArrayList<String>(); String[] state = getResources().getStringArray(R.array.HandleState); for (int i = 0; i < state.length; i++) { listState.add(state[i]); } } private void setListener() { tvStateLimited.setOnClickListener(this); } private void findView() { tvStateLimited = (TextView) findViewById(R.id.tv_state_limited); tvTimeLimited = (TextView) findViewById(R.id.tv_time_limited); llBackgroundGray = (LinearLayout) findViewById(R.id.ll_background_gray); stateWindowView = getLayoutInflater().inflate(R.layout.state_popupwindow_content_layout, null, false); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tv_state_limited: llBackgroundGray.setVisibility(View.VISIBLE); initStateSelect(); statePopupwindow.showAsDropDown(tvTimeLimited); break; default: break; } } private void initStateSelect() { statePopupwindow = new PopupWindow(stateWindowView, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true); statePopupwindow.setAnimationStyle(R.style.AnimationPreview); statePopupwindow.setOutsideTouchable(true); statePopupwindow.setBackgroundDrawable(new BitmapDrawable()); ListView stateListView = (ListView) stateWindowView.findViewById(R.id.listView_select_left); titleAdapter = new CompeteTitleAdapter(this, listState, loc_state); stateListView.setAdapter(titleAdapter); statePopupwindow.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { llBackgroundGray.setVisibility(View.GONE); } }); stateListView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { loc_state = arg2; statePopupwindow.dismiss(); } }); } }
activity_main.xml:
<LinearLayout 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" android:orientation="vertical" tools:context="com.hwgt.popupwindow.MainActivity" > <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="#ffffff" android:divider="@drawable/ic_pop_divider" android:orientation="horizontal" android:showDividers="middle" > <TextView android:id="@+id/tv_state_limited" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:paddingLeft="17dp" android:paddingRight="17dp" android:singleLine="true" android:text="全部" android:textColor="#303233" android:textSize="17dp" /> <TextView android:id="@+id/tv_time_limited" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:paddingLeft="17dp" android:paddingRight="17dp" android:singleLine="true" android:text="不限" android:textColor="#303233" android:textSize="17dp" /> </LinearLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:id="@+id/ll_background_gray" android:layout_width="match_parent" android:layout_height="match_parent" android:alpha="0.5" android:background="#55000000" android:orientation="vertical" android:visibility="gone" > </LinearLayout> </RelativeLayout> </LinearLayout>
arrays.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="HandleState"> <item>全部</item> <item>已提交</item> <item>已拒绝</item> <item>已处理</item> <item>已过期</item> </string-array> </resources>
CompeteTitleAdapter.java:
public class CompeteTitleAdapter extends BaseAdapter { public List<String> list; private Context context; private int selected_location = 0; public CompeteTitleAdapter(Context context, List<String> list, int selected_location) { this.context = context; this.list = list; this.selected_location = selected_location; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } public int getItemViewType(int position, List<String> list) { if (position == (list.size() - 1) && list.size() > 1) return 0; else if (position == 0 && (list.size() == 1)) { return 2; } else return 1; } @Override public View getView(final int position, View convertView, ViewGroup parent) { if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(context); convertView = inflater.inflate(R.layout.listitem_extra_reserve_title, null); } TextView tv = (TextView) convertView.findViewById(R.id.myspinner_dropdown_txt); tv.setText(list.get(position)); if (position == selected_location) { tv.setTextColor(context.getResources().getColor(R.color.consult_issolved_green)); } else { tv.setTextColor(context.getResources().getColor(R.color.text_black)); } return convertView; } }
styles.xml:
<style name="AnimationPreview"> <!-- PopupWindow弹出的效果 --> <item name="android:windowEnterAnimation">@anim/fade_in</item> <item name="android:windowExitAnimation">@anim/fade_out</item> </style>
anim-fade_in.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:fromXScale="1.0" android:toXScale="1.0" android:fromYScale="0.0" android:toYScale="1.0" android:pivotX="100%" android:pivotY="0" android:duration="500" android:fillAfter="false"/> </set>
anim-fade_out.xml:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <scale android:fromXScale="1.0" android:toXScale="1.0" android:fromYScale="1.0" android:toYScale="0.0" android:pivotX="100%" android:pivotY="0" android:duration="500" /> </set>
state_popupwindow_content_layout.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/production_factory" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/transparent" android:orientation="horizontal"> <ListView android:id="@+id/listView_select_left" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:cacheColorHint="@android:color/transparent" android:fadingEdge="none" android:listSelector="@drawable/sel_state_popupwindow_item" android:background="#e9e9e9"> </ListView> </LinearLayout>