Android中自定义dialog

在android中有时候我们不会满足于原生的控件,根据我们的需要,我们可能会需要自己的AlertDialog,例如QQ中的提示对话框如下:

qq中的删除好友dialog
—————————————————————————————
如何实现上面的效果呢?
先看我们自定义的效果如下:

自定义的dialog样式

先说一下大概步骤:
1. 自定义layout布局文件,这就是我们看到的dialog的整体外观;
2. 在res/values/styles.xml中创建我们自定义dialog需要的样式;
3. 创建自定义的dialog类继承dialog,完成相关代码即可;
4. 在需要使用的地方,使用自定义的dialog即可;

代码如下:
1.自定义布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="300dp"
    android:layout_height="wrap_content">

    <!--标题-->
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:gravity="center|bottom"
        android:text="删除好友"
        android:textSize="18sp"
        android:textStyle="bold"
        android:textColor="#000000"/>

    <!--内容-->
    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:gravity="center_vertical"
        android:text=""
        android:textColor="#000000"/>

    <!--水平分割线-->
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/colorLine"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <!--按钮1-->
        <Button
            android:id="@+id/btn_cancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="取消"
            android:textColor="@color/colorText"
            android:textSize="16sp"
            android:background="@drawable/shape_left_button"/>

        <!--两个按钮间的垂直分割线-->
        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="@color/colorLine"/>

        <!--按钮2-->
        <Button
            android:id="@+id/btn_confirm"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="删除"
            android:textColor="@color/colorText"
            android:textSize="16sp"
            android:background="@drawable/shape_right_button"/>
    </LinearLayout>
</LinearLayout>

关键点是我么要设计两个按钮的按压状态,因此需要自己定义selector文件。我们注意:左边按钮的左下角是圆角,我们此时定义为15px,故左边按钮如下定义:(右边按钮同理即可)

*shape_left_button.xml 文件:*
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--按压时-->
    <item android:state_pressed="true"  android:drawable="@drawable/shape_left"/>
    <!--默认状态下-->
    <item android:drawable="@drawable/shape_left_no"/>
</selector>


*shape_left.xml*
<?xml version="1.0" encoding="utf-8"?>
<!--按压状态-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:bottomLeftRadius="15px"/>
    <!--改变背景颜色-->
    <solid android:color="@color/colorLine"/>
</shape>


*shape_left_no.xml*
<?xml version="1.0" encoding="utf-8"?>
<!--未按压状态-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:bottomLeftRadius="15px"/>
</shape>

2.styles样式

 <style name="MyDialog" parent="android:style/Theme.Dialog">

        <!--dialog使用自己定义的背景-->
        <item name="android:windowBackground">@drawable/dialog</item>

        <!--dialog是否消除标题栏,默认是false,不消除的话,会占用一块空间-->
        <item name="android:windowNoTitle">true</item>

        <!--dialog是否浮动在activity上,默认是true,若为false话不会浮动在activity上-->
        <item name="android:windowIsFloating">true</item>

        <!--dialog的后面的activity是否显示灰色,默认是true-->
        <item name="android:backgroundDimEnabled">true</item>

    </style>

dialog的自定义背景如下:

*dialog.xml*
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <!--圆角为15px-->
    <corners android:radius="15px"/>
    <!--颜色为白色-->
    <solid android:color="@color/white"/>
</shape>

3.自定义MyDialog继承Dialog
主要思想是模仿原生的Dialog,使用静态内部类Builder来管理各种组件,并使用回调函数来进行事件的处理。(回调函数可以参考上一篇文章)

package space.wanhu.app_0518;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

/**
 * Created by Bingbing on 2016/5/18.
 * 自己定制dialog,按照原生dialog的基本方式
 */
public class MyDialog extends Dialog  {

    public MyDialog(Context context, int theme) {
        super(context, theme);

    }

    /**
     * dialog的助手类
     */
    public static class Builder{
        //获取需要自定义的组件
        private String tv_title,tv_content; //标题和内容
        private String btn_cancel,btn_confirm;//两种按钮的内容
        private DialogInterface.OnClickListener cancelListener,confirmListener;//回调接口对象
        private Context context;//上下文对象

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

        /**
         * 直接使用字符串来设置标题
         */
        public Builder setTitle(String title){
            this.tv_title = title;
            return this;
        }

        /**
         * 使用资源文件设置标题
         */
        public Builder setTitle(int id){
            this.tv_title = (String) context.getText(id);
            return this;
        }

        /**
         * 使用字符串设置dialog的提示内容
         */
        public Builder setContent(String content){
            this.tv_content = content;
            return this;
        }

