Android自定义view-弹出式dialog

闲谈:

发觉好久没有写长博客了,一是自己处于忙碌状态,没有时间写,其实最主要的还是归咎于自己太懒了。天下武功,唯懒不破。那就做一只早起的鸟儿吧。


前言:

在初学android的时候,就一直觉得系统的dialog写的简直是丑爆了,看到很多app都用了自己自定义的,感觉效果超棒,心想,哪天自己也有这个水平就好了,于是乎,下定决心,好好学习android。吐舌头废话太多了,赶紧今天的教程吧。


正文:

今天我们要实现的效果图是这样的:


这样的dialog比原生的好看多了,至少我是这样认为的害羞。其实做出这样一个效果还是不难的,代码来说,也不是很多。
项目结构图:


要学习这篇博客,首先要会一些常见的自定义style,和常见的android基础,我们这边没有用到自定义属性。
先来看看我们的主要布局吧。主要布局也就只有三个button,我就不详细说明怎么布局了,直接把代码贴上来了。
activity_main.xml:

<LinearLayout 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"
    android:background="@color/color_gray_normal"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/selector_btn_blue"
        android:padding="@dimen/dip10"
        android:text="btn1" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/dip10"
        android:background="@drawable/selector_btn_blue"
        android:padding="@dimen/dip10"
        android:text="btn2" />

    <Button
        android:id="@+id/btn3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/dip10"
        android:background="@drawable/selector_btn_blue"
        android:padding="@dimen/dip10"
        android:text="btn3" />

</LinearLayout>
当然这边有些color,dimen,也贴出来。
colors.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <color name="color_blue_lighted">#539ad6</color>
    <color name="color_blue_normal">#61b1f4</color>
    <color name="color_gray_normal">#f5f5f5</color>
    <color name="color_gray_lighted">#efefef</color>
    <color name="color_white">#FFFFFF</color>
    <color name="color_border_white">#e5e5e5</color>
    <color name="color_gray">#999999</color>

</resources>
dimens.xml:

<resources>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="cornerRadius_size">3dip</dimen>
    <dimen name="dip10">10dip</dimen>
    <dimen name="dip12">12dip</dimen>
    <dimen name="dip14">14dip</dimen>
    <dimen name="dip16">16dip</dimen>
    <dimen name="dip18">18dip</dimen>
    <dimen name="dip20">20dip</dimen>
    <dimen name="dip8">8dp</dimen>
    <dimen name="sp16">16sp</dimen>

</resources>
selectors太多了,我就不把主要篇幅花在这个上面了,需要的自行下载我稍后贴出的下载地址,或者去我的github地址clone一下吧。
Android自定义view-弹出式dialog_第1张图片

现在开始我们今天重中之重的内容了。
因为我们需要用自己定义的dialog,那么我们就需要自定义个dialog的布局文件。分析一下上面的dialog效果,无非是一个想要显示的

texview的主要内容,还有一个分隔线,最后还有两个button就完事了。
好,开始写我们的布局文件,也就是layout_common_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_parent"
    android:background="#00000000"
    android:gravity="center" >

    <LinearLayout
        android:id="@+id/llSuccessBoard"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/corner_btn_white_normal"
        android:gravity="center"
        android:orientation="vertical"
        android:padding="@dimen/dip20" >

        <TextView
            android:id="@+id/tvPromptMsg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="@dimen/dip18"
            android:text="提示"
            android:textColor="#444444"
            android:textSize="@dimen/sp16" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="1dip"
            android:background="#eeeeee" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="@dimen/dip14"
            android:orientation="horizontal" >

            <Button
                android:id="@+id/btnCancle"
                android:layout_width="100dip"
                android:layout_height="wrap_content"
                android:background="@drawable/selector_btn_gray"
                android:gravity="center"
                android:paddingBottom="@dimen/dip8"
                android:paddingLeft="@dimen/dip10"
                android:paddingRight="@dimen/dip10"
                android:paddingTop="@dimen/dip8"
                android:text="取消"
                android:textColor="@color/color_gray"
                android:textSize="@dimen/sp16" />

            <Button
                android:id="@+id/btnSure"
                android:layout_width="100dip"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dip"
                android:background="@drawable/selector_btn_blue"
                android:gravity="center"
                android:paddingBottom="@dimen/dip8"
                android:paddingLeft="@dimen/dip10"
                android:paddingRight="@dimen/dip10"
                android:paddingTop="@dimen/dip8"
                android:text="确定"
                android:textColor="@color/color_white"
                android:textSize="@dimen/sp16" />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>
当然,这个布局文件也没什么好说的,应该都是看得懂的,我们到时候就是通过这个布局文件inflater成一个view,设置原生dialog的contentView。
需要完成上述效果,还要定制一下我们的dialog风格,不然,你以为的灰色暗背景哪里来的。那我们就在styles.xml文件中定制一下风格吧。
styles.xml:
<resources>

    <style name="commonDialog" parent="@android:style/Theme.Dialog">

        <!-- Dialog的windowFrame框为无 -->
        <item name="android:windowFrame">@null</item>
        <!-- 没有标题 -->
        <item name="android:windowNoTitle">true</item>
        <!-- 透明背景颜色 -->
        <!-- <item name="android:windowIsTranslucent">false</item>:是否半透明 -->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!-- 是否浮动内容在activity之上 -->
        <item name="android:windowContentOverlay">@null</item>
        <!-- 是否浮现在activity之上 -->
        <item name="android:windowIsFloating">false</item>
        <!-- 是否允许全屏 -->
        <item name="android:windowFullscreen">false</item>
        <!-- 是否允许背景灰暗 -->
        <item name="android:backgroundDimEnabled">true</item>
    </style>

</resources>
讲到这里,我们的所有布局和准备工作就算是完成了,开始撸代码了。
CommonDialog.java:

