实现从底部弹出的PopupWindow

来源:互联网 发布:淘宝钻石展位考试 编辑:程序博客网 时间:2024/03/29 06:43

根据项目需求了一个从底部弹出的PopupWindow,它的作用是选择地址的。省份,市,区都在同一个里面,同时选择。先上效果图。
这里写图片描述

一、思路

1、用一个ListView加载这三个部分的数据,在切换的时候,直接切换数据选择。
2、选完某个地址时,对外提供一个回调事件,比如在省份选择后,则应该查询对应的城市,这时候是要对外提供接口,查询到城市的数据后,再切换到城市的选择。
3、一个从底部弹出的popupwindow的实现。

二、代码实现

1、在构造方法里,初始化popupWindow,需要继承PopupWindow

public MyPopupWindow(final Activity activity, final View parent,            List<String> provinces) {        this.activity = activity;        this.provinces = provinces;        citys = new ArrayList<String>();        districts =new ArrayList<String>();        view = LayoutInflater.from(activity).inflate(R.layout.my_pop, null);        //透明度    view.startAnimation(AnimationUtils.loadAnimation(activity,R.anim.fade_ins));    //从下往上出现         view.startAnimation(AnimationUtils.loadAnimation(activity,                R.anim.push_bottom_in));        //设置它的宽高        setWidth(LayoutParams.MATCH_PARENT);        setHeight(LayoutParams.WRAP_CONTENT);        // 实例化一个ColorDrawable颜色为半透明        ColorDrawable dw = new ColorDrawable(0xb0000000);        // 设置SelectPicPopupWindow弹出窗体的背景        this.setBackgroundDrawable(dw);        setFocusable(true);        setOutsideTouchable(true);        setContentView(view);        initView();        initListener();        initData();    }

2、点击其他区域,取消popupview。

这部分代码是放在initListener();方法里面,单独抽出来的。取消它的时候同时在setOnDismissListener()里改变Activity的透明度。

        view.setOnTouchListener(new OnTouchListener() {            public boolean onTouch(View v, MotionEvent event) {                switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    int y = (int) event.getY();                    // 没有点击到布局的区域                    if (isShowing()) {                        if (ll_content != null) {                            if (y < getScreenHeight()                                    - (ll_content.getHeight() + 50)) {                                dismiss();                            }                        } else {                            if (y < getScreenHeight() - (view.getHeight() + 50)) {                                dismiss();                            }                        }                    }                    break;                default:                    break;                }                return true;            }        });        setOnDismissListener(new OnDismissListener() {            @Override            public void onDismiss() {                params = activity.getWindow().getAttributes();                params.alpha = 1f;                activity.getWindow().setAttributes(params);            }        });

3、对外提供更新数据的接口

共3个接口,主要是对外提供选中的数据,同时获取对应的地区的数据,让用户进行下一步的选择。

/**     * @author Lenovo     *选择省份后回调事件,这时候就要查询省份,对应的城市,需要自行保存省份的值,之后不在传     */    public interface SelectProvince{        /**param 选中的省份*/        public void onSelectProvince(String province,MyAdapter myAdapter);    }    /**     * @author Lenovo     *选择城市后回调事件,这时候要查询城市对应的地区,需要自行保存城市的值,之后不在传     */    public interface SelectCity{        public void onSelectCity(String city,MyAdapter myAdapter);    }    /**     * @author Lenovo     *选择地区后回调事件     */    public interface SelectDistrict{        public void onSelectDistrict(String district,MyAdapter myAdapter);    }

4、设置Listview的点击事件,并调用上面的接口。

listView.setOnItemClickListener(new OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> arg0, View view, int pos,                    long id) {                if(currentPos==0){//省份                    provinceSelected = pos;                    citySelected = 0;                    districtSelected = 0;                    tv_city.setVisibility(View.VISIBLE);                    showLine(1);                    if(selectProvince!=null){//回调事件1                        selectProvince.onSelectProvince(provinces.get(pos),myAdapter);                    }                    tv_province.setText(provinces.get(pos));                }else if(currentPos==1){//市区                    citySelected = pos;                    districtSelected = 0;                    tv_district.setVisibility(View.VISIBLE);                    showLine(2);                    if(selectCity!=null){//回调事件2                                             selectCity.onSelectCity(citys.get(pos), myAdapter);                    }                    tv_city.setText(citys.get(pos).toString());                }else if(currentPos==2){//区域                    districtSelected = pos;                    if(selectDistrict!=null){                    //回调事件3                        selectDistrict.onSelectDistrict(districts.get(pos).toString(), myAdapter);                    }                    tv_district.setText(districts.get(pos).toString());                    //选完区域后结束                    dismiss();                }            }        });

5、实现透明度、从下往上的动画。

<?xml version="1.0" encoding="utf-8"?><alpha xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="20"    android:fromAlpha="0.0"    android:toAlpha="1.0" />
<?xml version="1.0" encoding="utf-8"?><translate xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="100"    android:fromYDelta="100%"    android:interpolator="@android:anim/decelerate_interpolator"    android:toYDelta="0" />

6、显示PopupWindow

要设置外部Activity的透明度,如下代码。

public void showPopupWindow(View parent){        params = activity.getWindow().getAttributes();        params.alpha = 0.7f;        activity.getWindow().setAttributes(params);        showAtLocation(parent, Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0);    }

7、外部Activity调用PopupWindow

主要是实现PopupWindow 所提供的三个接口

pop = new MyPopupWindow(this, content, provinces);pop.setSelectProvinceListener(new SelectProvince() {            @Override            public void onSelectProvince(String province, MyAdapter myAdapter) {                area = province;                bt1.setText(area);                //查询对应的城市                pop.setCitys(citys);                myAdapter.setDatas(citys);                myAdapter.notifyDataSetChanged();            }        });        pop.setSelectCityListener(new SelectCity() {            @Override            public void onSelectCity(String city, MyAdapter myAdapter) {                area += city;                bt1.setText(area);                //查询对应的区                pop.setDistricts(districts);                myAdapter.setDatas(districts);                myAdapter.notifyDataSetChanged();            }        });        pop.setSelectDistrictListener(new SelectDistrict() {            @Override            public void onSelectDistrict(String district, MyAdapter myAdapter) {                area += district;                bt1.setText(area);            }        });

8、其它的一下方法

/**     * 获取屏幕高度     *      * @return     */    public int getScreenHeight() {        int screenHeight = 0;        DisplayMetrics dm = new DisplayMetrics();        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);        if (dm != null) {            int screenWidth = dm.widthPixels;// 屏幕宽度            int height = dm.heightPixels;// 全屏幕高度            int statusBarHeight = getStatusBarHeight(activity);// 状态栏高度            screenHeight = height - statusBarHeight;// 屏幕高度        }        return screenHeight;    }    /**     * 获取状态栏高度     *      * @param activity     * @return     */    public int getStatusBarHeight(Activity activity) {        int result = 0;        int resourceId = activity.getResources().getIdentifier(                "status_bar_height", "dimen", "android");        if (resourceId > 0) {            result = activity.getResources().getDimensionPixelSize(resourceId);        }        return result;    }

三、总结

总体上实现这个控件还是比较简单的,主要是比较繁琐而已,其它的一些基础代码如布局文件,适配器等就不贴出来了。

源码

0 0
原创粉丝点击