Android自定义弹窗,实现仿ios底部弹窗

2,834 阅读2分钟

「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

在没有对接支付时,利用收款码曲线救国,现在有个需求,点击支付弹出底部弹窗,选择支付类型,弹出对应的收款码。(举个例子哈)

那就封装起来吧

既然是弹窗不妨就用PopupWindow实现

首先new一个类继承于PopupWindow

public class IosPopupWindow extends PopupWindow

接着定义变量

private String PaymentCodeTitle;//弹窗的标题
//支付的类型
private int PAY_TYPE_Alipay = 0;
private int PAY_TYPE_WeChat = 1;

private Activity mActivity;

private View dialogView;
private String dialogMessage = null;

仿ios布局效果
ios_popup_window_layout.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="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:background="@drawable/popup_shape"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="9dp"
            android:text="请选择支付类型"
            android:textColor="#666"
            android:textSize="14sp" />

        <View
            android:layout_width="match_parent"
            android:layout_height="0.1px"
            android:background="#888" />

        <TextView
            android:id="@+id/tv_Alipay"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="16dp"
            android:text="支付宝"
            android:textColor="@color/blue"
            android:textSize="18sp" />

        <View
            android:layout_width="match_parent"
            android:layout_height="0.1px"
            android:background="#888" />

        <TextView
            android:id="@+id/tv_WeChat"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="16dp"
            android:text="微信"
            android:textColor="@color/blue"
            android:textSize="18sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:background="@drawable/popup_shape">

        <TextView
            android:id="@+id/tv_cancel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="16dp"
            android:text="取消"
            android:textColor="@color/blue"
            android:textSize="18sp"
            android:textStyle="bold" />
    </LinearLayout>
</LinearLayout>

白色圆角效果 popup_shape.xml 此文件放在drawable文件夹下

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <corners
        android:topLeftRadius="20dp"
        android:topRightRadius="20dp"
        android:bottomRightRadius="20dp"
        android:bottomLeftRadius="20dp"/>
</shape>

实现构造函数,传入Activity和点击接口 并在里面设置布局和各个属性

  public IosPopupWindow(Activity context, OnClickListener itemsOnClick) {
        this.mActivity = context;
        mOnClickListener = itemsOnClick;
        View view = LayoutInflater.from(context).inflate(R.layout.ios_popup_window_layout, null);

        setContentView(view);
        setWidth( RelativeLayout.LayoutParams.MATCH_PARENT);
        setHeight( RelativeLayout.LayoutParams.WRAP_CONTENT);
        //设置背景,这个没什么效果,不添加会报错
        setBackgroundDrawable(new BitmapDrawable());
        //设置点击弹窗外隐藏自身
        setFocusable(true);
        setOutsideTouchable(true);
        //设置动画
        setAnimationStyle(R.style.ios_PopupWindow);

        //设置消失监听
        setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                dismissPopupWindow();
            }
        });
        //设置PopupWindow的View点击事件
        setOnPopupViewClick(view);
        //设置背景色
        setBackgroundAlpha(0.5f);
        
    }

弹出

Gravity.BOTTOM表示显示在底部

public void show(View parentView){
    //设置位置
    showAtLocation(parentView, Gravity.BOTTOM, 0, 66);
}

设置屏幕背景透明效果

public void setBackgroundAlpha(float alpha) {
    WindowManager.LayoutParams lp = mActivity.getWindow().getAttributes();
    lp.alpha = alpha;
    mActivity.getWindow().setAttributes(lp);
}
/**
 * ios弹窗点击事件
 *
 * @param view
 */
private void setOnPopupViewClick(View view) {
    dialogView = LayoutInflater.from(mActivity).inflate(R.layout.dialog_payment_qr_code_layout,null);
    ImageView iv =dialogView.findViewById(R.id.iv_payment_code);


    TextView tv_Alipay, tv_WeChat, tv_cancel;
    /**
     * 支付宝支付
     */
    tv_Alipay = (TextView) view.findViewById(R.id.tv_Alipay);
    tv_Alipay.setOnClickListener(v -> {

        dismissPopupWindow();
        PaymentCodeTitle ="支付宝支付";
        showPaymentCode(PAY_TYPE_Alipay);
    });
    /**
     * 微信支付
     */
    tv_WeChat = (TextView) view.findViewById(R.id.tv_WeChat);
    tv_WeChat.setOnClickListener(v -> {
        dismissPopupWindow();
        PaymentCodeTitle ="微信支付";
        showPaymentCode(PAY_TYPE_WeChat);

    });

    tv_cancel = (TextView) view.findViewById(R.id.tv_cancel);
    tv_cancel.setOnClickListener(v -> {
        //取消
        dismissPopupWindow();
        mOnClickListener.cancel();

    });
}

弹窗点击接口

private OnClickListener mOnClickListener;
public void setPopupOnClickListener(OnClickListener mPopupOnClickListener){
    this.mOnClickListener  = mPopupOnClickListener;
}
public interface OnClickListener{
    void alipayOnClick();//Alipay
    void weChatOnClick();//WeChat
    void cancel();//取消
}

点击支付类型之后就弹出二维码 我们用AlertDialog.Builder加自定义布局实现 dialogView就是开头定义的变量 创建布局,內部实际上就是view.addView()实现的

dialogView = LayoutInflater.from(mActivity).inflate(R.layout.dialog_payment_qr_code_layout,null);

接着在DialogBuilder里面设置视图

        alertDialogBuilder.setView(dialogView)

全部代码 dialog_payment_qr_code_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingStart="?attr/dialogPreferredPadding"
    android:paddingEnd="?attr/dialogPreferredPadding">
   <ImageView
       android:id="@+id/iv_payment_code"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
</FrameLayout>
/**
 * show二维码
 */
private void showPaymentCode(int PayType){

    dialogView = LayoutInflater.from(mActivity).inflate(R.layout.dialog_payment_qr_code_layout,null);
    //获取ImageView用来显示二维码
    ImageView iv =dialogView.findViewById(R.id.iv_payment_code);
    if (PayType==PAY_TYPE_Alipay){
        iv.setImageBitmap({你的Alipay码});
    } else if (PayType==PAY_TYPE_WeChat){
        iv.setImageBitmap({你的WeChat码});
    }
    AlertDialog.Builder alertDialogBuilder =  new MaterialAlertDialogBuilder(mActivity)
            .setView(dialogView)
            .setTitle(PaymentCodeTitle)//标题
            .setMessage(dialogMessage)//副标题
            .setPositiveButton(
                    "确定",new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        
                            if (PayType==PAY_TYPE_Alipay){
                                mOnClickListener.alipayOnClick();
                            }else {
                                mOnClickListener.weChatOnClick();
                            }
                        }
                    })
            .setNegativeButton("取消",null);
    alertDialogBuilder .show();
}

设置二维码的弹窗副标题 可以用来设置金额

public void setDialogMessage(String mag){
    this.dialogMessage = mag;
}

最后还有PopupWindow销毁弹窗

还要把背景颜色换回来

private void dismissPopupWindow() {
    dismiss();
    setBackgroundAlpha(1f);
}

调用方法

IosPopupWindow mPopupWindow = new IosPopupWindow(getActivity(), new IosPopupWindow.OnClickListener() {
    @Override
    public void alipayOnClick() {
    //弹出alipay码
    }

    @Override
    public void weChatOnClick() {
       //弹出weChat码
    }

    @Override
    public void cancel() {
    //取消
    }
});

mPopupWindow.setDialogMessage("点个赞吧");
mPopupWindow.show(v);

不放图的一律当水贴处理

IMG_20211116_233842.jpg 1637077548211.png