Android 自定义dialog的实现代码

发布时间 - 2026-01-11 00:16:24    点击率:

Android 自定义dialog的实现代码

搜索相关关键字网上一大堆实现,但是看完总觉得缺胳膊少腿,绕了不少弯路,终于弄好了自定义dialog。把自己整合的完整代码发上来。

要点:

1、设置自定义dialog的布局文件my_dialog.xml
2、设置一份自定义的样式文件styles_wx.xml,该文件用于覆盖Android的默认主题样式,如黑色边框等。
3、Java代码继承Dialog实现自定义类MyDialog,实现自定义布局,还有设置窗口的大小、位置等。

(网上文章要么少介绍第2点,要么是使用AlterDialog直接实现效果)

先看下效果,模仿微信风格的dialog:

允许添加子view到弹出dialog,如:

代码。

Part1.styles_wx.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources xmlns:android="http://schemas.android.com/apk/res/android"> 
 
  <!-- 微信弹窗 --> 
  <style name="wx_dialog" parent="@android:style/Theme.Dialog"> 
    <item name="android:windowFrame">@null</item> <!-- 边框 --> 
    <item name="android:windowIsFloating">true</item> <!-- 是否浮现在activity之上 --> 
    <item name="android:windowIsTranslucent">false</item> <!-- 半透明 --> 
    <item name="android:windowNoTitle">true</item> <!-- 无标题 --> 
    <item name="android:windowBackground">@drawable/transparent</item> <!-- 自己想要的背景 --> 
    <item name="android:backgroundDimEnabled">true</item> <!-- 背景内容模糊 --> 
  </style> 
 
</resources> 

注意,此处:

<item name="android:windowBackground">@drawable/transparent</item> 

这是设置对话框弹出背景,尝试设置@null,仍然是黑色背景,在使用半透明图片时会受其影响。

所以,可以在这里指定你想要的背景图片或者颜色。

我为了灵活性,我设置该属性为名为"transparent"的图片,这是一张1*1的透明图片。这样背景完全透明,真正使用的背景在my_dialog.xml里定义

Part2.my_dialog.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:background="@drawable/frame_white" 
  android:orientation="vertical" 
  android:padding="15dp" > 
 
  <TextView 
    android:id="@+id/tvTitle" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/systitle" 
    android:textSize="18sp" /> 
 
 
  <!-- 分隔符用 --> 
 
  <TextView 
    android:id="@+id/tvSeparator" 
    style="@style/TextViewAsSeparator" 
    android:layout_marginBottom="5dp" 
    android:layout_marginTop="5dp" /> 
 
  <TextView 
    android:id="@+id/tvText" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/sysText" 
    android:textSize="18sp" /> 
 
  <!-- 该RelativeLayout作为子视图容器 --> 
 
  <RelativeLayout 
    android:id="@+id/rlContent" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" > 
  </RelativeLayout> 
 
  <RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_marginTop="10dp" 
    android:orientation="horizontal" > 
 
    <TextView 
      android:id="@+id/tvButton2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentRight="true" 
      android:layout_marginLeft="10dp" 
      android:background="@drawable/selector_text_button" 
      android:clickable="true" 
      android:paddingBottom="5dp" 
      android:paddingLeft="15dp" 
      android:paddingRight="15dp" 
      android:paddingTop="5dp" 
      android:text="@string/ok" 
      android:textColor="@color/wx_text_link" 
      android:textSize="14sp" 
      android:visibility="visible" /> 
 
    <TextView 
      android:id="@+id/tvButton1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignWithParentIfMissing="true" 
      android:layout_marginLeft="10dp" 
      android:layout_toLeftOf="@id/tvButton2" 
      android:background="@drawable/selector_text_button" 
      android:clickable="true" 
      android:paddingBottom="5dp" 
      android:paddingLeft="15dp" 
      android:paddingRight="15dp" 
      android:paddingTop="5dp" 
      android:text="@string/cancel" 
      android:textColor="@color/wx_text_link" 
      android:textSize="14sp" /> 
  </RelativeLayout> 
 
</LinearLayout> 

Part3.MyDialog.java

package com.kwws; 
 
import android.app.Dialog; 
import android.content.Context; 
import android.os.Bundle; 
import android.util.DisplayMetrics; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.Window; 
import android.view.WindowManager; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 
 
import com.navigator.R; 
 
/** 
 * 自定义对话框 
 * 
 * @author Kangwei 
 * 
 */ 
public class MyDialog extends Dialog { 
 
  /* 属性 */ 
 
  // 数据 
  String title = "title"; 
  String text = "text"; 
  String cancelButtonText = "cancel"; 
  String okButtonText = "ok"; 
  int okColor = -1; 
  int cancelColor = -1; 
 
  // UI 
  Context mContent; 
  TextView tvTitle; 
  TextView tvSeparator; 
  TextView tvText; 
  TextView tvBtn1; 
  TextView tvBtn2; 
  RelativeLayout childViewWrapper;// 子组件容器 
 