        /**
         * 使用资源文件来设置dialog的内容
         */
        public Builder setContent(int id){
            this.tv_content = (String) context.getText(id);
            return this;
        }

        /**
         * 设置左边按钮的文字提示和回调函数
         */
        public Builder setCancelButton(String cancel,DialogInterface.OnClickListener cancelListener){
            this.btn_cancel = cancel;
            this.cancelListener = cancelListener;
            return this;
        }

        /**
         * 使用资源文件设置左边按钮的挑剔提示和回调函数
         */
        public Builder setCancelButton(int id,DialogInterface.OnClickListener cancelListener){
            this.btn_cancel = (String) context.getText(id);
            this.cancelListener = cancelListener;
            return this;
        }

        /**
         * 设置右边确定按钮的文字提示和回调函数
         */
        public Builder setConfirmButton(String confirm,DialogInterface.OnClickListener confirmListener){
            this.btn_confirm = confirm;
            this.confirmListener = confirmListener;
            return this;
        }

        /**
         * 使用资源文件来设置确定按钮的文字提示和回调函数
         */
        public Builder setConfirmButton(int id,DialogInterface.OnClickListener confirmListener){
            this.btn_confirm = (String) context.getText(id);
            this.confirmListener = confirmListener;
            return this;
        }

        /**
         * 在create方法中完成初始化和事件的注册
         */
        public MyDialog create(){

            //获取自定义的布局文件
            View viewRoot = LayoutInflater.from(context).inflate(R.layout.dialog_layout,null);

            //获取自定义dialog实例,并引入自定义的样式
            final MyDialog dialog = new MyDialog(context,R.style.MyDialog);

            //设置标题显示
            if(tv_title != null){
                ((TextView)viewRoot.findViewById(R.id.tv_title)).setText(tv_title);
            }

            //设置显示的内容
            if(tv_content != null){
                ((TextView)viewRoot.findViewById(R.id.tv_content)).setText(tv_content);
            }

            //设置左边按钮的文本和实现回调函数
            if(btn_cancel != null){
                Button button_cancel = (Button) viewRoot.findViewById(R.id.btn_cancel);
                button_cancel.setText(btn_cancel);
                if(cancelListener != null) {
                    button_cancel.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            cancelListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE);
                        }
                    });
                }
            }else {
                ((Button)viewRoot.findViewById(R.id.btn_cancel)).setVisibility(View.GONE);
            }

            //设置确定按钮的文本和实现回调函数
            if(btn_confirm != null){
                Button button_confirm = (Button) viewRoot.findViewById(R.id.btn_confirm);
                button_confirm.setText(btn_confirm);
                if(confirmListener != null){
                    button_confirm.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            confirmListener.onClick(dialog,DialogInterface.BUTTON_NEGATIVE);
                        }
                    });
                }

            }else {
                ((Button)viewRoot.findViewById(R.id.btn_confirm)).setVisibility(View.GONE);
            }

            dialog.setContentView(viewRoot);
            return dialog;
        }
    }
}

4. 使用自己定义的MyDialog,方法和原生的基本类似:

package space.wanhu.app_0518;

import android.content.Context;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private Context context;
    private MyDialog dialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;
        //启动原始的dialog
        findViewById(R.id.btn_ori).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                initOriDialog();
            }
        });
        //启动自定义dialog
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                initDialog();
            }
        });
    }

    /**
     * 初始化自定义的dialog
     */
    private void initDialog(){
        MyDialog.Builder builder = new MyDialog.Builder(context);
        builder.setTitle("删除");
        builder.setContent(R.string.tv_content);
        builder.setCancelButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.setConfirmButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(context,"您点击了确定!",Toast.LENGTH_SHORT).show();
            }
        });
        dialog = builder.create();
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }

    /**
     * 初始化原始的dialog
     */
    private void initOriDialog(){
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("删除好友");
        builder.setMessage("同时会将我从对方的列表中删除,且屏蔽对方的临时会话,不再接受此人\n" +
                "的消息同时会将我从对方的列表中删除.");
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(context,"您点击了取消",Toast.LENGTH_SHORT).show();
            }
        });
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(context,"您点击了确定",Toast.LENGTH_SHORT).show();
            }
        });
        builder.create().show();
    }
}

过程结束了,只要理解了基本的原理,我们就可以定义自己想要的Dialog了。

参考文档:
1. Android自定义对话框Dialog
2. 关于自定义Dialog的那些事
3. Android自定义Dialog

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值