软件编程
位置:首页>> 软件编程>> Android编程>> Android 自定义dialog的实现代码

Android 自定义dialog的实现代码

作者:lqh  发布时间:2023-12-05 08:17:29 

标签:Android,自定义dialog

Android 自定义dialog的实现代码

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

要点:

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

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

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

Android 自定义dialog的实现代码

Android 自定义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();
 }

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

0
投稿

猜你喜欢

  • 进阶JavaSE-三大接口:Comparator、Comparable和Cloneable。Comparable和Comparator这两个
  • 首先说明这是我一个不熟悉idea和SSM框架的新手小白遇到的坑,适合用idea搭建SSM框架的小伙伴看一看,老鸟就不用看了。以下为详细步骤(
  • 前言这周接到一个需求,需要在应用从后台切换到前台时,展示我们的广告。展示页面其实可以复用以前的开屏广告页,唯一的问题就是如何监听应用从后台切
  • IOC创建对象的方式一、 使用无参构造创建对象(默认方式)创建实体类注意:属性必须要有set方法,来完成注入public class Use
  • 前言今天来做个打方块的小游戏,继续熟悉kotlin的语法,更多关于kotlin的语法大家可以参考这篇文章:https://www.jb51.
  • 现在项目中有使用到音视频相关技术,在参考了网上各种大牛的资料及根据自己项目实际情况(兼容安卓6.0以上版本动态权限管理等),把声音录制及播放
  • 本篇文章是直接下载最新的APK安装的方法,并不是增量下载该APk。想要实现一个android应用,自动更新下载APK软件的方法,我采取的是以
  • Echarts图表数据一般都是从后台数据库实时取数据的 传输数据大多采用JSON数据格式 本文通过springmvc来拦截数据请求 完成数据
  • 背景在研究规则引擎时,如果规则以文件的形式存储,那么就需要监听指定的目录或文件来感知规则是否变化,进而进行加载。当然,在其他业务场景下,比如
  • 本文实例为大家分享了springboot实现基于aop的切面日志的具体代码,供大家参考,具体内容如下通过aop的切面方式实现日志通切面拦截所
  • 在谈 JVM 内存区域划分之前,我们先来看一下 Java 程序的具体执行过程,我画了一幅图。Java 源代码文件经过编译器编译后生成字节码文
  • 什么是依赖注入首先,某个类的成员变量称为依赖,如若此变量想要实例化引用其类的方法,可以通过构造函数传参或者通过某个方法获取对象,此等通过外部
  • 一、NIO基本简介NIO (New lO)也有人称之为java non-blocking lO是从Java 1.4版本开始引入的一个新的IO
  • 前言:最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap、BitmapFactor
  • springboot读取配置文件到静态工具类通常我们读取配置文件可以用@Value注解和@Configuration,@Configurat
  • C#中List可谓是使用最广泛的一种数据类型了,使用他来规范数据时,往往会涉及到对数据的处理操作,相关处理数据方法也非常丰富,本文将简单介绍
  • 没人会喜欢空指针异常!有什么方法可以避免它们吗?或许吧。。本文将讨论到以下几种技术1.Optional类型(Java 8中新引入的)2.Ob
  • 一、链表的概念和结构1.1 链表的概念简单来说链表是物理上不一定连续,但是逻辑上一定连续的一种数据结构1.2 链表的分类实际中链表的结构非常
  • 冒泡排序:就是按索引逐次比较相邻的两个元素,如果大于/小于(取决于需要升序排还是降序排),则置换,否则不做改变这样一轮下来,比较了n-1次,
  • 概述SpringMVC的处理器 * 类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦
手机版 软件编程 asp之家 www.aspxhome.com