├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── liangmutian │ │ └── myapplication2 │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── liangmutian │ │ │ └── myapplication2 │ │ │ ├── AirDialog.java │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ ├── activity_main.xml │ │ └── dialog.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── example │ └── liangmutian │ └── myapplication2 │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 26 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Abstraction issuesJava 46 | 47 | 48 | Android 49 | 50 | 51 | Android > Lint > Accessibility 52 | 53 | 54 | Android > Lint > Correctness 55 | 56 | 57 | Android > Lint > Correctness > Messages 58 | 59 | 60 | Android > Lint > Internationalization 61 | 62 | 63 | Android > Lint > Internationalization > Bidirectional Text 64 | 65 | 66 | Android > Lint > Performance 67 | 68 | 69 | Android > Lint > Security 70 | 71 | 72 | Android > Lint > Usability 73 | 74 | 75 | Android > Lint > Usability > Icons 76 | 77 | 78 | Android > Lint > Usability > Typography 79 | 80 | 81 | Assignment issuesJava 82 | 83 | 84 | Bitwise operation issuesJava 85 | 86 | 87 | C/C++ 88 | 89 | 90 | Class metricsJava 91 | 92 | 93 | Class structureJava 94 | 95 | 96 | Cloning issuesJava 97 | 98 | 99 | Code maturity issuesJava 100 | 101 | 102 | Code style issuesJava 103 | 104 | 105 | Compiler issuesJava 106 | 107 | 108 | Control FlowGroovy 109 | 110 | 111 | Control flow issuesJava 112 | 113 | 114 | Data flow issuesJava 115 | 116 | 117 | Dependency issuesJava 118 | 119 | 120 | Encapsulation issuesJava 121 | 122 | 123 | Error handlingJava 124 | 125 | 126 | Finalization issuesJava 127 | 128 | 129 | General 130 | 131 | 132 | GeneralC/C++ 133 | 134 | 135 | GeneralJava 136 | 137 | 138 | Google Cloud Endpoints 139 | 140 | 141 | Gradle 142 | 143 | 144 | Groovy 145 | 146 | 147 | HTML 148 | 149 | 150 | ImportsJava 151 | 152 | 153 | Inheritance issuesJava 154 | 155 | 156 | Initialization issuesJava 157 | 158 | 159 | Internationalization issues 160 | 161 | 162 | Internationalization issuesJava 163 | 164 | 165 | J2ME issuesJava 166 | 167 | 168 | JUnit issuesJava 169 | 170 | 171 | Java 172 | 173 | 174 | Java language level issuesJava 175 | 176 | 177 | Java language level migration aidsJava 178 | 179 | 180 | JavaBeans issuesJava 181 | 182 | 183 | Javadoc issuesJava 184 | 185 | 186 | Logging issuesJava 187 | 188 | 189 | Manifest 190 | 191 | 192 | Memory issuesJava 193 | 194 | 195 | Method MetricsGroovy 196 | 197 | 198 | Method metricsJava 199 | 200 | 201 | Modularization issuesJava 202 | 203 | 204 | Naming ConventionsGroovy 205 | 206 | 207 | Naming conventionsJava 208 | 209 | 210 | Numeric issuesJava 211 | 212 | 213 | Packaging issuesJava 214 | 215 | 216 | Pattern Validation 217 | 218 | 219 | Performance issuesJava 220 | 221 | 222 | Portability issuesJava 223 | 224 | 225 | Potentially confusing code constructsGroovy 226 | 227 | 228 | Probable bugsGradle 229 | 230 | 231 | Probable bugsGroovy 232 | 233 | 234 | Probable bugsJava 235 | 236 | 237 | Properties Files 238 | 239 | 240 | Properties FilesJava 241 | 242 | 243 | Security issuesJava 244 | 245 | 246 | Serialization issuesJava 247 | 248 | 249 | StyleGroovy 250 | 251 | 252 | TestNGJava 253 | 254 | 255 | Threading issuesGroovy 256 | 257 | 258 | Threading issuesJava 259 | 260 | 261 | Visibility issuesJava 262 | 263 | 264 | XML 265 | 266 | 267 | toString() issuesJava 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 289 | 290 | 291 | 292 | 293 | 294 | 299 | 300 | 301 | 302 | 303 | 304 | 1.8 305 | 306 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 322 | 323 | 324 | 325 | 326 | 327 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AirDialog 2 | 3 | 4 | **本文将从一下几个方面展开: 5 | 1Bulider模式的原理和使用 6 | 2系统Dailog的调用 7 | 3自定义Dailog 8 | 4自定义Dailog的一些小坑** 9 | 10 | 11 | 12 | 13 | 本文Github代码链接 14 | https://github.com/AndroidMsky/AirDialog 15 | 16 | 自定义Dailog效果: 17 | ![这里写图片描述](http://img.blog.csdn.net/20161031143817212) 18 | 19 | 20 | 21 | 1.Bulider模式的原理和使用 22 | ---------------- 23 | 24 | 当你看到这样的一串代码是不是觉得很炫酷? 25 | 26 | ``` 27 | airDialog = new AirDialog.Builder(this). 28 | setLeftText("gogo"). 29 | setRightText("nono"). 30 | create(); 31 | ``` 32 | 通过几个点点,像一个链子一样配置组装一个对象。今天就教给大家自己也可以设计这样一条链子。相比构造方法,这种模式更加灵活,更加清晰。 33 | 34 | 先看看设计图: 35 | ![这里写图片描述](http://img.blog.csdn.net/20161031144337035) 36 | 37 | 别怕相信大多数人都看不懂。不过对设计模式了解比较多的人呢还是可以看懂的,今天就咱不谈这个类图(你看懂不如会用)。 38 | 为什么可以里连续.......的调用方法,其实就是每次调用方法后return一个对象就好喽。当前的表达式值就一直是这个对象所以可以无限的....下去。 39 | 40 | ``` 41 | public Builder setLeftText(String left) { 42 | this.left=left; 43 | return this; 44 | } 45 | ``` 46 | 代码很清晰没个设置方法都是这样的,方法的返回类型就是当前的Builder。那么我们就可以继续的调用Builder类中的方法喽。 47 | 48 | 49 | 50 | 2.系统Dailog的调用 51 | ------------ 52 | 53 | 54 | 55 | ``` 56 | new AlertDialog.Builder(MainActivity.this).setTitle("系统提示")//设置对话框标题 57 | 58 | .setMessage("!")//设置显示的内容 59 | 60 | .setPositiveButton("确定",new DialogInterface.OnClickListener() {//添加确定按钮 61 | @Override 62 | 63 | public void onClick(DialogInterface dialog, int which) { 64 | } 65 | 66 | }).setNegativeButton("返回",new DialogInterface.OnClickListener() {//添加返回按钮 67 | @Override 68 | public void onClick(DialogInterface dialog, int which) { 69 | } 70 | }).show();//在按键响应事件中显示此对话框 71 | ``` 72 | 系统提供了很多的Dialog的子类本文不去详细介绍,接下来就说如何自己写一个类似Dialog的子类。 73 | 74 | 75 | 76 | 3.自定义Dailog 77 | ---------- 78 | 79 | 80 | 1继承Dialog并且实现构造方法: 81 | ``` 82 | public class AirDialog extends Dialog { 83 | 84 | public AirDialog(Context context) { 85 | super(context, R.style.custom_dialog); 86 | } 87 | ``` 88 | super方法的第二个参数是为Dialog指定一个主题,那就在Styles。xml中加入如下代码: 89 | 90 | ``` 91 | 98 | ``` 99 | 常用的几个标签的意思已经注释。可以通过配置跟多的标签来扩展dialog的样式。 100 | 这样就可以去调用一个dialog了,但是不行,我们要加入Builder模式,于是参考安卓源码后新建内部静态类Builder 101 | 102 | ``` 103 | public static class Builder{ 104 | 105 | private Context context; 106 | private Context context; 107 | private String left; 108 | private String right; 109 | private View.OnClickListener leftOCL; 110 | private View.OnClickListener rightOCL; 111 | private Button leftButton; 112 | private Button rightButton; 113 | 114 | public Builder(Context context){ 115 | this.context=context; 116 | 117 | } 118 | ``` 119 | 指定各种组装配置方法: 120 | 121 | ``` 122 | public Builder setLeftText(String left) { 123 | this.left=left; 124 | return this; 125 | } 126 | public Builder setRightText(String right) { 127 | this.right=right; 128 | return this; 129 | } 130 | public Builder setLeftOnClick(View.OnClickListener left) { 131 | this.leftOCL=left; 132 | return this; 133 | } 134 | public Builder setRightOnClick(View.OnClickListener right) { 135 | this.rightOCL=right; 136 | return this; 137 | } 138 | ``` 139 | 可以看出没个方法都return 了一个Builder方便下次调用。 140 | 141 | Builder类中的create方法最后调用根据前面的配置生成一个airDialog的对象: 142 | ``` 143 | public AirDialog create() { 144 | 145 | final AirDialog airDialog=new AirDialog(context); 146 | 147 | View view = LayoutInflater.from(context).inflate(R.layout.dialog, null); 148 | leftButton=(Button)view.findViewById(R.id.button2); 149 | rightButton=(Button)view.findViewById(R.id.quxiao_btn); 150 | 151 | if (!TextUtils.isEmpty(left)) 152 | leftButton.setText(left); 153 | if (!TextUtils.isEmpty(right)) 154 | rightButton.setText(right); 155 | if (leftOCL!=null) 156 | leftButton.setOnClickListener(leftOCL); 157 | if (rightOCL!=null) 158 | rightButton.setOnClickListener(rightOCL); 159 | 160 | 161 | 162 | Window win = airDialog.getWindow(); 163 | win.getDecorView().setPadding(0, 0, 0, 0); 164 | WindowManager.LayoutParams lp = win.getAttributes(); 165 | lp.width = WindowManager.LayoutParams.MATCH_PARENT; 166 | lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 167 | win.setAttributes(lp); 168 | // win.setGravity(Gravity.NO_GRAVITY); 169 | win.setGravity(Gravity.CENTER); 170 | airDialog.setContentView(view); 171 | airDialog.setCanceledOnTouchOutside(false); 172 | // airDialog.setCancelable(false); 173 | 174 | return airDialog; 175 | 176 | } 177 | 178 | ``` 179 | 可以看出Dialog的现实原理,是在WindowManager的控制下现实出来的: 180 | Window win = airDialog.getWindow(); 181 | win.getDecorView().setPadding(0, 0, 0, 0); 182 | WindowManager.LayoutParams lp = win.getAttributes(); 183 | 184 | Activity像一个工匠(控制单元), 185 | Window像窗户(承载模型), 186 | View像窗花(显示视图) 187 | LayoutInflater像剪刀, 188 | Xml配置像窗花图纸。(大家都这么比喻,不是我发明的) 189 | 清晰的说出了几者关系。 190 | 191 | 最后调用我们的dialog出来吧: 192 | 193 | ``` 194 | if (airDialog == null) 195 | 196 | airDialog = new AirDialog.Builder(this). 197 | setLeftText("gogo"). 198 | setRightText("nono"). 199 | setRightOnClick(new View.OnClickListener() { 200 | @Override 201 | public void onClick(View view) { 202 | airDialog.dismiss(); 203 | Toast.makeText(MainActivity.this, "nono", Toast.LENGTH_SHORT).show(); 204 | } 205 | }). 206 | create(); 207 | 208 | airDialog.show(); 209 | ``` 210 | 是不是很爽呢,自已可以做出这种链了。 211 | 212 | 213 | 214 | 4.自定义Dailog的一些小坑 215 | --------------- 216 | 217 | 218 | 第一次我xml是这样写的: 219 | 220 | ``` 221 | 222 | 229 | 230 | 231 | 240 | 241 |