Android UI设计系列之自定义Dialog实现各种风格的对话框效果(7)
作者:llew2011 发布时间:2023-11-18 14:26:37
虽然Android给我们提供了众多组件,但是使用起来都不是很方便,我们开发的APK都有自己的风格,如果使用了系统自带的组件,总是觉得和应用的主题不着边际并且看起来也不顺心,那我们就需要自定义了,为了方便大家对自定义组件的学习,我接下来准备了几遍有关自定义的Dialog的文章,希望对大家有帮助。
在开发APK中最常见的估计就数弹出对话框了,这种对话框按照按钮数量来分大致是三种:一个按钮,两个按钮,三个按钮。现在要讲的就是按照按钮数量分为以上三类吧(当然了可以有更多的按钮,只要你愿意)。
自定义Dialog对话大致可分为三步走吧:第一步就是重新定义Dialog的样式,第二部就是定义我们需要显示的布局文件,第三部就是设置事件 * 。
好了,还是老规矩,首先贴上工程目录:
在工程中我定义了一个基类BaseBean,这个类用来作为在整个工程项目中的基类,基类中定义一些公共的常用的属性,如有需要另外属性我们只需要继承基类就好了,所以我定义了DialogBean,它继承了BaseBean,因此拥有了BaseBean的所有功能。那我们先看看BaseBean中定义的都是啥吧:
public class BaseBean {
/**
* 标题
*/
String title;
/**
* 内容
*/
String content;
/**
* 获取标题
*
* @return 标题
*/
public String getTitle() {
return title;
}
/**
* 设置标题
*
* @param title
* 标题
*/
public void setTitle(String title) {
this.title = title;
}
/**
* 获取内容
*
* @return 内容
*/
public String getContent() {
return content;
}
/**
* 设置内容
*
* @param content
* 内容
*/
public void setContent(String content) {
this.content = content;
}
}
以上是基类中的内容,那接下来就看看Dialog中是怎么定义的吧:
public class DialogBean extends BaseBean {
/**
* 点击返回键是否可消失
*/
boolean cancelable;
/**
* 点击蒙皮是否可以消失
*/
boolean outCancelable;
/**
* 事件监听
*/
DialogClickListener listener;
/**
* 按钮类型【默认显示两个按钮】
*/
DialogButtonType buttonType = DialogButtonType.TwoButton;
/**
* 显示布局资源ID
*/
Integer layoutResID;
public DialogBean() {
}
/**
* 点击BACK键是否可以消失
*
* @return 【true:可消失】【false:不消失】
*/
public boolean isCancelable() {
return cancelable;
}
/**
* 设置点击BACK键是否可以消失
*
* @param cancelable
* 【true:可消失】【false:不消失】
*/
public void setCancelable(boolean cancelable) {
this.cancelable = cancelable;
}
/**
* 点击蒙皮是否可以消失
*
* @return 【true:可消失】【false:不消失】
*/
public boolean isOutCancelable() {
return outCancelable;
}
/**
* 设置点击蒙皮是否可以消失
*
* @param outCancelable
* 【true:可消失】【false:不消失】
*/
public void setOutCancelable(boolean outCancelable) {
this.outCancelable = outCancelable;
}
/**
* 获取事件 *
*
* @return 事件 *
*/
public DialogClickListener getListener() {
return listener;
}
/**
* 设置事件 *
*
* @param listener
* 事件 *
*/
public void setListener(DialogClickListener listener) {
this.listener = listener;
}
/**
* 获取按钮类型
*
* @return 按钮类型
*/
public DialogButtonType getButtonType() {
return buttonType;
}
/**
* 设置按钮类型
*
* @param buttonType
* 按钮类型
*/
public void setButtonType(DialogButtonType buttonType) {
this.buttonType = buttonType;
}
/**
* 获取要显示的布局ID
*
* @return 要显示的布局ID
*/
public Integer getLayoutResID() {
return layoutResID;
}
/**
* 设置要显示的布局ID
*
* @param layoutResID
* 要显示的布局ID
*/
public void setLayoutResID(Integer layoutResID) {
this.layoutResID = layoutResID;
}
/**
* 按钮类型
*
* @author llew
*/
public enum DialogButtonType {
/**
* 一个按钮
*/
OneButton,
/**
* 两个按钮
*/
TwoButton,
/**
* 三个按钮
*/
ThreeButton
}
/**
* 按钮点击 *
*
* @author llew
*
*/
public interface DialogClickListener {
/**
* 点击按钮
*
* @param buttonIndex
* 按钮下标【从0开始】
*/
public void onClick(int buttonIndex);
}
}
DialogBean中的代码注释的都很详细了,就不再多解释了,主要就是封装了对话框中常见的属性。接下来就看看定义的所需要的Dialog的样式吧:
<style name="theme_dialog_alert" parent="@android:style/Theme.Dialog">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
样式主要定义了该对话框没有标题,背景颜色是透明的,现在所需的样式定义完了,主角GlobleDialog该出场了,代码如下:
public class GlobleDialog extends Dialog implements View.OnClickListener {
private TextView titleTextView, contentTextView;
private Button leftButton, centerButton ,rightButton;
private DialogBean bean;
public GlobleDialog(Context context, int theme, DialogBean bean) {
super(context, theme);
this.bean = bean;
initWedgits();
}
/**
* 初始化各组件
*/
private void initWedgits() {
try {
setCancelable(bean.isCancelable());
setCanceledOnTouchOutside(bean.isOutCancelable());
View dialogView = getLayoutInflater().inflate(bean.getLayoutResID(), null);
titleTextView = (TextView) dialogView.findViewById(R.id.button_title);
contentTextView = (TextView) dialogView.findViewById(R.id.button_content);
titleTextView.setText(bean.getTitle());
contentTextView.setText(bean.getContent());
leftButton = (Button) dialogView.findViewById(R.id.button_left);
centerButton = (Button) dialogView.findViewById(R.id.button_center);
rightButton = (Button) dialogView.findViewById(R.id.button_right);
leftButton.setOnClickListener(this);
centerButton.setOnClickListener(this);
rightButton.setOnClickListener(this);
if(DialogButtonType.OneButton == bean.getButtonType()) {
leftButton.setVisibility(View.GONE);
rightButton.setVisibility(View.GONE);
} else if(DialogButtonType.TwoButton == bean.getButtonType()) {
centerButton.setVisibility(View.GONE);
}
setContentView(dialogView);
Window dialogWindow = getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.CENTER);
DisplayMetrics dm = new DisplayMetrics();
dialogWindow.getWindowManager().getDefaultDisplay().getMetrics(dm);
lp.width = dm.widthPixels - 20;
dialogWindow.setAttributes(lp);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onClick(View v) {
try {
switch (v.getId()) {
case R.id.button_left:
bean.getListener().onClick(0);
break;
case R.id.button_center:
bean.getListener().onClick(1);
break;
case R.id.button_right:
bean.getListener().onClick(2);
break;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
自定义的GlobleDialog的代码写完了,那就看看是如何使用的吧:
package com.llew.e.dialog.view.activity;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
import com.llew.e.dialog.R;
import com.llew.e.dialog.view.bean.DialogBean;
import com.llew.e.dialog.view.bean.DialogBean.DialogButtonType;
import com.llew.e.dialog.view.bean.DialogBean.DialogClickListener;
import com.llew.e.dialog.view.wedgit.GlobleDialog;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
private Dialog dialog;
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView) findViewById(R.id.textview);
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
DialogBean dialogBean = new DialogBean();
dialogBean.setCancelable(true);
dialogBean.setOutCancelable(true);
dialogBean.setTitle("小练习");
dialogBean.setContent("在这里输入提示信息");
dialogBean.setButtonType(DialogButtonType.TwoButton);
dialogBean.setLayoutResID(R.layout.dialog_common);
dialogBean.setListener(new DialogClickListener() {
@Override
public void onClick(int buttonIndex) {
switch (buttonIndex) {
case 0:
Toast.makeText(MainActivity.this, "点击了播放", Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(MainActivity.this, "点击了暂停", Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(MainActivity.this, "点击了停止", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
});
createDialog(dialogBean);
}
});
}
public void createDialog(DialogBean bean) {
if(null == dialog) {
dialog = new GlobleDialog(MainActivity.this, R.style.theme_dialog_alert, bean);
}
dialog.show();
}
}
代码实在是没有什么好解释的,我相信你一看就会,那看看运行效果吧:
界面看上去有点丑,大家可以自己修改颜色值或者使用图片代替。


猜你喜欢
- Android中获取资源 id 及资源 id 的动态获取我们平时获取资源是通过 findViewById 方法进行的,比如我们常
- 本文实例讲述了Android编程自定义组件。分享给大家供大家参考,具体如下:在Android中,所有的UI界面都是由View类和ViewGr
- 1、properties文件显示乱码问题原因是因为properties默认使用ASCII码,就算在文件中填写了中文,再打开后依然会转换成AS
- java @Value("${}")获取不到配置文件中值1、property.yml配置spring: ma
- 在java中读取读取文件,经常因为路径的问题找不到,此文用于记录如何定位文件的简单方法。本基于springboot做的测试,主要是构建工程方
- 为了重用Fragment UI 组件,在设计中你应该通过定义每一个fragemnt自己的layout和行为,让fragment的自包含和模块
- 1、spring-cloud-starter-alibaba-nacos-discovery 这里依赖报红,无法引入,或显示无法找到,更换版
- 案例sql脚本DROP DATABASE IF EXISTS `javacode2018`;CREATE DATABASE `javacod
- 常见尺寸单位Android开发中的常用尺寸单位有如下几种:dp (dip)pxptinchsp算不知道确切含义,相信对于以上这几种尺寸单位大
- WPF 窗体设置亚克力效果框架使用大于等于.NET40。Visual Studio 2022。项目使用 MIT 开源许可
- 获得redis所有的key-value运行结果:redis配置文件需要序列化@Bean public RedisT
- 前言最近在工作中遇到了这么一个需求:如何实现 Android 应用前后台切换的监听?下面来一起看看详细的介绍:iOS 内边是可以实现的,Ap
- 本文以实例形式讲述了Android Touch事件分发过程,对于深入理解与掌握Android程序设计有很大的帮助作用。具体分析如下:首先,从
- spring-retry模块支持方法和类、接口、枚举级别的重试方式很简单,引入pom包<parent> <gr
- 安装JDK 向导进行相关参数设置。如图: 正在安装程序的相关功能,如图: 选择安装的路径,可以自定义,也可以默认路径。如图: 成功安装之
- 目录一、连接查询:1、多对一:2、一对多:3、多对多:二、嵌套查询:1、多对一:2、一对多:首先在mysql中确立表:#表一:地址国家表CR
- 项目里头需要做一个判断用户输入的号码是否是正确的手机号码,正确的手机号码应该是11位的,这里我们需要用一个正则表达式来进行判断,
- HashMap的keySet()方法比较简单,作用是获取HashMap中的key的集合。虽然这个方法十分简单,似乎没有什么可供分析的,但真正
- 本文实例为大家分享了Android使用Gridview单行横向滚动显示的具体代码,供大家参考,具体内容如下要想实现滚动显示,layout布局
- ES 简介Elasticsearch 是一个基于 Lucene 实现的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 REST