美文网首页
Dialog自定义布局实现

Dialog自定义布局实现

作者: 木溪bo | 来源:发表于2022-08-05 16:58 被阅读0次

    小记一次自定义ui布局的Dialog实现
    很多时候我们会收到设计师各种花样别出的弹窗需求,比如各种颜色背景和圆角的设计,这时候可以使用安卓自带的dialog小巧快速的实现这种自定义的弹窗,安卓系统自带的系统dialog背景是直角白底的,我们需要先按ui设计图写好我们的xml布局


    image.png

    步骤一:按ui设计图画xml布局

    • 先画一个圆角shape文件shape_white_radius_10dp.xml来当做背景,在drawable文件夹加入
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <corners android:radius="10dp" />
        <solid android:color="#fffffff" />
    </shape>
    
    • 接着上我们的ui布局,my_dialog.xml
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/shape_white_radius_10dp"
        android:layout_margin="30dp"
        android:gravity="center">
    
        <LinearLayout
            android:id="@+id/ll_ad_diaglog"
            android:layout_width="260dp"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <TextView
                android:id="@+id/tv_msg_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:paddingLeft="10dp"
                android:paddingTop="12dp"
                android:paddingRight="10dp"
                android:paddingBottom="6dp"
                android:text="提示"
                android:textColor="#333333"
                android:textSize="18dp"
                android:textStyle="bold"
                android:visibility="visible" />
    
            <TextView
                android:id="@+id/tv_msg"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:padding="16dp"
                android:textColor="#333333"
                android:textSize="16dp"
                tools:text="欢迎你,我是小弹窗" />
    
            <View
                android:layout_width="match_parent"
                android:layout_height="0.5dp"
                android:background="#eeeeee" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:gravity="center_vertical">
    
                <Button
                    android:id="@+id/bt_cancel"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@android:color/transparent"
                    android:text="取消"
                    android:textColor="#999999"
                    android:textSize="16dp" />
    
                <View
                    android:id="@+id/view_line"
                    android:layout_width="0.5dp"
                    android:layout_height="match_parent"
                    android:background="#eeeeee" />
    
                <Button
                    android:id="@+id/bt_config"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@android:color/transparent"
                    android:text="确定"
                    android:textColor="#378bc4"
                    android:textSize="16dp" />
            </LinearLayout>
    
        </LinearLayout>
    
    </RelativeLayout>
    
    

    步骤二:自定义弹窗的样式,在themes.xml加入

    <style name="myDialog_Common" parent="Theme.AppCompat.Light.Dialog">
            <item name="android:windowBackground">@android:color/transparent</item>
            <item name="android:windowFrame">@null</item>
            <!-- 是否浮现在activity之上 ==当windowIsFloatin为true时会两边有空白-->
            <!--windowIsFloating为false会导致抖动-->
            <item name="android:windowIsFloating">true</item>
            <item name="android:windowIsTranslucent">true</item>
            <item name="android:backgroundDimEnabled">true</item>
            <item name="android:windowCloseOnTouchOutside">true</item>
            <item name="windowActionBar">false</item>
            <item name="windowNoTitle">true</item>
        </style>
    

    步骤三:代码实现部分

    public static void showDialog(Context mContext, String contentStr, boolean isCancleDialog) {
            View rootview = View.inflate(mContext, R.layout.my_dialog, null);
            TextView tvmsg = rootview.findViewById(R.id.tv_msg);
            Button btCancel = rootview.findViewById(R.id.bt_cancel);
            Button btConfig = rootview.findViewById(R.id.bt_config);
            tvmsg.setText(contentStr);
            tvmsg.setMovementMethod(ScrollingMovementMethod.getInstance());//内容滚动
    
            final AlertDialog dialog = new AlertDialog.Builder(mContext, R.style.FragDialog_Common).create();
            dialog.setCanceledOnTouchOutside(isCancleDialog);
            dialog.setCancelable(isCancleDialog);
            dialog.setView(rootview);
            dialog.show();
    
            btCancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (dialog != null)
                        dialog.dismiss();
                }
            });
            btConfig.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (dialog != null)
                        dialog.dismiss();
                }
            });
        }
    

    最终效果如下图预览

    image.png

    在实际开发中遇到一些问题:
    明明我在shape文件中设置好了粉色背景和20dp的圆角,始终真机显示不出这个效果。查询有说在代码中dialog获取到window设置窗口背景才能生效的,给他照办了,发现无效果。

     dialog.getWindow().setBackgroundDrawable();
     dialog.getWindow().setBackgroundDrawableResource();
     dialog.getWindow().setBackgroundBlurRadius();
    都设置一遍,依然无效果
    
    • 最后坑点是,我这是分模块开发的项目,自定义的dialog是在子模块里的,在主工程有一个shape_white_radius_10dp.xml文件同名的shape文件。在预览时,xml设置的背景文件引用的是子module的shape文件,在编译期引用的就是使用的主工程同名的shape文件。这导致我一直更改子module的shape文件样式却看不到我想要的效果。只要把我们dialog引用的背景文件修改为项目工程内唯一名字就好了
    • 此外发现不止是同名文件的引用,themes里的style设置只要是同名的,都会优先使用主工程已有的资源
    • 最后有遇到如果主工程和子工程拥有同名的layout布局文件,会导致莫名的R文件中id异常情况,一直提示你控件view的id错误,导致无法编译

    相关文章

      网友评论

          本文标题:Dialog自定义布局实现

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