安卓自定义dialog一篇文章搞定

在项目中我们经常会使用到自定义dialog,但是我们往往自定义了一个dialog,在show的时候,显示出来的效果却很奇葩,其显示出来的视图宽高,大小,里面控件大小等等属性都不对,甚至看起来效果惨不忍睹。 最近我也是被这问题搞的头大,在结合了网上一些文章案例,自己的实际操作后,终于总结出了怎么写好自定义dialog的方法,下面我们直接进入正题吧!

实现自定义dialog方式一

(1)先上布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#aaa"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Admin Password"
        android:textSize="24sp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#aaa"/>

    <EditText
        android:id="@+id/et_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:inputType="numberPassword"
        android:drawableLeft="@drawable/ic_hide_pwd"
        android:paddingLeft="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        />

    <CheckBox
        android:id="@+id/cb_forget"
        android:layout_width="wrap_content"
        android:layout_height="24dp"
        android:textSize="12sp"
        android:text="forget password"
        android:layout_marginLeft="10dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <Button
            android:id="@+id/button_ok"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:text="OK"
            android:textSize="12sp"
            android:layout_marginRight="10dp"
            />

        <Button
            android:id="@+id/button_cancel"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:text="cancel"
            android:textSize="12sp"
            android:layout_marginLeft="10dp"
            />

    </LinearLayout>

</LinearLayout>

预览效果:
在这里插入图片描述

(2)编写style中的dialog style
<style name="Dialog" parent="android:style/Theme.Dialog">
    <item name="android:background">#ffffff</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">true</item>
</style>

在(1)(2)步中,有个小细节可能很多人都注意不到,就是我没有在布局文件中写 background,但我在dialog 的style中,加了#ffffff 这个属性。

如果我把这个属性删掉,出来的弹窗的背景是透明的,就像下面这样:
在这里插入图片描述
此时的dialog style中样式为:
在这里插入图片描述
注意,没有了背景, 显示的是window的颜色,此时window为透明(因为android:windowBackground属性目前设的是透明)。 然后我将它换个颜色,那么window也会变颜色:
在这里插入图片描述
OK。 同理,如果我在布局文件中写了 background 。那么下面这两个属性忽略掉也可以(建议不要省略android:windowBackground属性,将它置为透明)。

(3)创建dialog
private Dialog dialog;

private void createDialog(){
    if (dialog == null){
         View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.custom_dialogview, null);
         dialog = new Dialog(MainActivity.this, R.style.Dialog);

         EditText editPwdText = view.findViewById(R.id.et_text);
        CheckBox checkBox = view.findViewById(R.id.cb_forget);
        Button ok = view.findViewById(R.id.button_ok);
        Button cancel = view.findViewById(R.id.button_cancel);

        checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    //InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD|InputType.TYPE_CLASS_TEXT
                    editPwdText.setInputType(InputType.TYPE_NUMBER_VARIATION_NORMAL | InputType.TYPE_CLASS_NUMBER);
                } else {
                    //InputType.TYPE_TEXT_VARIATION_PASSWORD|InputType.TYPE_CLASS_TEXT
                    editPwdText.setInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD | InputType.TYPE_CLASS_NUMBER);
                }
            }
        });

        ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        dialog.setContentView(view);//将显示的内容替换为我们的自定义view
        setLocation();//改变弹窗弹出位置,默认是在中央位置弹出
        dialog.show();
    } else {
        dialog.show();
    }

}

private void setLocation(){
    if (dialog != null){
        WindowManager.LayoutParams layoutParams = dialog.getWindow().getAttributes();
        //layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;//此处可修改宽度
        //layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;//此处可修改高度
        layoutParams.x = -100;
        layoutParams.y = -400;
        dialog.getWindow().setAttributes(layoutParams);
    }
}

//写了个按钮  开关dialog
findViewById(R.id.text_main).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (dialog == null || !dialog.isShowing()){
            createDialog();
        } else {
            dialog.dismiss();
        }
    }
});

这样我们自定义的弹窗效果就实现了。
弹出效果:
在这里插入图片描述

