android-自定义对话框视图及参数传递

一、雏形构建

先给大家看下这小节的效果图:

自定义一个对话框,内容是四个ImageView横排;

1、Dialog布局

根据上图的对话框样式,我们看一下Dialog的布局定义(custom_dialog.xml)

[html] view plaincopy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/log_in_layout"
  4. android:layout_width="fill_parent"
  5. android:layout_height="wrap_content"
  6. android:orientation="horizontal">
  7. <ImageView
  8. android:layout_width="match_parent"
  9. android:layout_height="100dip"
  10. android:src="@drawable/animal1"
  11. android:clickable="true"
  12. android:layout_weight="1"/>
  13. <ImageView
  14. android:layout_width="match_parent"
  15. android:layout_height="100dip"
  16. android:src="@drawable/animal2"
  17. android:clickable="true"
  18. android:layout_weight="1"/>
  19. <ImageView
  20. android:layout_width="match_parent"
  21. android:layout_height="100dip"
  22. android:src="@drawable/animal3"
  23. android:clickable="true"
  24. android:layout_weight="1"/>
  25. <ImageView
  26. android:layout_width="match_parent"
  27. android:layout_height="100dip"
  28. android:src="@drawable/animal4"
  29. android:clickable="true"
  30. android:layout_weight="1"/>
  31. </LinearLayout>

2、从Dialog派生对话框类

有关构造函数:
有三种构造函数,现在我这里使用重写了两个,这里只需要使用第一个,即传进去context即可;

有关OnCreate()

在OnCreate()时,利用LayoutInflater获取我们对话框的View,然后利用SetContentView指定为我们CustomDialog类的布局。

[java] view plaincopy

  1. public class CustomDialog extends Dialog {
  2. Context mContext;
  3. public CustomDialog (Context context){
  4. super(context);
  5. mContext = context;
  6. }
  7. public CustomDialog(Context context, int theme) {
  8. super(context, theme);
  9. mContext = context;
  10. }
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. LayoutInflater inflater = (LayoutInflater) mContext
  15. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  16. View layout = inflater.inflate(R.layout.custom_dialog, null);
  17. this.setContentView(layout);
  18. }
  19. }

3、主函数(MainActivity)

在MainActivity中,我们写一个Button,当用户点击的时候弹出我们自定义的对话框实例

MainActivity的布局:(activity_main.xml)

[html] view plaincopy

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context=".MainActivity">
  6. <Button
  7. android:id="@+id/btn_pop_dialog"
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:text="弹出对话框"/>
  11. </RelativeLayout>

代码中的处理:(MainActivity.java)
在点击Btn的时候,创建CustomDialog类的实例,并显示

[java] view plaincopy

  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. Button btn = (Button)findViewById(R.id.btn_pop_dialog);
  7. btn.setOnClickListener(new View.OnClickListener() {
  8. @Override
  9. public void onClick(View view) {
  10. CustomDialog dialog = new  CustomDialog(MainActivity.this);
  11. dialog.show();
  12. }
  13. });
  14. }
  15. }

这部分源码在文章最底部给出;

二、定义对话框样式

这里再回头看看上面弹出的对话框:

在布局中,我们只定义了一个水平布局,里面放了四个ImageView,即那四个小动物,那上面那一坨是哪来的呢(我用红笔圈出来的那块)?能不能去掉?这节,我们就说说有关样式的问题。

第一个问题,只所有上面那一坨,是因为我们没有指定对话框样式,系统会使用默认样式,那一坨就是标题栏。

要去掉的话,我们就需要自定义样式。

1、自定义样式

我们的样式是写在res/values文件夹下的style.xml文件中的,如图,如果没有style.xml,自已新建一个,位置如图:

这里定义的样式代码是这样的:

[html] view plaincopy

  1. <style name="dialog" parent="android:Theme.Dialog">
  2. <item name="android:windowFrame">@null</item>
  3. <item name="android:windowIsFloating">true</item>
  4. <item name="android:windowContentOverlay">@null</item>
  5. <item name="android:windowNoTitle">true</item>
  6. </style>

