Android PopupWindow的使用
2015-11-24 17:21
483 查看
摘要: 在工作中会遇到这种情况,调用系统的对话框会觉得很不舒服,跳转到另一个页面时跳转到的页面内容有比较少。这个时候我们可以采用当前页面弹出PopupWindow来实现自己想要的效果。
下面是一个弹出带ListView和TextView的PopupWindow实例:
这是弹出框的布局文件:
style中添加:
drawable中添加dialog_enter.xml和dialog_exit.xml:
补充:
在用PopupWindow实现底部弹出菜单的时候要注意几个问题:
1)如果弹出菜单中有EditText这种输入控件,如果不给PopupWindow设置可获取焦点的话,EditText是无法获取输入的。
2)一定要设置 虚拟软键盘随需要更改屏幕显示内容的大小,否则虚拟软键盘会被底部弹出菜单遮挡。
3)如果设置了PopupWindow可获取焦点的话,此时会遇到一个问题就是当PopupWindow中的控件比如EditText获取焦点之后,点击PopupWindow之外的控件是不会有响应的,如果用setBackgroundDrawable(new BitmapDrawable())进行设置的话,则不会出现这种情况。
//设置可以获取焦点,否则弹出菜单中的EditText是无法获取输入的
popWindow.setFocusable(true);
//这句是为了防止弹出菜单获取焦点之后,点击activity的其他组件没有响应
popWindow.setBackgroundDrawable(new BitmapDrawable());
//防止虚拟软键盘被弹出菜单遮住
popWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//在底部显示
popWindow.showAtLocation(this,Gravity.BOTTOM, 0, 0);
4)popupWindow.setBackgroundDrawable(new BitmapDrawable()); // 需要设置一下此参数,点击外边可消失, 如果不设置PopupWindow的背景,无论是点击外部区域还是Back键都无法dismiss弹框
popupWindow.setOutsideTouchable(true); // 设置popwindow如果点击外面区域,便关闭。
popupWindow.setFocusable(true); // 设置此参数获得焦点,否则无法点击
popupWindow.update();
5)PopupWindow和AlertDialog的区别
Android的对话框有两种:PopupWindow和AlertDialog。它们的不同点在于:
AlertDialog的位置固定,而PopupWindow的位置可以随意
AlertDialog是非阻塞线程的,而PopupWindow是阻塞线程的
PopupWindow的位置按照有无偏移分,可以分为偏移和无偏移两种;按照参照物的不同,可以分为相对于某个控件(Anchor锚)和相对于父控件。具体如下
showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
下面是一个弹出带ListView和TextView的PopupWindow实例:
import android.app.Activity; import android.content.Context; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.PopupWindow; import android.widget.TextView; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; /** * Created by SRain on 2015/10/15. * <p/> * 弹出框 */ public class PopupWindowUtils implements View.OnClickListener { private PopupWindow popupWindow; private Context context; private View view; private TextView tvClose; private JSONArray jsonArray; private BasicPopuListAdapter adapter; //ListView的适配器 public PopuWindowUtils(Context context, View view, JSONArray jsonArray, int index) { this.context = context; this.view = view; this.jsonArray = jsonArray; initPopuWindow(index); } /** * 弹出popupwindow * * @param index 弹出框样式标识 */ private void initPopuWindow(final int index) { View contentView = LayoutInflater.from(context).inflate(R.layout.layout_popupwindow, null); ListView listView = (ListView) contentView.findViewById(R.id.lv_files); tvClose = (TextView) contentView.findViewById(R.id.tvClose); tvClose.setVisibility(View.VISIBLE); tvClose.setOnClickListener(this); /* * 创建PopupWindow实例 * getScreenWidth(), (int) (getScreenWidth() * 0.6))分别是宽度和高度 */ if (popupWindow == null) { popupWindow = new PopupWindow(contentView, getScreenWidth(), (int) (getScreenWidth() * 0.6)); } // 自定义view添加触摸事件 contentView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (popupWindow != null && popupWindow.isShowing()) { popupWindow.dismiss(); return true; } // 这里如果返回true的话,touch事件将被拦截 // 拦截后 PopupWindow的onTouchEvent不被调用,这样点击外部区域无法dismiss return false; } }); switch (index) { case 1: adapter = new RoutePupuAdapter(context, jsonArray); break; } listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { try { adapter.setSelectedPosition(position); // 更新列表框 adapter.notifyDataSetInvalidated(); JSONObject object = jsonArray.getJSONObject(position); clickFunction(index, object); } catch (JSONException e) { Log.e("onItemClick", e.toString()); } } }); popupWindow.setAnimationStyle(R.style.PopupAnimation); popupWindow.setFocusable(true); /* * 弹出框位置 */ popupWindow.showAsDropDown(view, 0, -110); //popupWindow.showAtLocation(MainActivity.this.findViewById(R.id.main), Gravity.BOTTOM|Gravi //ty.CENTER_HORIZONTAL, 0, 0); //设置layout在PopupWindow中显示的位置,从底部弹出 } /** * 根据屏幕宽度设置高度值 */ private int getScreenWidth() { //获取屏幕宽度 DisplayMetrics dm = new DisplayMetrics(); double densityDpi = dm.density; //获取屏幕信息 ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm); int screenWidth = dm.widthPixels; return screenWidth; } public void clickFunction(int index, JSONObject json) { switch (index) { case 1: ((LocationMapActivity) context).initRoadLines(json); break; } } /** * 销毁PopupWindow */ public boolean dismissPopu() { if (popupWindow != null && popupWindow.isShowing()) { popupWindow.dismiss(); return true; } return false; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tvClose: dismissPopu(); break; } } }
//这是BasicPopuListAdapter代码,自己的listview中adapter继承它就可以了: import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import org.json.JSONArray; import org.json.JSONObject; /** * Created by SRain on 2015/10/20. * <p/> * 普通listview适配器 */ public abstract class BasicPopuListAdapter extends BaseAdapter { protected Context context; protected JSONArray array; protected LayoutInflater mInflater; private int selectedPosition = -1; public BasicPopuListAdapter(Context context, JSONArray array) { this.context = context; this.array = array; mInflater = LayoutInflater.from(context); } @Override public int getCount() { return array.length(); } @Override public Object getItem(int position) { JSONObject object = null; try { object = array.getJSONObject(position); } catch (Exception e) { } return object; } @Override public long getItemId(int position) { return position; } @Override public abstract View getView(int position, View convertView, ViewGroup parent); public abstract void setSelectedPosition(int position); public JSONArray getData(){ return this.array; } }
这是弹出框的布局文件:
<?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:background="@color/result_view" android:orientation="vertical"> <ListView android:id="@+id/lv_files" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@+id/tvClose" android:layout_marginTop="2dp" android:visibility="gone" android:layout_width="match_parent" android:layout_height="45dp" android:background="@color/green" android:gravity="center" android:text="关闭" android:textColor="@color/white" /> </LinearLayout>
style中添加:
<style name="PopupAnimation" mce_bogus="1" parent="android:Animation"> <item name="android:windowEnterAnimation">@anim/dialog_enter</item> <item name="android:windowExitAnimation">@anim/dialog_exit</item> </style>
drawable中添加dialog_enter.xml和dialog_exit.xml:
<!--dialog_enter--> <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromYDelta="500" android:toYDelta="0" /> </set>
<!--dialog_exit--> <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromYDelta="0" android:toYDelta="500" /> </set>
补充:
在用PopupWindow实现底部弹出菜单的时候要注意几个问题:
1)如果弹出菜单中有EditText这种输入控件,如果不给PopupWindow设置可获取焦点的话,EditText是无法获取输入的。
2)一定要设置 虚拟软键盘随需要更改屏幕显示内容的大小,否则虚拟软键盘会被底部弹出菜单遮挡。
3)如果设置了PopupWindow可获取焦点的话,此时会遇到一个问题就是当PopupWindow中的控件比如EditText获取焦点之后,点击PopupWindow之外的控件是不会有响应的,如果用setBackgroundDrawable(new BitmapDrawable())进行设置的话,则不会出现这种情况。
//设置可以获取焦点,否则弹出菜单中的EditText是无法获取输入的
popWindow.setFocusable(true);
//这句是为了防止弹出菜单获取焦点之后,点击activity的其他组件没有响应
popWindow.setBackgroundDrawable(new BitmapDrawable());
//防止虚拟软键盘被弹出菜单遮住
popWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//在底部显示
popWindow.showAtLocation(this,Gravity.BOTTOM, 0, 0);
4)popupWindow.setBackgroundDrawable(new BitmapDrawable()); // 需要设置一下此参数,点击外边可消失, 如果不设置PopupWindow的背景,无论是点击外部区域还是Back键都无法dismiss弹框
popupWindow.setOutsideTouchable(true); // 设置popwindow如果点击外面区域,便关闭。
popupWindow.setFocusable(true); // 设置此参数获得焦点,否则无法点击
popupWindow.update();
5)PopupWindow和AlertDialog的区别
Android的对话框有两种:PopupWindow和AlertDialog。它们的不同点在于:
AlertDialog的位置固定,而PopupWindow的位置可以随意
AlertDialog是非阻塞线程的,而PopupWindow是阻塞线程的
PopupWindow的位置按照有无偏移分,可以分为偏移和无偏移两种;按照参照物的不同,可以分为相对于某个控件(Anchor锚)和相对于父控件。具体如下
showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
相关文章推荐
- android教程之使用popupwindow创建菜单示例
- android PopupWindow 和 Activity弹出窗口实现方式
- Android PopupWindow 点击外面取消实现代码
- android自定义popupwindow仿微信右上角弹出菜单效果
- Android PopupWindow使用实例
- Android中PopupWindow响应返回键并关闭的2种方法
- android使用PopupWindow实现页面点击顶部弹出下拉菜单
- Android入门之PopupWindow用法实例解析
- android popwindow实现左侧弹出菜单层及PopupWindow主要方法介绍
- 一段android跳转到web界面的代码
- 收藏各种技术源码
- PopupWindow gridview 无法响应Item
- PopupWindow 实现 弹出后 其余部分变灰(类似dialog)
- 一个简单的PopupWindow做的选项菜单点击按钮会在按钮下弹出几个下拉控件
- PopupWindow的使用
- PopupWindow(第一篇CSDN博客,希望能坚持写下去,也希望大家多多支持)
- PopupWindow的显示位置及简单的响应事件
- popupwindow上使用spinner,能显示,但当点击spinner时出现异常
- PopupWindow
- popupwindow 弹出框 使用详情