首页 > 技术文章 > Android - PopupWindow

hwgt 2016-04-18 14:13 原文

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>

 

  

 

 

 

推荐阅读