先对这几个参数解释一下:

android:windowFrame:界面对应的前景图片;
android:windowIsFloating:表示浮在屏幕上的,如果在这里使用了,整个layout就会在 屏幕中心,相当于浮在屏幕上,所以这个只适用于dialog
android:windowContentOverlay:表示标题栏的阴影部分的样式,使用图片或者颜色
android:windowNoTitle:标题栏是否隐藏,这就是我们上面显示的标题栏

有关样式的内容很多很杂,这里有篇文章大家可以参考下《Andriod中Style/Theme原理以及Activity界面文件选取过程浅析》,有机会给大家总结一下有关样式和主题的内容,到时再细讲,这里不是本篇的重点,就不再细讲了。

2、使用样式

方法一:

这里有两种方法来使用样式,主要还是利用构造函数,还记得我们上面说过,对话框的两个构造函数:

[java] view plaincopy

  1. public class CustomDialog extends Dialog {
  2. Context mContext;
  3. public CustomDialog(Context context) {
  4. super(context);
  5. mContext = context;
  6. }
  7. public CustomDialog(Context context, int theme) {
  8. super(context, theme);
  9. mContext = context;
  10. }
  11. …………
  12. }

看第二个就是我们的Theme样式,所以第一种使用样式的方法是在构造时直接将样式传进来,如果这样使用,那我们在构造对话框时应该是这样的“:

[java] view plaincopy

  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. Button btn = (Button)findViewById(R.id.btn_pop_dialog);
  7. btn.setOnClickListener(new View.OnClickListener() {
  8. @Override
  9. public void onClick(View view) {
  10. CustomDialog dialog = new  CustomDialog(MainActivity.this,R.style.dialog);
  11. dialog.show();
  12. }
  13. });
  14. }
  15. }

即在新建CustomDialog实例时,第二个参数传进来我们上面定义的样式。

方法二:

第二种方法,就是我们在构造时,不让别人传样式,只让传进来Context,但在内部,我们利用Super(context,theme)来指定样式,代码如下:

[java] view plaincopy

  1. public class CustomDialog extends Dialog {
  2. Context mContext;
  3. public CustomDialog(Context context) {
  4. super(context,R.style.dialog);
  5. mContext = context;
  6. }
  7. …………
  8. }

这种情况一般用在我们封装代码时,不让其它人在外部改变我们的样式时使用的。
无论使用哪种方法,我们就已经指定我我们的对话框样式,现在的效果是这样的:

看到了没,上面的标题栏没了,下面再看看有关参数传递的问题

三、参数传递

这里涉及到两个问题:传进去和传出来;

传进去:下面有两个按钮,当用户点第一个按钮时,在对话框中显示"From btn 1",如果用户点击第二个按钮,在对话框中显示“From btn 2”

传出来:这四个图片都是可以点击的,当用户点击任何一个图片,把它的ID传出来,并设置到我们的MainActivity中;

这里为了好理解,更改了对话框的布局,将水平布局改成了垂直布局。并且在MainActiviy下面加了一个ImageView.

1、传进去

往对话框里传参数,一般就是利用构造函数来完成的,很简单,即在对话框的构造函数上加上我们自己想要传的参数,这里我们需要额外传一个字符串,来表示从哪个BTN来的。

所以对话框的构造函数就变成了这样:

[java] view plaincopy

  1. public class CustomDialog extends Dialog{
  2. private Context mContext;
  3. private String mStr;
  4. public CustomDialog(Context context, String str, int theme) {
  5. super(context, theme);
  6. mContext = context;
  7. mStr = str;
  8. }
  9. …………
  10. }

在使用的时候,也很简单:

[java] view plaincopy

  1. Button btn2 = (Button)findViewById(R.id.btn_pop_dialog_2);
  2. btn2.setOnClickListener(new View.OnClickListener() {
  3. @Override
  4. public void onClick(View view) {
  5. CustomDialog dialog = new  CustomDialog(MainActivity.this,"From btn 2",R.style.dialog);
  6. dialog.show();
  7. }
  8. });