package com.example.commondialog;

import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;

/**
 * 通用弹出框
 * 
 */

public class CommonDialog {
	private Dialog dialog;
	Context context;
	DialogPositiveListener positiveListener;
	DialogNegativeListener negativeListener;

	public CommonDialog(Context context) {
		super();
		this.context = context;
	}

	public void setPositiveListener(DialogPositiveListener positiveListener) {
		this.positiveListener = positiveListener;
	}

	public void setNegativeListener(DialogNegativeListener negativeListener) {
		this.negativeListener = negativeListener;
	}

	/**
	 * context promptMsg 提示信息
	 * */
	public Dialog initDialog(String promptMsg) {
		return initDialog(promptMsg, "取消", "确认");
	}

	/**
	 * context promptMsg 提示信息 cancleBtnMsg 取消按钮信息 sureBtnMsg 确认按钮信息
	 * */
	public Dialog initDialog(String promptMsg, String cancleBtnMsg,String sureBtnMsg) {
		View view = LayoutInflater.from(context).inflate(
				R.layout.layout_common_dialog, null);
		view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT));
		dialog = ResultDialog.creatAlertDialog(context, view);
		TextView tvPromptMsg = (TextView) view.findViewById(R.id.tvPromptMsg);
		Button btnCancle = (Button) view.findViewById(R.id.btnCancle);
		Button btnSure = (Button) view.findViewById(R.id.btnSure);

		tvPromptMsg.setText(promptMsg);
		btnCancle.setText(cancleBtnMsg);
		btnSure.setText(sureBtnMsg);

		btnCancle.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (negativeListener != null) {
					negativeListener.onClick();
				}
				dialog.dismiss();
			}
		});
		btnSure.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (positiveListener != null) {
					positiveListener.onClick();
				}
				dialog.dismiss();
			}
		});
		return dialog;
	}

	public interface DialogPositiveListener {
		void onClick();
	}

	public interface DialogNegativeListener {
		void onClick();
	}
}
呐,上面的效果图中可以看出,我们不仅可以只指定提示的内容,我们还可以指定button的内容是什么。所以呢,我们需要构造两个创建dialog的方法来初始化dialog。同时,我们也需要传入两个监听器,来监听两个button的点击触发事件。
我们在initDialog的时候创建我们的alertDialog,新开了一个类用来创建我们的dialog。
ResultDialog.java:
package com.example.commondialog;

import android.app.Dialog;
import android.content.Context;
import android.view.View;
import android.widget.LinearLayout;

/**
 * view 视图作为 dialog 弹出提示框
 * */
public class ResultDialog {
	static Dialog loading = null;

	public static Dialog creatAlertDialog(Context context, View view) {
		Dialog loading = new Dialog(context, R.style.commonDialog);
		loading.setCancelable(true);
		loading.setContentView(view, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (LinearLayout.LayoutParams.MATCH_PARENT)));
		return loading;
	}
}
最主要的就是setContentVIew了,也就是我们之前提到过的哦,view也就是我们inflater的那个view。同时,我们也指定了dialog的风格,也是我们刚才定义的。其实写到这里我们的主要工作已经到了尾声了。剩下的就是调用了。
MainActivity.java:
package com.example.commondialog;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.example.commondialog.CommonDialog.DialogNegativeListener;
import com.example.commondialog.CommonDialog.DialogPositiveListener;

public class MainActivity extends Activity implements OnClickListener {

	private Button btn1;
	private Button btn2;
	private Button btn3;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		btn1 = (Button) findViewById(R.id.btn1);
		btn1.setOnClickListener(this);
		btn2 = (Button) findViewById(R.id.btn2);
		btn2.setOnClickListener(this);
		btn3 = (Button) findViewById(R.id.btn3);
		btn3.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn1:
			CommonDialog dialog1 = new CommonDialog(this);
			dialog1.setPositiveListener(new DialogPositiveListener() {
				@Override
				public void onClick() {
					ToastUtils.show(MainActivity.this, "确定");
				}
			});
			dialog1.initDialog("您确定要删除收藏?").show();
			break;
		case R.id.btn2:
			CommonDialog dialog2 = new CommonDialog(this);
			dialog2.setPositiveListener(new DialogPositiveListener() {
				@Override
				public void onClick() {
					ToastUtils.show(MainActivity.this, "确定");
				}
			});
			dialog2.setNegativeListener(new DialogNegativeListener() {
				@Override
				public void onClick() {
					ToastUtils.show(MainActivity.this, "取消");
				}
			});
			dialog2.initDialog("您确定要取消该收藏?").show();
			break;
		case R.id.btn3:
			CommonDialog dialog3 = new CommonDialog(this);
			dialog3.setPositiveListener(new DialogPositiveListener() {
				@Override
				public void onClick() {
					ToastUtils.show(MainActivity.this, "再看看");
				}
			});
			dialog3.setNegativeListener(new DialogNegativeListener() {
				@Override
				public void onClick() {
					ToastUtils.show(MainActivity.this, "退出");
				}
			});
			dialog3.initDialog("您确定现在退出app吗?", "退出", "再看看").show();
			break;
		default:
			break;
		}

	}

}
调用我就不详细讲了,对于一些基础的toast工具的封装啊,大家不会的就自行百度吧,我认为学习还是要靠自己的。
后语:
嗯,到这里我们的项目就算是结束了。大家有没有觉得不是很难(不敢说简单)。
Github地址: https://github.com/xuejiawei/beyole_android_commondialog 欢迎fork or star
csdn下载地址: http://download.csdn.net/detail/smarticeberg/9469652

题外话:

android交流群:279031247(广告勿入)

新浪微博:SmartIceberg




你可能感兴趣的:(Android自定义view-弹出式dialog)