  /** 
   * 设置对话框样式,设置null则不显示 
   * 
   * @param context 
   *      上下文 
   * @param title 
   *      标题 
   * @param text 
   *      文本 
   * @param cancelButtonText 
   *      取消按钮文本 
   * @param okButtonText 
   *      确认按钮文本 
   */ 
  public MyDialog(Context context, String title, String text, 
      String cancelButtonText, String okButtonText) { 
    super(context, R.style.wx_dialog);// 样式定义,该样式去除android默认的黑色背景边框等。 
    this.mContent = context; 
    setDialogStyle(title, text, cancelButtonText, okButtonText); 
  } 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
    LayoutInflater layout = LayoutInflater.from(mContent); 
    View view = layout.inflate(R.layout.my_dialog, null); 
    setContentView(view); 
    findView(); 
    initView(); 
    initViewEvent(); 
  } 
 
  private void setDialogStyle(String title, String text, 
      String cancelButtonText, String okButtonText) { 
    this.title = title; 
    this.text = text; 
    this.cancelButtonText = cancelButtonText; 
    this.okButtonText = okButtonText; 
  } 
 
  private void findView() { 
    tvTitle = (TextView) findViewById(R.id.tvTitle); 
    tvSeparator = (TextView) findViewById(R.id.tvSeparator); 
    tvText = (TextView) findViewById(R.id.tvText); 
    tvBtn1 = (TextView) findViewById(R.id.tvButton1); 
    tvBtn2 = (TextView) findViewById(R.id.tvButton2); 
    childViewWrapper = (RelativeLayout) findViewById(R.id.rlContent); 
  } 
 
  private void initView() { 
    if (title == null) { 
      tvTitle.setVisibility(View.GONE); 
      tvSeparator.setVisibility(View.GONE); 
    } else { 
      tvTitle.setVisibility(View.VISIBLE); 
      tvSeparator.setVisibility(View.VISIBLE); 
      tvTitle.setText(title); 
    } 
    if (text == null) { 
      tvText.setVisibility(View.GONE); 
    } else { 
      tvText.setVisibility(View.VISIBLE); 
      tvText.setText(text); 
    } 
    if (cancelButtonText == null) { 
      tvBtn1.setVisibility(View.GONE); 
    } else { 
      tvBtn1.setVisibility(View.VISIBLE); 
      tvBtn1.setText(cancelButtonText); 
      if (cancelColor != -1) { 
        tvBtn1.setTextColor(cancelColor); 
      } 
    } 
    if (okButtonText == null) { 
      tvBtn2.setVisibility(View.GONE); 
    } else { 
      tvBtn2.setVisibility(View.VISIBLE); 
      tvBtn2.setText(okButtonText); 
      if (okColor != -1) { 
        tvBtn2.setTextColor(okColor); 
      } 
    } 
 
    if (childViewWrapper != null && childView != null) { 
      childViewWrapper.addView(childView); 
    } 
 
    // 设置对话框大小 
    Window dialogWindow = getWindow(); 
    WindowManager.LayoutParams lp = dialogWindow.getAttributes(); 
    DisplayMetrics d = mContent.getResources().getDisplayMetrics(); 
    // 获取屏幕宽、高用 
    lp.width = (int) (d.widthPixels * 0.8); // 高度设置为屏幕的0.8 
    dialogWindow.setAttributes(lp); 
  } 
 
  private void initViewEvent() { 
    View.OnClickListener listener = new View.OnClickListener() { 
 
      @Override 
      public void onClick(View v) { 
        // TODO Auto-generated method stub 
        switch (v.getId()) { 
        case R.id.tvButton1: 
          if (mListener != null) { 
            mListener.onCancelButtonClick(MyDialog.this, v); 
          } 
          break; 
        case R.id.tvButton2: 
          if (mListener != null) { 
            mListener.onOKButtonClick(MyDialog.this, v); 
          } 
          break; 
        default: 
          break; 
        } 
      } 
    }; 
    tvBtn1.setOnClickListener(listener); 
    tvBtn2.setOnClickListener(listener); 
  } 
 
  public interface OnDialogButtonClickListener { 
    void onCancelButtonClick(MyDialog dialog, View view); 
 
    void onOKButtonClick(MyDialog dialog, View view); 
  } 
 
  private OnDialogButtonClickListener mListener; 
 
  /** 
   * 对话框按钮监听 
   * 
   * @param listener 
   */ 
  public void setOnDialogButtonClickListener( 
      OnDialogButtonClickListener listener) { 
    this.mListener = listener; 
  } 
 
  /** 
   * 确定按钮文本颜色 
   * 
   * @param color 
   */ 
  public void setOKButtonTextColor(int color) { 
    this.okColor = color; 
  } 
 
  /** 
   * 取消按钮文本颜色 
   * 
   * @param color 
   */ 
  public void setCancelButtonTextColor(int color) { 
    this.cancelColor = color; 
  } 
 
  View childView; 
 
  /** 
   * 在对话框显示自定义视图 
   */ 
  public void setChildView(View view) { 
    childView = view; 
  } 
} 

Part4.使用