直接利用构造函数传参即可

2、传出来

利用构造函数传参数大家都知道,但要怎么把用户的操作信息传出来就不是那么简单了,这里就要利用回调来实现了!

回调函数的使用主要依照下面这些步骤:

在对话框中:

[java] view plaincopy

  1. public class CustomDialog extends Dialog {
  2. // 利用interface来构造一个回调函数
  3. public interface ICustomDialogEventListener {
  4. public void customDialogEvent(int valueYouWantToSendBackToTheActivity);
  5. }
  6. private ICustomDialogEventListener onCustomDialogEventListener;
  7. // 在构造函数中,设置进去回调函数
  8. public CustomDialog(Context context,
  9. ICustomDialogEventListener onCustomDialogEventListener) {
  10. super(context);
  11. this.onCustomDialogEventListener = onCustomDialogEventListener;
  12. }
  13. //当你想把值传回去的时候,调用回调函数将值设置进去
  14. @Override
  15. public void onCreate(Bundle savedInstanceState)
  16. {
  17. Button btnOk = (Button) findViewById(R.id.customDialogButton);
  18. btnOk.setOnClickListener( new Button.OnClickListener()
  19. {
  20. public void onClick(View v) {
  21. onCustomDialogEventListener.customDialogEvent(valueYouWantToSendBackToTheActivity);
  22. dismiss();
  23. }
  24. });
  25. }
  26. }

在构造对话框时:

[java] view plaincopy

  1. final CustomDialog dialog = new CustomDialog(this, new ICustomDialogEventListener() {
  2. public void customDialogEvent(int value) {
  3. //在这里就获取到了从对话框传回来的值
  4. }
  5. });

大致使用流程就是这样的,下面就把我们上面的效果利用回调函数实现出来;

首先在对话框中新建一个回调函数(接口),并且在对话框的构造方法中把回调函数传进来:

[java] view plaincopy

  1. public class CustomDialog extends Dialog implements View.OnClickListener {
  2. //增加一个回调函数,用以从外部接收返回值
  3. public interface ICustomDialogEventListener {
  4. public void customDialogEvent(int id);
  5. }
  6. private ICustomDialogEventListener mCustomDialogEventListener;
  7. private Context mContext;
  8. private String mStr;
  9. //把回调函数传进来
  10. public CustomDialog(Context context, String str, ICustomDialogEventListener listener, int theme) {
  11. super(context, theme);
  12. mContext = context;
  13. mStr = str;
  14. mCustomDialogEventListener = listener;
  15. }
  16. …………
  17. }

然后在OnCreate() 函数中设定ImageView的点击事件,我们将CustomDialog类继承View.OnClickListener接口,对点击事件统一处理:

[java] view plaincopy

  1. private void bindImageClickEvent(View layout){
  2. ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1);
  3. ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2);
  4. ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3);
  5. ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4);
  6. img1.setOnClickListener(this);
  7. img2.setOnClickListener(this);
  8. img3.setOnClickListener(this);
  9. img4.setOnClickListener(this);
  10. }
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. LayoutInflater inflater = (LayoutInflater) mContext
  15. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  16. View layout = inflater.inflate(R.layout.custom_dialog, null);
  17. TextView tv = (TextView)layout.findViewById(R.id.dialog_text);
  18. tv.setText(mStr);
  19. bindImageClickEvent(layout);//绑定ImageView点击事件
  20. this.setContentView(layout);
  21. }

在OnCreate()中,首先将传进来的String字符串设置到对话框的TextView中;然后绑定各个ImageView的点击事件
然后 就是在OnClick中的处理:

主要是根据用户当前点击的ImageView的ID,把这个ImageView所用的图片的DrawableID返回给MainActivity,代码如下:

[java] view plaincopy

  1. public void onClick(View view) {
  2. int id = view.getId();
  3. int drawableID = -1;
  4. switch (id){
  5. case R.id.dialog_image1:
  6. drawableID = R.drawable.animal1;
  7. break;
  8. case R.id.dialog_image2:
  9. drawableID = R.drawable.animal2;
  10. break;
  11. case R.id.dialog_image3:
  12. drawableID = R.drawable.animal3;
  13. break;
  14. case R.id.dialog_image4:
  15. drawableID = R.drawable.animal4;
  16. break;
  17. }
  18. if (drawableID != -1) {
  19. mCustomDialogEventListener.customDialogEvent(drawableID);
  20. }
  21. dismiss();
  22. }

这样就把对话框的构造过程讲完了,完整的对话框代码是这样的:

[java] view plaincopy

  1. public class CustomDialog extends Dialog implements View.OnClickListener{
  2. //增加一个回调函数,用以从外部接收返回值
  3. public interface ICustomDialogEventListener {
  4. public void customDialogEvent(int id);
  5. }
  6. private ICustomDialogEventListener mCustomDialogEventListener;
  7. private Context mContext;
  8. private String mStr;
  9. public CustomDialog(Context context) {
  10. super(context);
  11. mContext = context;
  12. }
  13. public CustomDialog(Context context, String str,ICustomDialogEventListener listener,int theme) {
  14. super(context, theme);
  15. mContext = context;
  16. mStr = str;
  17. mCustomDialogEventListener = listener;
  18. }
  19. private void bindImageClickEvent(View layout){
  20. ImageView img1 = (ImageView)layout.findViewById(R.id.dialog_image1);
  21. ImageView img2 = (ImageView)layout.findViewById(R.id.dialog_image2);
  22. ImageView img3 = (ImageView)layout.findViewById(R.id.dialog_image3);
  23. ImageView img4 = (ImageView)layout.findViewById(R.id.dialog_image4);
  24. img1.setOnClickListener(this);
  25. img2.setOnClickListener(this);
  26. img3.setOnClickListener(this);
  27. img4.setOnClickListener(this);
  28. }
  29. @Override
  30. protected void onCreate(Bundle savedInstanceState) {
  31. super.onCreate(savedInstanceState);
  32. LayoutInflater inflater = (LayoutInflater) mContext
  33. .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  34. View layout = inflater.inflate(R.layout.custom_dialog, null);
  35. TextView tv = (TextView)layout.findViewById(R.id.dialog_text);
  36. tv.setText(mStr);
  37. bindImageClickEvent(layout);
  38. this.setContentView(layout);
  39. }
  40. @Override
  41. public void onClick(View view) {
  42. int id = view.getId();
  43. int drawableID = -1;
  44. switch (id){
  45. case R.id.dialog_image1:
  46. drawableID = R.drawable.animal1;
  47. break;
  48. case R.id.dialog_image2:
  49. drawableID = R.drawable.animal2;
  50. break;
  51. case R.id.dialog_image3:
  52. drawableID = R.drawable.animal3;
  53. break;
  54. case R.id.dialog_image4:
  55. drawableID = R.drawable.animal4;
  56. break;
  57. }
  58. if (drawableID != -1) {
  59. mCustomDialogEventListener.customDialogEvent(drawableID);
  60. }
  61. dismiss();
  62. }
  63. }

下面就是构造对话框的过程了:

在MainAcitivity中,当点击一个按钮时,new一个ICustomDialogEventListener实例来接收传过来的值;

[java] view plaincopy

  1. Button btn = (Button)findViewById(R.id.btn_pop_dialog_1);
  2. btn.setOnClickListener(new View.OnClickListener() {
  3. @Override
  4. public void onClick(View view) {
  5. CustomDialog dialog = new  CustomDialog(MainActivity.this,"From btn 1",new CustomDialog.ICustomDialogEventListener() {
  6. @Override
  7. public void customDialogEvent(int id) {
  8. ImageView imageView = (ImageView)findViewById(R.id.main_image);
  9. imageView.setImageDrawable(getResources().getDrawable(id));
  10. }
  11. },R.style.dialog);
  12. dialog.show();
  13. }
  14. });

