Android 仿IOS的PopupWindow和通用BaseP

作者: Kandy_JS | 来源:发表于2018-10-29 20:11 被阅读49次

    截图

    pw.png

    实现

    1、BasePopupWindow.java

    1.1、实现动态加载不同layout
    1.2、动态配置是否弹出后背景半透明,关闭时候恢复(监听ondismiss,靠window类来变色)
    1.3、一些基础性的方法抽象方法
    1.4、为了更加复杂的样式和动效,可以继续扩展此类

    /**
     * Created by wujn on 2018/10/29.
     * Version : v1.0
     * Function: base popuwindow
     */
    public abstract class BasePopupWindow extends PopupWindow implements View.OnClickListener{
    
        /**
         * 上下文
         */
        private Context context;
        /**
         * 最上边的背景视图
         */
        private View vBgBasePicker;
        /**
         * 内容viewgroup
         */
        private LinearLayout llBaseContentPicker;
    
        public BasePopupWindow(Context context) {
            super(context);
            this.context = context;
            View parentView = View.inflate(context, R.layout.base_popup_window_picker, null);
            vBgBasePicker = parentView.findViewById(R.id.v_bg_base_picker);
            llBaseContentPicker = (LinearLayout) parentView.findViewById(R.id.ll_base_content_picker);
            /***
             * 添加布局到界面中
             */
            llBaseContentPicker.addView(View.inflate(context, bindLayout(), null));
            setContentView(parentView);
            //设置PopupWindow弹出窗体的宽
            this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
            //设置PopupWindow弹出窗体的高
            this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
            //在PopupWindow里面就加上下面代码,让键盘弹出时,不会挡住pop窗口。
            this.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
            this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
            setFocusable(true);//设置获取焦点
            setTouchable(true);//设置可以触摸
            setOutsideTouchable(true);//设置外边可以点击
            ColorDrawable dw = new ColorDrawable(0xffffff);
            setBackgroundDrawable(dw);
            //设置SelectPicPopupWindow弹出窗体动画效果
            this.setAnimationStyle(R.style.BottomDialogWindowAnim);
            initView(parentView);
            initListener();
            initData();
            vBgBasePicker.setOnClickListener(this);
            //是否需要屏幕半透明
            setBackgroundHalfTransition(isNeedBackgroundHalfTransition());
        }
    
        /**
         * 初始化布局
         *
         * @return
         */
        protected abstract int bindLayout();
    
        /**
         * 初始化view
         *
         * @param parentView
         */
        protected abstract void initView(View parentView);
    
        /**
         * 初始化数据
         */
        protected abstract void initData();
    
        /**
         * 初始化监听
         */
        protected abstract void initListener();
    
    
    
    
    
        /**
         * 为了适配7.0系统以上显示问题(显示在控件的底部)
         *
         * @param anchor
         */
        @Override
        public void showAsDropDown(View anchor) {
            if (Build.VERSION.SDK_INT >= 24) {
                Rect rect = new Rect();
                anchor.getGlobalVisibleRect(rect);
                int h = anchor.getResources().getDisplayMetrics().heightPixels - rect.bottom;
                setHeight(h);
            }
            super.showAsDropDown(anchor);
            if(isNeedBgHalfTrans){
                backgroundAlpha(0.5f);
            }
        }
    
        /**
         * 展示在屏幕的底部
         *
         * @param layoutid rootview
         */
        public void showAtLocation(@LayoutRes int layoutid) {
            showAtLocation(LayoutInflater.from(context).inflate(layoutid, null),
                    Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);
            if(isNeedBgHalfTrans){
                backgroundAlpha(0.5f);
            }
        }
    
    
        /**
         * 最上边视图的点击事件的监听
         *
         * @param v
         */
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.v_bg_base_picker:
                    dismiss();
                    break;
            }
        }
    
        /**
         * 是否设置背景半透明
         * */
        public boolean isNeedBackgroundHalfTransition(){
            return false;
        }
    
        private boolean isNeedBgHalfTrans = false;
        private void setBackgroundHalfTransition(boolean isNeed){
            isNeedBgHalfTrans = isNeed;
            if(isNeedBgHalfTrans){
                this.setOnDismissListener(new OnDismissListener() {
                    @Override
                    public void onDismiss() {
                        backgroundAlpha(1f);
                    }
                });
            }
        }
    
        /**
         * 设置添加屏幕的背景透明度
         * @param bgAlpha
         */
        private void backgroundAlpha(float bgAlpha) {
            WindowManager.LayoutParams lp = ((Activity)context).getWindow().getAttributes();
            lp.alpha = bgAlpha; //0.0-1.0
            ((Activity)context).getWindow().setAttributes(lp);
        }
    
    
    }
    
    2、base_popup_window_picker.xml
    <?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:orientation="vertical">
    
        <View
            android:id="@+id/v_bg_base_picker"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1" />
    
        <LinearLayout
            android:id="@+id/ll_base_content_picker"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:orientation="vertical" />
    </LinearLayout>
    
    3、进入和退出时候的动画style
    <!--animanation-->
        <!-- 底部的dialog弹出的动画样式-->
        <style name="BottomDialogWindowAnim" parent="android:Animation">
            <item name="android:windowEnterAnimation">@anim/popup_bottom_enter_anim</item>
            <item name="android:windowExitAnimation">@anim/popup_bottom_exit_anim</item>
        </style>
    

    进入动画:popup_bottom_enter_anim.xml

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

    退出动画:popup_bottom_exit_anim.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate
            android:duration="200"
            android:fromYDelta="0"
            android:toYDelta="50%p" />
        <alpha
            android:duration="200"
            android:fromAlpha="1.0"
            android:toAlpha="0.0" />
    
    </set>
    
    4、仿IOS的layout:popup_window_album_or_camera.xml
    <?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:orientation="vertical"
        android:padding="10dp">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_shape_corner_white"
            android:orientation="vertical">
    
            <Button
                android:id="@+id/btnCamera"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@null"
                android:text="拍照"
                android:textColor="@color/dodgerblue"
                android:textSize="@dimen/normal_text_size" />
    
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@color/gray_1" />
    
    
            <Button
                android:id="@+id/btnAlbum"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@null"
                android:text="从相册中选择"
                android:textColor="@color/dodgerblue"
                android:textSize="@dimen/normal_text_size" />
        </LinearLayout>
    
    
        <LinearLayout
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_shape_corner_white"
            android:orientation="vertical">
    
            <Button
                android:id="@+id/btnCancel"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@null"
                android:text="@string/cancel"
                android:textColor="@color/dodgerblue"
                android:textSize="@dimen/normal_text_size" />
    
        </LinearLayout>
    
    </LinearLayout>
    

    item的背景style

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <solid android:color="@color/white" />
        <corners android:radius="6dp"/>
        <stroke android:width="1dp" android:color="@color/gray_1" />
    </shape>
    
    5、仿IOS的popuwindow类:AlbumOrCameraPopupWindow
    public class AlbumOrCameraPopupWindow extends BasePopupWindow {
    
        private Button btnCamera;
        private Button btnAlbum;
        private Button btnCancel;
    
        private OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener;
        public AlbumOrCameraPopupWindow(Context context,OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener) {
            super(context);
            this.onCameraOrAlbumSelectListener = onCameraOrAlbumSelectListener;
        }
    
        @Override
        public boolean isNeedBackgroundHalfTransition(){
            return true;
        }
    
        @Override
        protected int bindLayout() {
            return R.layout.popup_window_album_or_camera;
        }
    
        @Override
        protected void initView(View parentView) {
            btnCamera = (Button) parentView.findViewById(R.id.btnCamera);
            btnAlbum = (Button) parentView.findViewById(R.id.btnAlbum);
            btnCancel = (Button) parentView.findViewById(R.id.btnCancel);
        }
    
        @Override
        protected void initData() {
    
        }
    
        @Override
        protected void initListener() {
            btnCamera.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismiss();
                    if(onCameraOrAlbumSelectListener != null){
                        onCameraOrAlbumSelectListener.OnSelectCamera();
                    }
                }
            });
    
            btnAlbum.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismiss();
                    if(onCameraOrAlbumSelectListener != null){
                        onCameraOrAlbumSelectListener.OnSelectAlbum();
                    }
                }
            });
    
            btnCancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dismiss();
                }
            });
        }
    
    }
    

    选择相机或者相册的监听接口

    public interface OnCameraOrAlbumSelectListener {
        public void OnSelectCamera();
        public void OnSelectAlbum();
    }
    
    6、具体使用
    private AlbumOrCameraPopupWindow ACWindow;
        private void initListener(){
            ACWindow = new AlbumOrCameraPopupWindow(this, onCameraOrAlbumSelectListener);
            btnIosPopupWindow.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(ACWindow != null && !ACWindow.isShowing()){
                        ACWindow.showAtLocation(R.layout.activity_view_popup_window);
                    }
                }
            });
        }
    
        /**选择相机或者相册*/
        private OnCameraOrAlbumSelectListener onCameraOrAlbumSelectListener = new OnCameraOrAlbumSelectListener() {
            @Override
            public void OnSelectCamera() {
                LogUtil.i("OnSelectCamera...");
                ToastUtil.showShort(instance, "相机");
            }
    
            @Override
            public void OnSelectAlbum() {
                LogUtil.i("OnSelectAlbum...");
                ToastUtil.showShort(instance, "从相册中选择");
            }
        };
    

    朝CV工程师又进一步~~~😆

    相关文章

      网友评论

      • 榴莲小哥:得到APP 全平台全部付费课(共4T)原音质音频+图文全部打包¥68,含金量超乎想象限时免费试听!点头像私信
      • 我欠你的不只是一句对不起:楼主你好,最近遇到一个问题,不管使用popupwindow还是dialog设置了动画,当popupwindow或dialog显示时,按home键popupwindow或dialog会出现退出动画,重新进入应用,又会出现进入的动画,有办法解决吗

      本文标题:Android 仿IOS的PopupWindow和通用BaseP

      本文链接:https://www.haomeiwen.com/subject/xsjitqtx.html