今天给大家讲讲有关自定义对话框的相关内容,前面两篇都在在利用系统提供的函数来实现对话框,但局限性太大,当我们想自己定义视图的时候,就不能利用系统函数了,就需要我们这里的自定义对话框了,有关自定义对话框的东东,以前有写过一篇《android之Dialog相关》,写的不好,今天给大家重新写一篇

一、雏形构建
先给大家看下这小节的效果图:
自定义一个对话框,内容是四个ImageView横排;
1、Dialog布局
根据上图的对话框样式,我们看一下Dialog的布局定义(custom_dialog.xml)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/log_in_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:layout_width="match_parent" android:layout_height="100dip" android:src="@drawable/animal1" android:clickable="true" android:layout_weight="1"/> <ImageView android:layout_width="match_parent" android:layout_height="100dip" android:src="@drawable/animal2" android:clickable="true" android:layout_weight="1"/> <ImageView android:layout_width="match_parent" android:layout_height="100dip" android:src="@drawable/animal3" android:clickable="true" android:layout_weight="1"/> <ImageView android:layout_width="match_parent" android:layout_height="100dip" android:src="@drawable/animal4" android:clickable="true" android:layout_weight="1"/> </LinearLayout>
2、从Dialog派生对话框类
有关构造函数:
有三种构造函数,现在我这里使用重写了两个,这里只需要使用第一个,即传进去context即可;
有关OnCreate()
在OnCreate()时,利用LayoutInflater获取我们对话框的View,然后利用SetContentView指定为我们CustomDialog类的布局。
public class CustomDialog extends Dialog {
Context mContext;
public CustomDialog (Context context){
super(context);
mContext = context;
}
public CustomDialog(Context context, int theme) {
super(context, theme);
mContext = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog, null);
this.setContentView(layout);
}
}
3、主函数(MainActivity)
在MainActivity中,我们写一个Button,当用户点击的时候弹出我们自定义的对话框实例
MainActivity的布局:(activity_main.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/btn_pop_dialog" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="弹出对话框"/> </RelativeLayout>
代码中的处理:(MainActivity.java)
在点击Btn的时候,创建CustomDialog类的实例,并显示
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button)findViewById(R.id.btn_pop_dialog);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomDialog dialog = new CustomDialog(MainActivity.this);
dialog.show();
}
});
}
}
这部分源码在文章最底部给出;
二、定义对话框样式
这里再回头看看上面弹出的对话框:
在布局中,我们只定义了一个水平布局,里面放了四个ImageView,即那四个小动物,那上面那一坨是哪来的呢(我用红笔圈出来的那块)?能不能去掉?这节,我们就说说有关样式的问题。
第一个问题,只所有上面那一坨,是因为我们没有指定对话框样式,系统会使用默认样式,那一坨就是标题栏。
要去掉的话,我们就需要自定义样式。
1、自定义样式
我们的样式是写在res/values文件夹下的style.xml文件中的,如图,如果没有style.xml,自已新建一个,位置如图:
这里定义的样式代码是这样的:
<style name="dialog" parent="android:Theme.Dialog"> <item name="android:windowFrame">@null</item> <item name="android:windowIsFloating">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowNoTitle">true</item> </style>
先对这几个参数解释一下:
Android:windowFrame:界面对应的前景图片;
android:windowIsFloating:表示浮在屏幕上的,如果在这里使用了,整个layout就会在 屏幕中心,相当于浮在屏幕上,所以这个只适用于dialog
android:windowContentOverlay:表示标题栏的阴影部分的样式,使用图片或者颜色
android:windowNoTitle:标题栏是否隐藏,这就是我们上面显示的标题栏
有关样式的内容很多很杂,这里有篇文章大家可以参考下《Andriod中Style/Theme原理以及Activity界面文件选取过程浅析》,有机会给大家总结一下有关样式和主题的内容,到时再细讲,这里不是本篇的重点,就不再细讲了。
2、使用样式
方法一:
这里有两种方法来使用样式,主要还是利用构造函数,还记得我们上面说过,对话框的两个构造函数:
public class CustomDialog extends Dialog {
Context mContext;
public CustomDialog(Context context) {
super(context);
mContext = context;
}
public CustomDialog(Context context, int theme) {
super(context, theme);
mContext = context;
}
…………
}
看第二个就是我们的Theme样式,所以第一种使用样式的方法是在构造时直接将样式传进来,如果这样使用,那我们在构造对话框时应该是这样的“:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button)findViewById(R.id.btn_pop_dialog);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomDialog dialog = new CustomDialog(MainActivity.this,R.style.dialog);
dialog.show();
}
});
}
}
即在新建CustomDialog实例时,第二个参数传进来我们上面定义的样式。
方法二:
第二种方法,就是我们在构造时,不让别人传样式,只让传进来Context,但在内部,我们利用Super(context,theme)来指定样式,代码如下:
public class CustomDialog extends Dialog {
Context mContext;
public CustomDialog(Context context) {
super(context,R.style.dialog);
mContext = context;
}
…………
}
这种情况一般用在我们封装代码时,不让其它人在外部改变我们的样式时使用的。
无论使用哪种方法,我们就已经指定我我们的对话框样式,现在的效果是这样的:
看到了没,上面的标题栏没了,下面再看看有关参数传递的问题
三、参数传递
这里涉及到两个问题:传进去和传出来;
传进去:下面有两个按钮,当用户点第一个按钮时,在对话框中显示"From btn 1",如果用户点击第二个按钮,在对话框中显示“From btn 2”
传出来:这四个图片都是可以点击的,当用户点击任何一个图片,把它的ID传出来,并设置到我们的MainActivity中;
这里为了好理解,更改了对话框的布局,将水平布局改成了垂直布局。并且在MainActiviy下面加了一个ImageView.
1、传进去
往对话框里传参数,一般就是利用构造函数来完成的,很简单,即在对话框的构造函数上加上我们自己想要传的参数,这里我们需要额外传一个字符串,来表示从哪个BTN来的。
所以对话框的构造函数就变成了这样:
public class CustomDialog extends Dialog{
private Context mContext;
private String mStr;
public CustomDialog(Context context, String str, int theme) {
super(context, theme);
mContext = context;
mStr = str;
}
…………
}
在使用的时候,也很简单:
Button btn2 = (Button)findViewById(R.id.btn_pop_dialog_2);
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomDialog dialog = new CustomDialog(MainActivity.this,"From btn 2",R.style.dialog);
dialog.show();
}
});
直接利用构造函数传参即可
2、传出来
利用构造函数传参数大家都知道,但要怎么把用户的操作信息传出来就不是那么简单了,这里就要利用回调来实现了!
回调函数的使用主要依照下面这些步骤:
在对话框中:
public class CustomDialog extends Dialog {
// 利用interface来构造一个回调函数
public interface ICustomDialogEventListener {
public void customDialogEvent(int valueYouWantToSendBackToTheActivity);
}
private ICustomDialogEventListener onCustomDialogEventListener;
// 在构造函数中,设置进去回调函数
public CustomDialog(Context context,
ICustomDialogEventListener onCustomDialogEventListener) {
super(context);
this.onCustomDialogEventListener = onCustomDialogEventListener;
}
//当你想把值传回去的时候,调用回调函数将值设置进去
@Override
public void onCreate(Bundle savedInstanceState)
{
Button btnOk = (Button) findViewById(R.id.customDialogButton);
btnOk.setOnClickListener( new Button.OnClickListener()
{
public void onClick(View v) {
onCustomDialogEventListener.customDialogEvent(valueYouWantToSendBackToTheActivity);
dismiss();
}
});
}
}
在构造对话框时:
final CustomDialog dialog = new CustomDialog(this, new ICustomDialogEventListener() {
public void customDialogEvent(int value) {
//在这里就获取到了从对话框传回来的值
}
});
大致使用流程就是这样的,下面就把我们上面的效果利用回调函数实现出来;
首先在对话框中新建一个回调函数(接口),并且在对话框的构造方法中把回调函数传进来:
public class CustomDialog extends Dialog implements View.OnClickListener {
//增加一个回调函数,用以从外部接收返回值
public interface ICustomDialogEventListener {
public void customDialogEvent(int id);
}
private ICustomDialogEventListener mCustomDialogEventListener;
private Context mContext;
private String mStr;
//把回调函数传进来
public CustomDialog(Context context, String str, ICustomDialogEventListener listener, int theme) {
super(context, theme);
mContext = context;
mStr = str;
mCustomDialogEventListener = listener;
}
…………
}
然后在OnCreate() 函数中设定ImageView的点击事件,我们将CustomDialog类继承View.OnClickListener接口,对点击事件统一处理:
private void bindImageClickEvent(View layout){
ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1);
ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2);
ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3);
ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4);
img1.setOnClickListener(this);
img2.setOnClickListener(this);
img3.setOnClickListener(this);
img4.setOnClickListener(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog, null);
TextView tv = (TextView)layout.findViewById(R.id.dialog_text);
tv.setText(mStr);
bindImageClickEvent(layout);//绑定ImageView点击事件
this.setContentView(layout);
}
在OnCreate()中,首先将传进来的String字符串设置到对话框的TextView中;然后绑定各个ImageView的点击事件
然后 就是在OnClick中的处理:
主要是根据用户当前点击的ImageView的ID,把这个ImageView所用的图片的DrawableID返回给MainActivity,代码如下:
public void onClick(View view) {
int id = view.getId();
int drawableID = -1;
switch (id){
case R.id.dialog_image1:
drawableID = R.drawable.animal1;
break;
case R.id.dialog_image2:
drawableID = R.drawable.animal2;
break;
case R.id.dialog_image3:
drawableID = R.drawable.animal3;
break;
case R.id.dialog_image4:
drawableID = R.drawable.animal4;
break;
}
if (drawableID != -1) {
mCustomDialogEventListener.customDialogEvent(drawableID);
}
dismiss();
}
这样就把对话框的构造过程讲完了,完整的对话框代码是这样的:
public class CustomDialog extends Dialog implements View.OnClickListener{
//增加一个回调函数,用以从外部接收返回值
public interface ICustomDialogEventListener {
public void customDialogEvent(int id);
}
private ICustomDialogEventListener mCustomDialogEventListener;
private Context mContext;
private String mStr;
public CustomDialog(Context context) {
super(context);
mContext = context;
}
public CustomDialog(Context context, String str,ICustomDialogEventListener listener,int theme) {
super(context, theme);
mContext = context;
mStr = str;
mCustomDialogEventListener = listener;
}
private void bindImageClickEvent(View layout){
ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1);
ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2);
ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3);
ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4);
img1.setOnClickListener(this);
img2.setOnClickListener(this);
img3.setOnClickListener(this);
img4.setOnClickListener(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog, null);
TextView tv = (TextView)layout.findViewById(R.id.dialog_text);
tv.setText(mStr);
bindImageClickEvent(layout);
this.setContentView(layout);
}
@Override
public void onClick(View view) {
int id = view.getId();
int drawableID = -1;
switch (id){
case R.id.dialog_image1:
drawableID = R.drawable.animal1;
break;
case R.id.dialog_image2:
drawableID = R.drawable.animal2;
break;
case R.id.dialog_image3:
drawableID = R.drawable.animal3;
break;
case R.id.dialog_image4:
drawableID = R.drawable.animal4;
break;
}
if (drawableID != -1) {
mCustomDialogEventListener.customDialogEvent(drawableID);
}
dismiss();
}
}
下面就是构造对话框的过程了:
在MainAcitivity中,当点击一个按钮时,new一个ICustomDialogEventListener实例来接收传过来的值;
Button btn = (Button)findViewById(R.id.btn_pop_dialog_1);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CustomDialog dialog = new CustomDialog(MainActivity.this,"From btn 1",new CustomDialog.ICustomDialogEventListener() {
@Override
public void customDialogEvent(int id) {
ImageView imageView = (ImageView)findViewById(R.id.main_image);
imageView.setImageDrawable(getResources().getDrawable(id));
}
},R.style.dialog);
dialog.show();
}
});
在我们收到传过来的DrawableID时,把它设置gc主页面ImageVIew里显示出来,这就完成了我们上面的功能。
好了,本文就到这里了,有关对话框的东东基本上都讲完了,一般还是我们自定义对话框的时间比较多,所以这里讲的啰嗦了一点;
# android对话框dialog
# Android UI设计系列之自定义Dialog实现各种风格的对话框效果(7)
# Android中制作自定义dialog对话框的实例分享
# Android中AlertDialog各种对话框的用法实例详解
# Android中使用DialogFragment编写对话框的实例教程
# Android 自定义对话框 showSetPwdDialog
# 对话框
# 回调
# 自定义
# 标题栏
# 第一个
# 是这样
# 第二个
# 给大家
# 弹出
# 那一
# 在这里
# 对话框中
# 就把
# 如图
# 绑定
# 即在
# 新建一个
# 返回值
# 都是
# 是在
相关文章:
如何通过宝塔面板实现本地网站访问?
如何选择适配移动端的WAP自助建站平台?
XML的“混合内容”是什么 怎么用DTD或XSD定义
建站之星图片链接生成指南:自助建站与智能设计教程
企业网站制作公司网页,推荐几家专业的天津网站制作公司?
清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?
C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)
如何高效完成独享虚拟主机建站?
已有域名和空间如何快速搭建网站?
,南京靠谱的征婚网站?
如何快速搭建FTP站点实现文件共享?
山东网站制作公司有哪些,山东大源集团官网?
开源网站制作软件,开源网站什么意思?
如何快速搭建支持数据库操作的智能建站平台?
宝塔建站无法访问?如何排查配置与端口问题?
制作门户网站的参考文献在哪,小说网站怎么建立?
建站中国必看指南:CMS建站系统+手机网站搭建核心技巧解析
官网自助建站平台指南:在线制作、快速建站与模板选择全解析
如何用花生壳三步快速搭建专属网站?
如何在Golang中使用encoding/gob序列化对象_存储和传输数据
宿州网站制作公司兴策,安徽省低保查询网站?
微信h5制作网站有哪些,免费微信H5页面制作工具?
javascript中对象的定义、使用以及对象和原型链操作小结
建站主机核心功能解析:服务器选择与网站搭建流程指南
设计网站制作公司有哪些,制作网页教程?
建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略
唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?
网页设计网站制作软件,microsoft office哪个可以创建网页?
微信网站制作公司有哪些,民生银行办理公司开户怎么在微信网页上查询进度?
建站之星上传入口如何快速找到?
网站代码制作软件有哪些,如何生成自己网站的代码?
如何在Tomcat中配置并部署网站项目?
实例解析Array和String方法
免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?
,想在网上投简历,哪几个网站比较好?
建站之星如何开启自定义404页面避免用户流失?
洛阳网站制作公司有哪些,洛阳的招聘网站都有哪些?
建站之星代理如何优化在线客服效率?
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
如何通过虚拟主机快速搭建个人网站?
建站主机选择指南:服务器配置与SEO优化实战技巧
自助网站制作软件,个人如何自助建网站?
如何选择靠谱的建站公司加盟品牌?
网站制作免费,什么网站能看正片电影?
如何选购建站域名与空间?自助平台全解析
新网站制作渠道有哪些,跪求一个无线渠道比较强的小说网站,我要发表小说?
如何确认建站备案号应放置的具体位置?
微信推文制作网站有哪些,怎么做微信推文,急?
如何通过服务器快速搭建网站?完整步骤解析
*请认真填写需求信息,我们会在24小时内与您取得联系。