在我们收到传过来的DrawableID时,把它设置gc主页面ImageVIew里显示出来,这就完成了我们上面的功能。

转自:http://blog.csdn.net/harvic880925/article/details/42712777

时间: 2024-08-08 02:32:20

android-自定义对话框视图及参数传递的相关文章

Android 自定义View视图

创建全新的视图将满足我们独特的UI需求. 本文介绍在指南针开发中会用到的罗盘的界面UI,通过继承View类实现的自定义视图,以此来深刻了解自定义视图. 实现效果图: 源代码: 布局文件activity_main(其中CompassView继承View类): <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.

android 自定义对话框

新建一个布局文件 my_dialog.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match

Android 自定义对话框,进度条,下拉刷新等

这个demo集合了自定义对话框,进度条,下拉刷新以及popup弹出框等.是学习了网上开源项目后,抽取集合了常用对话框,进度条,下拉刷新以及popup弹出框等.现在结构目录简单,更易于学习和扩展使用.注释都卸载代码.下面进行简单的介绍以及部分代码展示. 本文demo下载:点击 1.整体实现的效果图 2.项目结构图 这上面项目结构图也是一目了然,有什么功能展示.大家也看到了,这上面类有点多,如果全部贴出来,不大可能,有兴趣下载本文源码. 3.看看基础类BaseActivity 我就贴一下基础类,还有

Android自定义组件系列【13】——Android自定义对话框如此简单

在我们的日常项目中很多地方会用到对话框,但是Android系统为我们提供的对话框样子和我们精心设计的界面很不协调,在这种情况下我们想很自由的定义对话框,或者有的时候我们的对话框是一个图片,没有标题和按钮,例如这样的一系列需求,这一篇文章我们来给大家介绍一下如何像使用Activity一样来自定义我们的对话框. 一般自定义对话框有下面几种办法: 1.重写Dialog来实现. 2.获取Dialog的Window对象实现. 3.使用WindowManager来实现. 4.使用DialogTheme来实现

android自定义对话框

2015-04-02 18:27:02 有的时候安卓内置的对话框不能满足我们的需要,或许是功能不齐全亦或者不符合我们的界面设计要求,这个时候我们就需要弄一个我们自己设置的对话框了,下面我将为大家讲一种很简单的方法创建自己的对话框. 首先创建一个style 即:<style name="你自己命名" parent="@android:Theme.Dialog">.......</style>这个相信大家都懂的. 接着创建你自己的对话框布局:自己

Android自定义对话框实现QQ退出界面

效果 首先看下qq的效果图,点击菜单按钮后点退出就会出现如图的对话框. 从上图可以看出,该对话框有一个圆角,以及标题,提示信息,两个按钮,按钮颜色是白色,按钮点击后背景会变成灰色,正常状态下对话框的背景色是白色.并且除了点击取消按钮和返回键外,点击屏幕其他区域该对话框不会小时.那么现在我们来实现一下这个对话框.我们实现后的效果如下图所示 实现 首先编写我们的背景,背景默认情况下是白色的,并且有一个圆角,使用shape实现 <?xml version="1.0" encoding=

Android自定义对话框(Dialog)位置,大小

代码: package angel.devil; import android.app.Activity;import android.app.Dialog;import android.os.Bundle;import android.view.Gravity;import android.view.Window;import android.view.WindowManager; public class DialogDemoActivity extends Activity { /** C

Android 自定义对话框(Dialog)位置,大小

代码: package angel.devil; import android.app.Activity; import android.app.Dialog; import android.os.Bundle; import android.view.Gravity; import android.view.Window; import android.view.WindowManager; public class DialogDemoActivity extends Activity {

Android 自定义对话框使用静态Handler传递参数

JsdMainDialog.java package com.jsd.demo; import android.app.Activity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import andr