Android 自定义dialog的实现代码

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();
  }

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

(0)

相关推荐

  • Android UI设计系列之自定义Dialog实现各种风格的对话框效果(7)

    虽然Android给我们提供了众多组件,但是使用起来都不是很方便,我们开发的APK都有自己的风格,如果使用了系统自带的组件,总是觉得和应用的主题不着边际并且看起来也不顺心,那我们就需要自定义了,为了方便大家对自定义组件的学习,我接下来准备了几遍有关自定义的Dialog的文章,希望对大家有帮助. 在开发APK中最常见的估计就数弹出对话框了,这种对话框按照按钮数量来分大致是三种:一个按钮,两个按钮,三个按钮.现在要讲的就是按照按钮数量分为以上三类吧(当然了可以有更多的按钮,只要你愿意). 自定义Di

  • Android 去掉自定义dialog的白色边框的简单方法

    在value目录下,创建styles.xml文件 复制代码 代码如下: <?xml version="1.0" encoding="UTF-8"?><resources xmlns:android="http://schemas.android.com/apk/res/android"> <style        name="dialog"        parent="@androi

  • Android自定义dialog可选择展示年月日时间选择栏

    自定义dialog package com.poptest; import android.app.DatePickerDialog; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.DatePicker; //dialog类 public class YearPickerDialog extends DatePickerD

  • Android自定义Dialog实现文字动态加载效果

    之前在技术问答上面看到一个提问 "加载中-" 后面三个点是动态的,这么一个效果实现.想来想去,好像没想到好的处理方式. 尝试了一下,以一个最笨的方式实现了.先来看一下效果 : 我是通过自定义一个Dialog,加载中的效果,是在Dialog内部实现的,进度还是从Activity里面控制的. 下面是Dialog实现类: public class CustomDialog extends AlertDialog { public CustomDialog(Context context) {

  • Android编程经典代码集锦(复制,粘贴,浏览器调用,Toast显示,自定义Dialog等)

    本文实例总结了Android编程经典代码段.分享给大家供大家参考,具体如下: 1. 复制,粘贴 clip = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); clip.setText("copy"); // 复制 clip.getText(); // 粘贴 2.调用浏览器 核心代码如下: Intent intent = new Intent(); intent.setAction("android.

  • Android 自定义Dialog 实例

    开发中经常需要请求网络获取数据,我们在请求网络到得到数据时当中需要等待一些时间,为了增加用户体验,我们一般会用一个Dialog来提示用户我们在加载网络数据. 今天我们来实现如下效果的加载中Dialog. 从图中我们可以看到要这个Dialog是图片还有文字组成的,(不过我这里使用代码实现的,没有用图片),以下是这个加载图形的代码: public class LVCircularRing extends View { private float mWidth = 0f; private float

  • Android中用Builder模式自定义Dialog的方法

    前言 我们开发人员在实际项目过程中遇到的需求是多种多样的,有时我们要匹配APP自己的设计风格,有时我们会觉得系统的对话框使用起来不够自由,因此自己定义一个适合自己的Dialog是很有必要的. 为什么要用Builder模式 Builder设计模式是一步步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程.它的优点就在于将对象的构建和表示分离从而解耦.我们都知道Android系统自身的对话框如AlertDialog就采用了Builder模式,因此可见

  • Android编程自定义Dialog的方法分析

    本文实例讲述了Android编程自定义Dialog的方法.分享给大家供大家参考,具体如下: 功能: android 提供给我们的只有2种Dialog 即 AlertDialog & ProgressDialog 但是 Dialog 有其自身的特点:1. 不是 Activity 2. 开销比 Activity 小得多 鉴于以上的优点 我们就有定制自己Dialog 的需求 原理: 1. android 系统提供了一个class: Dialog. 而且你可以把自己的工作放在"protected

  • Android中制作自定义dialog对话框的实例分享

    自定义dialog基础版 很多时候,我们在使用android sdk提供的alerdialog的时候,会因为你的系统的不同而产生不同的效果,就好比如你刷的是MIUI的系统,弹出框都会在顶部显示!这里简单的介绍自定义弹出框的应用. 首先创建布局文件dialog: 代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.and

  • Android编程中自定义dialog用法实例

    本文实例讲述了Android编程中自定义dialog用法.分享给大家供大家参考,具体如下: dialog是android中提供的一组弹出提示框,非常好用,可是它的样式是一个定式,有时候我们需求定义一些自己的样式 1.定义一个样式文件,此文件继承自Theme.Dialog,在style.xml文件中建立一个自己的样式 <style name="addNoteType_error_Dialog" parent="@android:Theme.Dialog">

  • Android自定义dialog简单实现方法

    本文实例讲述了Android自定义dialog简单实现方法.分享给大家供大家参考,具体如下: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.function_music); // 实例化新的窗口 Window w = getWindow(); // 获取默认显示数据 Display display

随机推荐