发觉好久没有写长博客了,一是自己处于忙碌状态,没有时间写,其实最主要的还是归咎于自己太懒了。天下武功,唯懒不破。那就做一只早起的鸟儿吧。
在初学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,也贴出来。
<?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一下吧。
现在开始我们今天重中之重的内容了。
因为我们需要用自己定义的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。
<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>讲到这里,我们的所有布局和准备工作就算是完成了,开始撸代码了。
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的点击触发事件。
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的风格,也是我们刚才定义的。其实写到这里我们的主要工作已经到了尾声了。剩下的就是调用了。
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工具的封装啊,大家不会的就自行百度吧,我认为学习还是要靠自己的。
题外话:
android交流群:279031247(广告勿入)
新浪微博:SmartIceberg