博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android PopupWindow的使用
阅读量:5901 次
发布时间:2019-06-19

本文共 7293 字,大约阅读时间需要 24 分钟。

hot3.png

下面是一个弹出带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. * 

 * 弹出框 */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. * 

 * 普通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;    }}

这是弹出框的布局文件:

    
    

style中添加:

    
@anim/dialog_enter    
@anim/dialog_exit

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等),可以设置偏移或无偏移

 

转载于:https://my.oschina.net/u/2320057/blog/534867

你可能感兴趣的文章
leetcode 64. Minimum Path Sum
查看>>
textkit
查看>>
CentOS7+CDH5.14.0安装CDH错误排查: HiveServer2 该角色的进程已退出。该角色的预期状态为已启动...
查看>>
The Oregon Trail 俄勒冈之旅
查看>>
Excel VBA连接MySql 数据库获取数据
查看>>
Developing a Service Provider using Java API(Service Provider Interface)(转)
查看>>
BAE Flask UEditor 使用七牛云
查看>>
Bootstrap系列 -- 15. 下拉选择框select
查看>>
【转载】无限级分类的简单实例
查看>>
关于WinPE安装操作系统
查看>>
LeetCode Median of Two Sorted Arrays
查看>>
oschina程序开发
查看>>
mysql创建每月执行一次的event
查看>>
kafka集群部署
查看>>
STM8串口初始化寄存器配置
查看>>
ReactNative常用组件汇总
查看>>
openfaas 安装(docker swarm 模式)
查看>>
nested exception is java.lang.NoClassDefFoundError: net/sf/cglib/proxy/CallbackFilter
查看>>
“正在注册字体”问题解决
查看>>
[转]OPEN(SAP) UI5 学习入门系列之一:扫盲与热身(上)
查看>>