Android 仿IOS的PopupWindow和通用BasePopupWindow搭建

简介: 截图pw.png实现1、BasePopupWindow.java1.1、实现动态加载不同layout1.2、动态配置是否弹出后背景半透明,关闭时候恢复(监听ondismiss,靠window类来变色)1.

截图

img_9fe4d71e84b6b466807c25b64eef0d6f.png
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工程师又进一步~~~

目录
相关文章
|
24天前
|
搜索推荐 Android开发 iOS开发
安卓与iOS系统的用户界面设计对比分析
本文通过对安卓和iOS两大操作系统的用户界面设计进行对比分析,探讨它们在设计理念、交互方式、视觉风格等方面的差异及各自特点,旨在帮助读者更好地理解和评估不同系统的用户体验。
18 1
|
2月前
|
物联网 vr&ar Android开发
探索安卓与iOS操作系统的未来发展趋势
【2月更文挑战第9天】本文将深入探讨安卓与iOS操作系统的未来发展趋势。通过分析当前技术发展和市场趋势,我们将探讨移动操作系统在人工智能、虚拟现实、物联网等领域的应用前景,以及如何满足用户需求并提升用户体验。同时,我们还将着重讨论两大操作系统在隐私保护、系统优化和生态建设方面的不断改进。
24 4
|
2月前
|
搜索推荐 Android开发 iOS开发
探析安卓与iOS系统的优劣
【2月更文挑战第7天】安卓与iOS是当今手机市场上最主流的两款操作系统,各有优劣。本文将从用户体验、开放程度、生态系统等方面对两者进行深入探析,以期帮助读者更好地了解它们的特点。
|
22天前
|
搜索推荐 Android开发 iOS开发
安卓与iOS操作系统的发展与比较
在移动互联网时代,安卓和iOS两大操作系统在智能手机市场竞争激烈。本文将从技术架构、生态系统、用户体验等方面对安卓和iOS进行比较分析,探讨它们各自的特点和发展趋势。
|
1月前
|
Web App开发 前端开发 网络安全
前端分析工具之 Charles 录制 Android/IOS 手机的 https 应用
【2月更文挑战第21天】前端分析工具之 Charles 录制 Android/IOS 手机的 https 应用
47 1
前端分析工具之 Charles 录制 Android/IOS 手机的 https 应用
|
1月前
|
人工智能 算法 Android开发
探索未来:Android与iOS在人工智能时代的融合与创新
【2月更文挑战第13天】 在数字化时代的快速发展下,Android与iOS作为两大主流移动操作系统,它们在人工智能(AI)领域的融合与创新已成为推动科技进步的关键力量。本文将从操作系统的核心功能拓展、AI技术的集成应用,以及开发者生态系统的演变三个维度,深入探讨Android和iOS如何在AI时代实现协同发展,以及这一进程对用户体验、应用开发和行业趋势产生的深远影响。通过对比分析和案例研究,我们旨在揭示两大平台在AI驱动下的创新路径,及其对未来科技格局的塑造作用。
|
1月前
|
人工智能 自然语言处理 语音技术
探索未来:安卓与iOS在人工智能领域的竞争与合作
【2月更文挑战第12天】本文深入探讨了安卓和iOS两大操作系统在人工智能(AI)领域的发展现状、竞争态势及未来合作可能性。通过对比分析两系统在AI技术集成、开发者支持、用户体验优化等方面的表现,揭示了它们各自的优势与挑战。文章最终展望了一个既有竞争又充满合作的未来,认为安卓和iOS的共同进步将推动整个人工智能技术向前发展,为用户带来更加智能、便捷的生活体验。
|
1月前
|
搜索推荐 Android开发 iOS开发
探索未来:安卓与iOS双系统的融合与创新
【2月更文挑战第12天】 在数字化时代,智能手机操作系统的发展不仅代表了技术的进步,更是用户体验革新的前沿。本文深入探讨了安卓和iOS这两大主流操作系统的未来走向,特别是它们在技术融合与创新方面的可能性。通过分析当前的市场需求、技术挑战和潜在的发展机会,我们将展望一个可能出现的未来场景:一个结合了安卓开放性和iOS优雅体验的双系统融合平台。这不仅仅是对技术极限的挑战,更是对用户体验极致追求的一次探索。
36 2
|
1月前
|
人工智能 搜索推荐 Android开发
探索未来:安卓与iOS在人工智能时代的融合趋势
【2月更文挑战第12天】 在这篇探索性文章中,我们将深入分析安卓和iOS两大移动操作系统在人工智能(AI)时代的融合趋势。随着技术的飞速发展,AI已成为推动智能手机进化的关键力量。本文通过对安卓和iOS各自在AI领域的最新进展进行比较,揭示了两大平台如何在保持各自特色的同时,也在向着更加智能、更加个性化的方向发展。我们不仅聚焦于当前的技术现状,而且还将展望未来,探讨这一趋势对用户体验、应用开发以及整个科技生态的深远影响。
|
1月前
|
人工智能 安全 搜索推荐
探索未来:安卓与iOS在人工智能时代的融合与创新
【2月更文挑战第12天】随着人工智能(AI)技术的飞速发展,安卓和iOS系统作为智能手机操作系统的两大巨头,正面临着前所未有的融合与创新机遇。本文将从AI技术对移动操作系统的影响、两大系统在AI领域的创新应用,以及未来可能的融合方向三个方面进行深入探讨。通过对比分析,我们旨在揭示安卓和iOS在人工智能时代如何共同推进技术革新,为用户提供更加智能、便捷的服务体验。