实现自定义dialog方式二

(1)创建CustomDialog类,继承自dialog
public class CustomDialog extends Dialog {

    public CustomDialog(@NonNull Context context) {
        super(context);
    }

    public CustomDialog(@NonNull Context context, int themeResId) {
        super(context, themeResId);
    }

    protected CustomDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    public static class Builder {

        private Context context;
        private View contentView;
        private String title;
        private String message;
        private int imageRes;
        //...

        public Builder(Context context){
            this.context = context;
        }

        public Builder setView(View layout){
            contentView = layout;
            return this;
        }
        
        public Builder setImageRes(int imageRes) {
            this.imageRes = imageRes;
            return this;
        }

        public Builder setTitle(String title){
            this.title = title;
            return this;
        }

        public CustomDialog build(){

            final CustomDialog dialog = new CustomDialog(context,R.style.Dialog);

            Button ok = contentView.findViewById(R.id.button_ok);
            Button cancel = contentView.findViewById(R.id.button_cancel);
            CheckBox checkBox = contentView.findViewById(R.id.cb_forget);
            EditText editPwdText = contentView.findViewById(R.id.et_text);

            checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked) {
                        //InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD|InputType.TYPE_CLASS_TEXT
                        editPwdText.setInputType(InputType.TYPE_NUMBER_VARIATION_NORMAL | InputType.TYPE_CLASS_NUMBER);
                    } else {
                        //InputType.TYPE_TEXT_VARIATION_PASSWORD|InputType.TYPE_CLASS_TEXT
                        editPwdText.setInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD | InputType.TYPE_CLASS_NUMBER);
                    }
                }
            });

            ok.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                }
            });

            cancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                }
            });

            dialog.setContentView(contentView);
            dialog.setLocation();
            return dialog;
        }
    }
    
    //更改弹窗位置的
    private void setLocation(){
        WindowManager.LayoutParams layoutParams = this.getWindow().getAttributes();
        layoutParams.x = 0;
        layoutParams.y = -300;
        this.getWindow().setAttributes(layoutParams);
    }

} 

通过builder模式,创建自定义dialog对象。 这里我只简单的写了下, 你可以通过title,message等是否有值,在build的时候选择是否显示相关视图。

(2) 创建dialog
private Dialog dialog2;
private void createDialog2(){
    if (dialog2 == null){
        View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.custom_dialogview, null);
        CustomDialog.Builder builder = new CustomDialog.Builder(MainActivity.this)
                .setView(view);
        dialog2 = builder.build();
        dialog2.show();
    } else {
        dialog2.show();
    }
}

findViewById(R.id.text_main2).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (dialog2 == null || !dialog2.isShowing()){
            createDialog2();
        } else {
            dialog2.dismiss();
        }
    }
});

效果如下:
在这里插入图片描述
好了,这就是本文的全部内容了。如果项目中有很多处用到自定义dialog,建议使用方式二,设计一个强大的dialog,然后就可以愉快的使用了。

END

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android自定义dialog是一种可以根据开发者的需求进行自定义的对话框。通过自定义dialog,开发者可以实现特定的界面设计和功能。根据引用,我们可以使用AlertDialog.Builder来创建一个普通的弹出框。而根据引用,我们可以通过简单的设置和技巧来实现Android自定义dialog。如果想要对话框具有自定义布局,可以创建一个布局文件,然后通过调用AlertDialog.Builder的setView()方法将其添加到对话框中。默认情况下,自定义布局会填充对话框窗口,但是仍然可以使用AlertDialog.Builder的其他方法来添加按钮和标题。此外,开发者还可以完全自定义一个Dialog,需要进行以下几步: 1. 定义一个style 2. 创建一个继承自Dialog的子类 3. 在子类中实现自定义布局和相关功能 4. 在应用中调用自定义dialog的实例来显示对话框。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [android自定义Dialog](https://blog.csdn.net/weixin_41796401/article/details/96636408)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Android自定义dialog简单实现方法](https://download.csdn.net/download/weixin_38736562/12800768)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值