// 退出提示框 
public void exitDialog() { 
 
  MyDialog dialog = new MyDialog(this, "提示", "确认退出?", "取消", "退出"); 
  dialog.setOKButtonTextColor(getResources().getColor(R.color.red)); 
  dialog.setOnDialogButtonClickListener(new OnDialogButtonClickListener() { 
 
    @Override 
    public void onOKButtonClick(MyDialog dialog, View view) { 
      finish(); 
    } 
 
    @Override 
    public void onCancelButtonClick(MyDialog dialog, View view) { 
      dialog.dismiss(); 
    } 
  }); 
  dialog.show(); 
} 

/* 
   * 显示配置对话框 
   */ 
  private void showConfigDialog() { 
    // 读取参数 
    final SharedPreferencesHelper helper = new SharedPreferencesHelper( 
        this, "config"); 
    final String ip = helper.getValue("serverip"); 
    final String port = helper.getValue("serverport"); 
 
    // 配置界面 输入IP和端口的简单界面,这里就不附xml了 
    View view = getLayoutInflater().inflate(R.layout.dialog_config, null); 
    final EditText etIP = (EditText) view.findViewById(R.id.etIP); 
    final EditText etPort = (EditText) view.findViewById(R.id.etPort); 
    etIP.setText(ip != null ? ip : Ksoap2Helper.getServerIP()); 
    etPort.setText(port != null ? port : String.valueOf(Ksoap2Helper 
        .getServerPort())); 
 
    // 配置对话框 
    MyDialog dialog = new MyDialog(this, "参数配置", null, "取消", "确定"); 
    // 添加配置界面到对话框 
    dialog.setChildView(view); 
    // 按钮监听 
    dialog.setOnDialogButtonClickListener(new OnDialogButtonClickListener() { 
 
      @Override 
      public void onOKButtonClick(MyDialog dialog, View view) { 
        // 保存配置 
        String newIP = etIP.getText().toString(); 
        String newPort = etPort.getText().toString(); 
 
        if (true) { 
          helper.putValue("serverip", newIP); 
          Ksoap2Helper.setServerIP(newIP); 
        } 
        if (true) { 
          helper.putValue("serverport", newPort); 
          Ksoap2Helper.setServerPort(Integer.valueOf(newPort)); 
        } 
        dialog.dismiss(); 
      } 
 
      @Override 
      public void onCancelButtonClick(MyDialog dialog, View view) { 
        dialog.dismiss(); 
      } 
    }); 
    dialog.show(); 
  } 

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# Android  # 自定义dialog  # 自定义dialog详解及实例  # android几种不同对话框的实现方式  # Android自定义dialog简单实现方法  # 7种形式的Android Dialog使用实例  # Android自定义对话框Dialog的简单实现  # 8种android 对话框(Dialog)使用方法详解  # Android的八种对话框的实现代码示例  # Android 多种dialog的实现方法(推荐)  # 自定义  # 对话框  # 这是  # 弹出  # 在这里  # 就不  # 网上  # 希望能  # 看完  # 仍然是  # 总觉得  # 谢谢大家  # 弄好  # 设置为  # 该文件  # 先看  # 你想要  # 发上来  # 绕了  # 受其 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?  悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤  详解Android——蓝牙技术 带你实现终端间数据传输  如何在万网自助建站中设置域名及备案?  如何快速辨别茅台真假?关键步骤解析  如何在Windows环境下新建FTP站点并设置权限?  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  Bootstrap整体框架之CSS12栅格系统  香港服务器租用费用高吗?如何避免常见误区?  如何彻底删除建站之星生成的Banner?  如何为不同团队 ID 动态生成多个独立按钮  php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  如何用JavaScript实现文本编辑器_光标和选区怎么处理  如何用AWS免费套餐快速搭建高效网站?  Laravel如何使用Telescope进行调试?(安装和使用教程)  成都网站制作公司哪家好,四川省职工服务网是做什么用?  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法  Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询  如何用免费手机建站系统零基础打造专业网站?  想要更高端的建设网站,这些原则一定要坚持!  HTML5空格和nbsp有啥关系_nbsp的作用及使用场景【说明】  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  新三国志曹操传主线渭水交兵攻略  昵图网官方站入口 昵图网素材图库官网入口  Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解  LinuxCD持续部署教程_自动发布与回滚机制  瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  Laravel如何集成Inertia.js与Vue/React?(安装配置)  WordPress 子目录安装中正确处理脚本路径的完整指南  如何登录建站主机?访问步骤全解析  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  简历没回改:利用AI润色让你的文字更专业  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  如何利用DOS批处理实现定时关机操作详解  如何在腾讯云免费申请建站?  node.js报错:Cannot find module &#39;ejs&#39;的解决办法  如何为不同团队 ID 动态生成多个非值班状态按钮  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)  在线教育网站制作平台,山西立德教育官网?  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  如何在阿里云虚拟服务器快速搭建网站?  HTML 中动态设置元素 name 属性的正确语法详解  Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程  Android实现代码画虚线边框背景效果  活动邀请函制作网站有哪些,活动邀请函文案?