├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── timmy │ │ └── tdialog │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── timmy │ │ │ └── tdialogdemo │ │ │ ├── MainActivity.java │ │ │ ├── adapter │ │ │ └── SimpleAdapter.java │ │ │ ├── dialogfragment │ │ │ ├── MyAlertDialogFragment.java │ │ │ └── MyDialogFragment.java │ │ │ ├── ui │ │ │ ├── DialogEncapActivity.java │ │ │ ├── DiffentDialogActivity.java │ │ │ ├── NormalDFActivity.java │ │ │ └── SystemDialog.java │ │ │ └── 目标 │ └── res │ │ ├── anim │ │ ├── enter_scale_dialog.xml │ │ ├── enter_translate_dialog.xml │ │ ├── exit_scale_dialog.xml │ │ └── exit_translate_dialog.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_launcher_background.xml │ │ ├── selector_solid_topic.xml │ │ ├── shape_solid_topic.xml │ │ ├── shape_solid_white_10.xml │ │ ├── shape_solid_white_4.xml │ │ └── shape_stroke_gray_99.xml │ │ ├── layout │ │ ├── activity_dialog_encap.xml │ │ ├── activity_diffent_dialog.xml │ │ ├── activity_main.xml │ │ ├── activity_normal_df.xml │ │ ├── activity_system_dialog.xml │ │ ├── dialog_change_avatar.xml │ │ ├── dialog_click.xml │ │ ├── dialog_custom.xml │ │ ├── dialog_evaluate.xml │ │ ├── dialog_home_ad.xml │ │ ├── dialog_loading.xml │ │ ├── dialog_loading_progress.xml │ │ ├── dialog_recycler_test.xml │ │ ├── dialog_share_recycler.xml │ │ ├── dialog_simple.xml │ │ ├── dialog_vb_convert.xml │ │ ├── dialog_version_upgrde.xml │ │ ├── dialog_version_upgrde_strong.xml │ │ ├── fragment_my_dialog.xml │ │ ├── item_share.xml │ │ ├── item_simple_text.xml │ │ └── view_simple_text.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── img_home_ad_close.png │ │ └── img_home_banner.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── timmy │ └── tdialog │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── TDialog-fw.png └── TDialog.gif ├── settings.gradle └── tdialog ├── .gitignore ├── bintrayUpload.gradle ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── timmy │ └── tdialog │ └── ExampleInstrumentedTest.java ├── main ├── AndroidManifest.xml ├── java │ └── com │ │ └── timmy │ │ └── tdialog │ │ ├── TDialog.java │ │ ├── base │ │ ├── BaseDialogFragment.java │ │ ├── BindViewHolder.java │ │ ├── TBaseAdapter.java │ │ └── TController.java │ │ ├── list │ │ └── TListDialog.java │ │ └── listener │ │ ├── OnBindViewListener.java │ │ └── OnViewClickListener.java └── res │ ├── layout │ └── dialog_recycler.xml │ └── values │ └── strings.xml └── test └── java └── com └── timmy └── tdialog └── ExampleUnitTest.java /.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/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### 前言 2 | >文章代码示例已放到Github上了,有需要的朋友可以去看下[TDialog](https://github.com/Timmy-zzh/TDialog),欢迎star和fork,项目会一直维护,有疑问可以提Issues或留言. 3 | ##### 文章目录 4 | * TDialog框架的由来 5 | * 框架使用解析 6 | * 框架原理解析 7 | ###### 正文开始前先来一波效果图 8 | ![](/images/TDialog.gif) 9 | #### 一.TDialog的由来 10 | 所有框架的由来都是为了更方便,更高效的解决问题,TDialog也一样,是为了在项目中更高效的实现项目的弹窗效果 11 | 12 | TDialog是继承自DialogFragment进行封装的,大部分开发者在实现弹窗效果的时候,会首选系统提供的AlertDialog; 13 | 但是使用系统的Dialog在某些情况下会出现问题,最常见的场景是当手机屏幕旋转时Dialog弹窗会消失,并抛出一个系统,这个异常不会导致异常崩溃,因为Google开发者知道这个问题,并进行了处理. 14 | Dialog使用起来其实更简单,但是Google却是推荐尽量使用DialogFragment. 15 | ##### 1.DialogFragment的优点 16 | * DialogFragment 本身是 Fragment 的子类,有着和 Fragment 基本一样的生命周期,使用 DialogFragment 来管理对话框,当旋转屏幕和按下后退键的时候可以更好的管理其生命周期 17 | * 在手机配置变化导致 Activity 需要重新创建时,例如旋转屏幕,基于 DialogFragment 的对话框将会由 FragmentManager 自动重建,然而基于 Dialog 实现的对话框却没有这样的能力 18 | ####使用 19 | 1.添加依赖 20 | a. 在工程build.gradle文件repositories中添加 21 | ``` 22 | repositories { 23 | ... 24 | jcenter() 25 | } 26 | ``` 27 | b.在model下build.gradle文件添加 28 | ``` 29 | implementation 'com.timmy.tdialog:tdialog:2.1.1' 30 | ``` 31 | 2.Activity或者Fragment中使用 32 | ``` 33 | 34 | new TDialog.Builder(getSupportFragmentManager()) 35 | .setLayoutRes(R.layout.dialog_click) //设置弹窗展示的xml布局 36 | // .setDialogView(view) //设置弹窗布局,直接传入View 37 | .setWidth(600) //设置弹窗宽度(px) 38 | .setHeight(800) //设置弹窗高度(px) 39 | .setScreenWidthAspect(this, 0.8f) //设置弹窗宽度(参数aspect为屏幕宽度比例 0 - 1f) 40 | .setScreenHeightAspect(this, 0.3f) //设置弹窗高度(参数aspect为屏幕宽度比例 0 - 1f) 41 | .setGravity(Gravity.CENTER) //设置弹窗展示位置 42 | .setTag("DialogTest") //设置Tag 43 | .setDimAmount(0.6f) //设置弹窗背景透明度(0-1f) 44 | .setCancelableOutside(true) //弹窗在界面外是否可以点击取消 45 | .setDialogAnimationRes(R.style.animate_dialog) //设置弹窗动画 46 | .setOnDismissListener(new DialogInterface.OnDismissListener() { //弹窗隐藏时回调方法 47 | @Override 48 | public void onDismiss(DialogInterface dialog) { 49 | Toast.makeText(DiffentDialogActivity.this, "弹窗消失回调", Toast.LENGTH_SHORT).show(); 50 | } 51 | }) 52 | .setOnBindViewListener(new OnBindViewListener() { //通过BindViewHolder拿到控件对象,进行修改 53 | @Override 54 | public void bindView(BindViewHolder bindViewHolder) { 55 | bindViewHolder.setText(R.id.tv_content, "abcdef"); 56 | bindViewHolder.setText(R.id.tv_title, "我是Title"); 57 | } 58 | }) 59 | .addOnClickListener(R.id.btn_left, R.id.btn_right, R.id.tv_title) //添加进行点击控件的id 60 | .setOnViewClickListener(new OnViewClickListener() { //View控件点击事件回调 61 | @Override 62 | public void onViewClick(BindViewHolder viewHolder, View view, TDialog tDialog) { 63 | switch (view.getId()) { 64 | case R.id.btn_left: 65 | Toast.makeText(DiffentDialogActivity.this, "left clicked", Toast.LENGTH_SHORT).show(); 66 | break; 67 | case R.id.btn_right: 68 | Toast.makeText(DiffentDialogActivity.this, "right clicked", Toast.LENGTH_SHORT).show(); 69 | tDialog.dismiss(); 70 | break; 71 | case R.id.tv_title: 72 | Toast.makeText(DiffentDialogActivity.this, "title clicked", Toast.LENGTH_SHORT).show(); 73 | viewHolder.setText(R.id.tv_title, "Title点击了"); 74 | break; 75 | } 76 | } 77 | }) 78 | .setOnKeyListener(new DialogInterface.OnKeyListener() { 79 | @Override 80 | public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { 81 | return false; 82 | } 83 | }) 84 | .create() //创建TDialog 85 | .show(); //展示 86 | 87 | ``` 88 | 添加动画姿势 89 | ``` 90 | 新建补间动画文件 91 | enter.xml 92 | 93 | 97 | 98 | 99 | exit.xml 100 | 101 | 105 | 106 | 107 | style.xml文件 108 | 112 | ``` 113 | #### 使用方法解析 114 | TDialog的实现原理和系统Dialog原理差不多,主要使用Builder设计模式实现 115 | 1.创建弹窗,传入xml布局文件或者传入View控件,且自己设置背景色,因为默认是透明背景色 116 | ``` 117 | new TDialog.Builder(getSupportFragmentManager()) 118 | .setLayoutRes(R.layout.dialog_click) 119 | .setDialogView(view) 120 | .create() 121 | .show(); 122 | ``` 123 | 2.设置弹窗的宽高(如果不设置宽或者高,默认使用包裹内容的高度) 124 | ``` 125 | new TDialog.Builder(getSupportFragmentManager()) 126 | .setLayoutRes(R.layout.dialog_click) 127 | .setWidth(600) //设置弹窗固定宽度(单位:px) 128 | .setHeight(800)//设置弹窗固定高度 129 | .setScreenWidthAspect(Activity.this,0.5f) //动态设置弹窗宽度为屏幕宽度百分比(取值0-1f) 130 | .setScreenHeightAspect(Activity.this,0.6f)//设置弹窗高度为屏幕高度百分比(取值0-1f) 131 | .create() 132 | .show(); 133 | ``` 134 | 3.设置弹窗展示的位置 135 | ``` 136 | .setGravity(Gravity.CENTER) 137 | 其他位置有:Gravity.Bottom / Gravity.LEFT等等和设置控件位置一样 138 | ``` 139 | 4.设置弹窗背景色透明度(取值0-1f,0为全透明) 140 | ``` 141 | .setDimAmount(0.6f) 142 | ``` 143 | 5.设置弹窗外部是否可以点击取消(默认可点击取消),和设置弹窗是否可以取消(默认可取消),弹窗隐藏时回调方法 144 | ``` 145 | .setCancelableOutside(true) 146 | .setOnDismissListener(new DialogInterface.OnDismissListener() { //弹窗隐藏时回调方法 147 | @Override 148 | public void onDismiss(DialogInterface dialog) { 149 | Toast.makeText(DiffentDialogActivity.this, "弹窗隐藏回调", Toast.LENGTH_SHORT).show(); 150 | } 151 | }) 152 | ``` 153 | 6.当弹窗需要动态改变控件子view内容时,这里借鉴了RecyclerView.Adapter的设计思想,内部封装好一个BindViewHolder 154 | ``` 155 | .setOnBindViewListener(new OnBindViewListener() { 156 | @Override 157 | public void bindView(BindViewHolder bindViewHolder) { 158 | bindViewHolder.setText(R.id.tv_content, "abcdef"); 159 | bindViewHolder.setText(R.id.tv_title,"我是Title"); 160 | } 161 | }) 162 | ``` 163 | 7.监听弹窗子控件的点击事件,内部也是通过BindViewHolder实现 164 | addOnClickListener(ids[])只需要将点击事件控件的id传入,并设置回调接口setOnViewClickListener() 165 | ``` 166 | .addOnClickListener(R.id.btn_right, R.id.tv_title) 167 | .setOnViewClickListener(new OnViewClickListener() { 168 | @Override 169 | public void onViewClick(BindViewHolder viewHolder,View view1, TDialog tDialog) { 170 | switch (view1.getId()) { 171 | case R.id.btn_right: 172 | Toast.makeText(DialogEncapActivity.this, "btn_right", Toast.LENGTH_SHORT).show(); 173 | tDialog.dismiss(); 174 | break; 175 | case R.id.tv_title: 176 | Toast.makeText(DialogEncapActivity.this, "tv_title", Toast.LENGTH_SHORT).show(); 177 | break; 178 | } 179 | } 180 | }) 181 | ``` 182 | 8.设置弹窗动画 183 | ``` 184 | .setDialogAnimationRes(R.style.animate_dialog) 185 | ``` 186 | 9.监听返回键点击事件,需配合setCancelableOutside(false)方法一起使用 187 | ``` 188 | .setOnKeyListener(new DialogInterface.OnKeyListener() { 189 | @Override 190 | public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { 191 | if (keyCode == KeyEvent.KEYCODE_BACK) { 192 | Toast.makeText(DiffentDialogActivity.this, "返回健无效,请强制升级后使用", Toast.LENGTH_SHORT).show(); 193 | return true; 194 | } 195 | return false; //默认返回值 196 | } 197 | }) 198 | ``` 199 | a.列表弹窗-使用TListDialog,TListDialog继承自TDialog,可以使用父类所有的方法,并且扩展列表数据展示丰富setAdapter()和item点击事件回调方法setOnAdapterItemClickListener() 200 | ``` 201 | new TListDialog.Builder(getSupportFragmentManager()) 202 | .setHeight(600) 203 | .setScreenWidthAspect(this, 0.8f) 204 | .setGravity(Gravity.CENTER) 205 | .setAdapter(new TBaseAdapter(R.layout.item_simple_text, Arrays.asList(data)) { 206 | 207 | @Override 208 | protected void onBind(BindViewHolder holder, int position, String s) { 209 | holder.setText(R.id.tv, s); 210 | } 211 | }) 212 | .setOnAdapterItemClickListener(new TBaseAdapter.OnAdapterItemClickListener() { 213 | @Override 214 | public void onItemClick(BindViewHolder holder, int position, String s, TDialog tDialog) { 215 | Toast.makeText(DiffentDialogActivity.this, "click:" + s, Toast.LENGTH_SHORT).show(); 216 | tDialog.dismiss(); 217 | } 218 | }) 219 | .create() 220 | .show(); 221 | ``` 222 | ##### 列表弹窗 223 | 为了方便使用: 224 | 1. 不用传入layoutRes布局文件,TDialog内部设置了一个默认的RecyclerView布局,且RecyclerView的控件id为recycler_view,背景为#ffffff 225 | 2. setAdapter(Adapter),设置recyclerview的adapter,为了封装Adapter的item点击事件,传入的adapter需要为TBaseAdapter的实现类 226 | 3. setOnAdapterItemClickListener(),设置adapter的点击事件 227 | ``` 228 | 229 | 236 | ``` 237 | TBaseAdapter实现:需要使用者传入item的xml布局,和List数据 238 | ``` 239 | public abstract class TBaseAdapter extends RecyclerView.Adapter { 240 | 241 | private final int layoutRes; 242 | private List datas; 243 | private OnAdapterItemClickListener adapterItemClickListener; 244 | private TDialog dialog; 245 | 246 | protected abstract void onBind(BindViewHolder holder, int position, T t); 247 | 248 | public TBaseAdapter(@LayoutRes int layoutRes, List datas) { 249 | this.layoutRes = layoutRes; 250 | this.datas = datas; 251 | } 252 | 253 | @Override 254 | public BindViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 255 | return new BindViewHolder(LayoutInflater.from(parent.getContext()).inflate(layoutRes, parent, false)); 256 | } 257 | 258 | @Override 259 | public void onBindViewHolder(final BindViewHolder holder, final int position) { 260 | onBind(holder, position, datas.get(position)); 261 | holder.itemView.setOnClickListener(new View.OnClickListener() { 262 | @Override 263 | public void onClick(View v) { 264 | adapterItemClickListener.onItemClick(holder, position, datas.get(position), dialog); 265 | } 266 | }); 267 | } 268 | 269 | @Override 270 | public int getItemCount() { 271 | return datas.size(); 272 | } 273 | 274 | public void setTDialog(TDialog tDialog) { 275 | this.dialog = tDialog; 276 | } 277 | 278 | public interface OnAdapterItemClickListener { 279 | void onItemClick(BindViewHolder holder, int position, T t, TDialog tDialog); 280 | } 281 | 282 | public void setOnAdapterItemClickListener(OnAdapterItemClickListener listener) { 283 | this.adapterItemClickListener = listener; 284 | } 285 | } 286 | ``` 287 | ##### 如果使用者需要使用自己的列表布局时,可以使用setListLayoutRes(layotuRes,LayoutManager)方法设置xml布局和布局管理器LayoutManager,切记xml布局中的RecyclerView的id必须设置为recycler_view(如效果图中的分享弹窗) 288 | ``` 289 | //底部分享 290 | public void shareDialog(View view) { 291 | new TListDialog.Builder(getSupportFragmentManager()) 292 | .setListLayoutRes(R.layout.dialog_share_recycler, LinearLayoutManager.HORIZONTAL) 293 | .setScreenWidthAspect(this, 1.0f) 294 | .setGravity(Gravity.BOTTOM) 295 | .setAdapter(new TBaseAdapter(R.layout.item_share, Arrays.asList(sharePlatform)) { 296 | @Override 297 | protected void onBind(BindViewHolder holder, int position, String s) { 298 | holder.setText(R.id.tv, s); 299 | } 300 | }) 301 | .setOnAdapterItemClickListener(new TBaseAdapter.OnAdapterItemClickListener() { 302 | @Override 303 | public void onItemClick(BindViewHolder holder, int position, String item, TDialog tDialog) { 304 | Toast.makeText(DiffentDialogActivity.this, item, Toast.LENGTH_SHORT).show(); 305 | tDialog.dismiss(); 306 | } 307 | }) 308 | .create() 309 | .show(); 310 | } 311 | ``` 312 | 自定义列表布局 313 | ``` 314 | 315 | 321 | 322 | 332 | 333 | 340 | 341 | 342 | ``` 343 | #### 框架原理解析 344 | TDialog的实现原理主要分为三步 345 | 1. 实例化TDialog.Builer对象builder,然后调用各种setXXX()方法设置数据,设置的数据都保存在TController.TParams实例中 346 | 2. create()方法调用后才会实例化TDialog对象,并将TController.TParams中设置的数据传递到TDialog的属性TController对象中 347 | 3. show()方法调用显示弹窗 348 | 4. UML调用时序图 349 | ![](/images/TDialog-fw.png) 350 | #### 项目github地址:https://github.com/Timmy-zzh/TDialog 351 | 352 | ##### 版本历史 353 | ``` 354 | 2.1.1版本: 355 | 添加返回键事件监听 356 | show()方法添加容错处理 357 | 358 | 2.0.0版本: 359 | 添加弹窗动画 360 | 修复show()方法调用时bug 361 | 去除setCancelable()方法 362 | 363 | 1.3.1版本: 364 | 添加弹窗隐藏时回调监听方法:setOnDismissListener() 365 | 366 | 1.3.0版本: 367 | 处理setCancelable()方法,禁止弹窗点击取消 368 | 弹窗内容直接传入View: setDialogView() 369 | 370 | 1.2.0版本: 371 | 分离出列表弹窗TListDialog 372 | 解决弹窗按Home键时出现的bug 373 | 374 | 1.1.0版本: 添加点击事件封装回调方法 375 | addOnClickListener() 376 | setOnViewClickListener() 377 | 378 | 1.0.0版本: 弹窗实现基本功能 379 | OnBindViewListener 380 | ``` -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 27 5 | defaultConfig { 6 | applicationId "com.timmy.tdialog" 7 | minSdkVersion 15 8 | targetSdkVersion 27 9 | versionCode 211 10 | versionName "2.1.1" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(dir: 'libs', include: ['*.jar']) 23 | implementation 'com.android.support:appcompat-v7:27.1.1' 24 | implementation 'com.android.support:support-v4:27.1.1' 25 | 26 | implementation 'com.android.support:support-v4:27.1.1' 27 | implementation 'com.android.support:recyclerview-v7:27.1.1' 28 | 29 | implementation 'com.android.support.constraint:constraint-layout:1.1.2' 30 | testImplementation 'junit:junit:4.12' 31 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 32 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 33 | implementation project(':tdialog') 34 | } 35 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/timmy/tdialog/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.timmy.tdialog; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.timmy.tdialog", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/timmy/tdialogdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.timmy.tdialogdemo; 2 | 3 | import android.content.Intent; 4 | import android.os.Handler; 5 | import android.os.HandlerThread; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.view.Gravity; 9 | import android.view.View; 10 | import android.widget.FrameLayout; 11 | import android.widget.LinearLayout; 12 | import android.widget.TextView; 13 | import android.widget.Toast; 14 | 15 | import com.timmy.tdialog.TDialog; 16 | import com.timmy.tdialog.base.BindViewHolder; 17 | import com.timmy.tdialog.listener.OnBindViewListener; 18 | import com.timmy.tdialog.listener.OnViewClickListener; 19 | import com.timmy.tdialogdemo.ui.DialogEncapActivity; 20 | import com.timmy.tdialogdemo.ui.DiffentDialogActivity; 21 | import com.timmy.tdialogdemo.ui.NormalDFActivity; 22 | import com.timmy.tdialogdemo.ui.SystemDialog; 23 | 24 | public class MainActivity extends AppCompatActivity { 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | setContentView(R.layout.activity_main); 30 | } 31 | 32 | /** 33 | * 系统Dialog使用 34 | * 35 | * @param view 36 | */ 37 | public void systemDialog(View view) { 38 | startActivity(new Intent(this, SystemDialog.class)); 39 | } 40 | 41 | /** 42 | * DialogFragment的使用 43 | * 44 | * @param view 45 | */ 46 | public void NormalDF(View view) { 47 | startActivity(new Intent(this, NormalDFActivity.class)); 48 | } 49 | 50 | /** 51 | * DialogFragment封装 52 | * 53 | * @param view 54 | */ 55 | public void DialogEncap(View view) { 56 | startActivity(new Intent(this, DialogEncapActivity.class)); 57 | } 58 | 59 | /** 60 | * 常用的各种Dialog 61 | * 62 | * @param view 63 | */ 64 | public void diffentDialog(View view) { 65 | startActivity(new Intent(this, DiffentDialogActivity.class)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/timmy/tdialogdemo/adapter/SimpleAdapter.java: -------------------------------------------------------------------------------- 1 | package com.timmy.tdialogdemo.adapter; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.TextView; 8 | 9 | import com.timmy.tdialogdemo.R; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** 15 | * Created by Timmy on 2017/12/18. 16 | */ 17 | 18 | public class SimpleAdapter extends RecyclerView.Adapter { 19 | 20 | private List mData; 21 | 22 | public SimpleAdapter(List mData) { 23 | this.mData = mData == null ? new ArrayList() : mData; 24 | } 25 | 26 | @Override 27 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 28 | View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_simple_text, parent, false); 29 | return new ViewHolder(view); 30 | } 31 | 32 | @Override 33 | public void onBindViewHolder(ViewHolder holder, int position) { 34 | String item = mData.get(position); 35 | holder.textView.setText(item); 36 | } 37 | 38 | @Override 39 | public int getItemCount() { 40 | return mData.size(); 41 | } 42 | 43 | public class ViewHolder extends RecyclerView.ViewHolder { 44 | 45 | public TextView textView; 46 | 47 | public ViewHolder(View itemView) { 48 | super(itemView); 49 | textView = itemView.findViewById(R.id.tv); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/timmy/tdialogdemo/dialogfragment/MyAlertDialogFragment.java: -------------------------------------------------------------------------------- 1 | package com.timmy.tdialogdemo.dialogfragment; 2 | 3 | import android.app.Dialog; 4 | import android.content.DialogInterface; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.v4.app.DialogFragment; 8 | import android.support.v7.app.AlertDialog; 9 | import android.util.Log; 10 | 11 | import com.timmy.tdialogdemo.R; 12 | 13 | /** 14 | * 采用返回Dialog的方式处理 15 | */ 16 | public class MyAlertDialogFragment extends DialogFragment { 17 | public static final String TAG = MyDialogFragment.class.getName(); 18 | 19 | public static MyAlertDialogFragment newInstance(String title) { 20 | MyAlertDialogFragment frag = new MyAlertDialogFragment(); 21 | Bundle args = new Bundle(); 22 | args.putString("title", title); 23 | frag.setArguments(args); 24 | return frag; 25 | } 26 | 27 | @NonNull 28 | @Override 29 | public Dialog onCreateDialog(Bundle savedInstanceState) { 30 | String title = getArguments().getString("title"); 31 | 32 | return new AlertDialog.Builder(getActivity()) 33 | .setIcon(R.mipmap.ic_launcher_round) 34 | .setTitle(title) 35 | .setPositiveButton("确定", 36 | new DialogInterface.OnClickListener() { 37 | public void onClick(DialogInterface dialog, int whichButton) { 38 | Log.d(TAG, "setPositiveButton"); 39 | } 40 | } 41 | ) 42 | .setNegativeButton("取消", 43 | new DialogInterface.OnClickListener() { 44 | public void onClick(DialogInterface dialog, int whichButton) { 45 | Log.d(TAG, "setNegativeButton"); 46 | } 47 | } 48 | ) 49 | .create(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/timmy/tdialogdemo/dialogfragment/MyDialogFragment.java: -------------------------------------------------------------------------------- 1 | package com.timmy.tdialogdemo.dialogfragment; 2 | 3 | 4 | import android.app.Dialog; 5 | import android.os.Bundle; 6 | import android.support.annotation.NonNull; 7 | import android.support.annotation.Nullable; 8 | import android.support.v4.app.DialogFragment; 9 | import android.util.Log; 10 | import android.view.LayoutInflater; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.Button; 14 | import android.widget.TextView; 15 | 16 | import com.timmy.tdialogdemo.R; 17 | 18 | /** 19 | * 使用onCreateView返回Dialog的界面布局 20 | */ 21 | public class MyDialogFragment extends DialogFragment { 22 | 23 | public static final String TAG = MyDialogFragment.class.getName(); 24 | 25 | /** 26 | * 实例化,并传递数据 27 | */ 28 | public static MyDialogFragment getInstance(int num) { 29 | MyDialogFragment dialogFragment = new MyDialogFragment(); 30 | Bundle bundle = new Bundle(); 31 | bundle.putInt("num", num); 32 | dialogFragment.setArguments(bundle); 33 | return dialogFragment; 34 | } 35 | 36 | @Override 37 | public void onCreate(@Nullable Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | // int num = getArguments().getInt("num"); 40 | // Log.d(TAG, "onCreate num:" + num); 41 | // //设置style类型 42 | // // Pick a style based on the num. 43 | // int style = DialogFragment.STYLE_NORMAL, theme = 0; 44 | // Log.d(TAG, "(num - 1) % 6:" + ((num - 1) % 6)); 45 | // switch ((num - 1) % 6) { 46 | // case 1: 47 | // style = DialogFragment.STYLE_NO_TITLE; 48 | // break; 49 | // case 2: 50 | // style = DialogFragment.STYLE_NO_FRAME; 51 | // break; 52 | // case 3: 53 | // style = DialogFragment.STYLE_NO_INPUT; 54 | // break; 55 | // } 56 | // switch ((num - 1) % 6) { 57 | // case 1: 58 | // theme = android.R.style.Theme_Holo; 59 | // break; 60 | // case 2: 61 | // theme = android.R.style.Theme_Holo_Light_Dialog; 62 | // break; 63 | // case 3: 64 | // theme = android.R.style.Theme_Holo_Light; 65 | // break; 66 | // } 67 | // setStyle(style, theme); 68 | 69 | } 70 | 71 | @NonNull 72 | @Override 73 | public Dialog onCreateDialog(Bundle savedInstanceState) { 74 | return super.onCreateDialog(savedInstanceState); 75 | } 76 | 77 | @Nullable 78 | @Override 79 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 80 | Log.d(TAG, "onCreateView"); 81 | View view = inflater.inflate(R.layout.fragment_my_dialog, container, false); 82 | TextView textView = view.findViewById(R.id.tv); 83 | textView.setText("DialogFragment"); 84 | Button button = view.findViewById(R.id.btn); 85 | button.setOnClickListener(new View.OnClickListener() { 86 | @Override 87 | public void onClick(View v) { 88 | Log.d(TAG,"onClick"); 89 | // ((NormalDFActivity) getActivity()).showDialogFragment(null); 90 | } 91 | }); 92 | return view; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/timmy/tdialogdemo/ui/DialogEncapActivity.java: -------------------------------------------------------------------------------- 1 | package com.timmy.tdialogdemo.ui; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.Gravity; 6 | import android.view.View; 7 | import android.widget.Toast; 8 | 9 | import com.timmy.tdialog.TDialog; 10 | import com.timmy.tdialog.base.BindViewHolder; 11 | import com.timmy.tdialog.base.TBaseAdapter; 12 | import com.timmy.tdialog.list.TListDialog; 13 | import com.timmy.tdialog.listener.OnBindViewListener; 14 | import com.timmy.tdialog.listener.OnViewClickListener; 15 | import com.timmy.tdialogdemo.R; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | /** 21 | * DialogFragment封装 22 | */ 23 | public class DialogEncapActivity extends AppCompatActivity { 24 | 25 | @Override 26 | protected void onCreate(Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | setContentView(R.layout.activity_dialog_encap); 29 | } 30 | 31 | /** 32 | * 展示Dialog 33 | */ 34 | public void showTDialog(View view) { 35 | new TDialog.Builder(getSupportFragmentManager()) 36 | .setLayoutRes(R.layout.dialog_click) 37 | .setScreenWidthAspect(DialogEncapActivity.this, 0.8f) 38 | .setTag("DialogTest") 39 | .setDimAmount(0.6f) 40 | .setGravity(Gravity.CENTER) 41 | .setOnBindViewListener(new OnBindViewListener() { 42 | @Override 43 | public void bindView(BindViewHolder bindViewHolder) { 44 | bindViewHolder.setText(R.id.tv_content, "abcdef"); 45 | } 46 | }) 47 | .addOnClickListener(R.id.btn_right, R.id.tv_title) 48 | .setOnViewClickListener(new OnViewClickListener() { 49 | @Override 50 | public void onViewClick(BindViewHolder viewHolder, View view1, TDialog tDialog) { 51 | switch (view1.getId()) { 52 | case R.id.btn_right: 53 | Toast.makeText(DialogEncapActivity.this, "btn_right", Toast.LENGTH_SHORT).show(); 54 | tDialog.dismiss(); 55 | break; 56 | case R.id.tv_title: 57 | Toast.makeText(DialogEncapActivity.this, "tv_title", Toast.LENGTH_SHORT).show(); 58 | break; 59 | } 60 | } 61 | }) 62 | .create() 63 | .show(); 64 | } 65 | 66 | public void showTListDialog(View view) { 67 | List datas = new ArrayList<>(); 68 | for (int i = 0; i < 10; i++) { 69 | datas.add("item:" + i); 70 | } 71 | 72 | TListDialog.Builder builder = new TListDialog.Builder(getSupportFragmentManager()); 73 | builder.setLayoutRes(R.layout.dialog_recycler_test); 74 | builder.setHeight(600); 75 | builder.setScreenWidthAspect(DialogEncapActivity.this, 1.0f); 76 | builder.setAdapter(new TBaseAdapter(R.layout.item_simple_text, datas) { 77 | @Override 78 | protected void onBind(BindViewHolder holder, int position, String item) { 79 | holder.setText(R.id.tv, item); 80 | } 81 | }); 82 | builder.setOnAdapterItemClickListener(new TBaseAdapter.OnAdapterItemClickListener() { 83 | @Override 84 | public void onItemClick(BindViewHolder holder, int position, Object o, TDialog tDialog) { 85 | String item = (String) o; 86 | Toast.makeText(DialogEncapActivity.this, "pos:" + position + "," + item, Toast.LENGTH_SHORT).show(); 87 | tDialog.dismiss(); 88 | } 89 | }); 90 | builder.setGravity(Gravity.BOTTOM); 91 | 92 | TDialog tListDialog = builder.create(); 93 | tListDialog.show(); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/com/timmy/tdialogdemo/ui/DiffentDialogActivity.java: -------------------------------------------------------------------------------- 1 | package com.timmy.tdialogdemo.ui; 2 | 3 | import android.content.Context; 4 | import android.content.DialogInterface; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.os.Message; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.support.v7.widget.LinearLayoutManager; 10 | import android.view.Gravity; 11 | import android.view.KeyEvent; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.view.inputmethod.InputMethodManager; 16 | import android.widget.EditText; 17 | import android.widget.ProgressBar; 18 | import android.widget.TextView; 19 | import android.widget.Toast; 20 | 21 | import com.timmy.tdialog.TDialog; 22 | import com.timmy.tdialog.base.BindViewHolder; 23 | import com.timmy.tdialog.base.TBaseAdapter; 24 | import com.timmy.tdialog.list.TListDialog; 25 | import com.timmy.tdialog.listener.OnBindViewListener; 26 | import com.timmy.tdialog.listener.OnViewClickListener; 27 | import com.timmy.tdialogdemo.R; 28 | 29 | import java.util.Arrays; 30 | 31 | /** 32 | * 常用的各种Dialog 33 | */ 34 | public class DiffentDialogActivity extends AppCompatActivity { 35 | 36 | private static final String TAG = "TDialog"; 37 | private static final int WHAT_LOADING = 0; 38 | private static final int WHAT_PROGRESS = 1; 39 | private String[] data = {"java", "android", "NDK", "c++", "python", "ios", "Go", "Unity3D", "Kotlin", "Swift", "js"}; 40 | private String[] sharePlatform = {"微信", "朋友圈", "短信", "微博", "QQ空间", "Google", "FaceBook", "微信", "朋友圈", "短信", "微博", "QQ空间"}; 41 | private TDialog tDialog; 42 | int currProgress = 5; 43 | private ProgressBar progressBar; 44 | private TextView tvProgress; 45 | 46 | 47 | private Handler handler = new Handler() { 48 | @Override 49 | public void handleMessage(Message msg) { 50 | switch (msg.what) { 51 | case WHAT_LOADING: 52 | if (tDialog != null) { 53 | tDialog.dismiss(); 54 | } 55 | return; 56 | 57 | case WHAT_PROGRESS: 58 | currProgress += 5; 59 | progressBar.setProgress(currProgress); 60 | tvProgress.setText("progress:" + currProgress + "/100"); 61 | if (tDialog != null && currProgress >= 100) { 62 | currProgress = 0; 63 | tDialog.dismiss(); 64 | tDialog = null; 65 | } else { 66 | handler.sendEmptyMessageDelayed(WHAT_PROGRESS, 1000); 67 | } 68 | return; 69 | } 70 | } 71 | }; 72 | 73 | @Override 74 | protected void onCreate(Bundle savedInstanceState) { 75 | super.onCreate(savedInstanceState); 76 | setContentView(R.layout.activity_diffent_dialog); 77 | } 78 | 79 | public void testDialog(View view2) { 80 | View view = LayoutInflater.from(this).inflate(R.layout.dialog_loading, null); 81 | tDialog = new TDialog.Builder(getSupportFragmentManager()) 82 | .setDialogView(view) 83 | .setCancelableOutside(false) 84 | .setOnKeyListener(new DialogInterface.OnKeyListener() { 85 | @Override 86 | public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { 87 | Toast.makeText(DiffentDialogActivity.this, "keyCode:" + keyCode, Toast.LENGTH_SHORT).show(); 88 | if (keyCode == KeyEvent.KEYCODE_BACK) { 89 | 90 | return true; 91 | } 92 | return false; 93 | } 94 | }) 95 | .create(); 96 | tDialog.show(); 97 | } 98 | 99 | public void useTDialog(View view) { 100 | new TDialog.Builder(getSupportFragmentManager()) 101 | .setLayoutRes(R.layout.dialog_click) //设置弹窗展示的xml布局 102 | // .setDialogView(view) //设置弹窗布局,直接传入View 103 | .setWidth(600) //设置弹窗宽度(px) 104 | .setHeight(800) //设置弹窗高度(px) 105 | .setScreenWidthAspect(this, 0.8f) //设置弹窗宽度(参数aspect为屏幕宽度比例 0 - 1f) 106 | .setScreenHeightAspect(this, 0.3f) //设置弹窗高度(参数aspect为屏幕宽度比例 0 - 1f) 107 | .setGravity(Gravity.CENTER) //设置弹窗展示位置 108 | .setTag("DialogTest") //设置Tag 109 | .setDimAmount(0.6f) //设置弹窗背景透明度(0-1f) 110 | .setCancelableOutside(true) //弹窗在界面外是否可以点击取消 111 | .setDialogAnimationRes(R.style.animate_dialog) //设置弹窗动画 112 | .setOnDismissListener(new DialogInterface.OnDismissListener() { //弹窗隐藏时回调方法 113 | @Override 114 | public void onDismiss(DialogInterface dialog) { 115 | Toast.makeText(DiffentDialogActivity.this, "弹窗消失回调", Toast.LENGTH_SHORT).show(); 116 | } 117 | }) 118 | .setOnBindViewListener(new OnBindViewListener() { //通过BindViewHolder拿到控件对象,进行修改 119 | @Override 120 | public void bindView(BindViewHolder bindViewHolder) { 121 | bindViewHolder.setText(R.id.tv_content, "abcdef"); 122 | bindViewHolder.setText(R.id.tv_title, "我是Title"); 123 | } 124 | }) 125 | .addOnClickListener(R.id.btn_left, R.id.btn_right, R.id.tv_title) //添加进行点击控件的id 126 | .setOnViewClickListener(new OnViewClickListener() { //View控件点击事件回调 127 | @Override 128 | public void onViewClick(BindViewHolder viewHolder, View view, TDialog tDialog) { 129 | switch (view.getId()) { 130 | case R.id.btn_left: 131 | Toast.makeText(DiffentDialogActivity.this, "left clicked", Toast.LENGTH_SHORT).show(); 132 | break; 133 | case R.id.btn_right: 134 | Toast.makeText(DiffentDialogActivity.this, "right clicked", Toast.LENGTH_SHORT).show(); 135 | tDialog.dismiss(); 136 | break; 137 | case R.id.tv_title: 138 | Toast.makeText(DiffentDialogActivity.this, "title clicked", Toast.LENGTH_SHORT).show(); 139 | viewHolder.setText(R.id.tv_title, "Title点击了"); 140 | break; 141 | } 142 | } 143 | }) 144 | .setOnKeyListener(new DialogInterface.OnKeyListener() { 145 | @Override 146 | public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { 147 | Toast.makeText(DiffentDialogActivity.this, "按键 keyCode:" + keyCode, Toast.LENGTH_SHORT).show(); 148 | return false; 149 | } 150 | }) 151 | .create() //创建TDialog 152 | .show(); //展示 153 | } 154 | 155 | public void upgradeDialog(View view) { 156 | new TDialog.Builder(getSupportFragmentManager()) 157 | .setLayoutRes(R.layout.dialog_version_upgrde) 158 | .setScreenWidthAspect(this, 0.7f) 159 | .addOnClickListener(R.id.tv_cancel, R.id.tv_confirm) 160 | .setDialogAnimationRes(R.style.animate_dialog_scale) 161 | .setOnViewClickListener(new OnViewClickListener() { 162 | @Override 163 | public void onViewClick(BindViewHolder viewHolder, View view, TDialog tDialog) { 164 | switch (view.getId()) { 165 | case R.id.tv_cancel: 166 | tDialog.dismiss(); 167 | break; 168 | case R.id.tv_confirm: 169 | Toast.makeText(DiffentDialogActivity.this, "开始下载新版本apk文件", Toast.LENGTH_SHORT).show(); 170 | tDialog.dismiss(); 171 | break; 172 | } 173 | } 174 | }) 175 | .create() 176 | .show(); 177 | } 178 | 179 | public void upgradeDialogStrong(View view) { 180 | new TDialog.Builder(getSupportFragmentManager()) 181 | .setLayoutRes(R.layout.dialog_version_upgrde_strong) 182 | .setScreenWidthAspect(this, 0.7f) 183 | .addOnClickListener(R.id.tv_confirm) 184 | .setCancelableOutside(false) 185 | .setDialogAnimationRes(R.style.animate_dialog_scale) 186 | .setOnKeyListener(new DialogInterface.OnKeyListener() { 187 | @Override 188 | public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { 189 | if (keyCode == KeyEvent.KEYCODE_BACK) { 190 | Toast.makeText(DiffentDialogActivity.this, "返回健无效,请强制升级后使用", Toast.LENGTH_SHORT).show(); 191 | return true; 192 | } 193 | return false; 194 | } 195 | }) 196 | .setOnViewClickListener(new OnViewClickListener() { 197 | @Override 198 | public void onViewClick(BindViewHolder viewHolder, View view, TDialog tDialog) { 199 | Toast.makeText(DiffentDialogActivity.this, "开始下载新版本apk文件", Toast.LENGTH_SHORT).show(); 200 | } 201 | }) 202 | .create() 203 | .show(); 204 | } 205 | 206 | public void tipsDialog(View view) { 207 | new TDialog.Builder(getSupportFragmentManager()) 208 | .setLayoutRes(R.layout.dialog_vb_convert) 209 | .setScreenWidthAspect(this, 0.85f) 210 | .setCancelableOutside(false) 211 | .addOnClickListener(R.id.tv_jiuyuan_desc, R.id.tv_cancel, R.id.tv_confirm) 212 | .setOnViewClickListener(new OnViewClickListener() { 213 | @Override 214 | public void onViewClick(BindViewHolder viewHolder, View view, TDialog tDialog) { 215 | switch (view.getId()) { 216 | case R.id.tv_jiuyuan_desc: 217 | Toast.makeText(DiffentDialogActivity.this, "进入说明界面", Toast.LENGTH_SHORT).show(); 218 | break; 219 | case R.id.tv_cancel: 220 | tDialog.dismiss(); 221 | break; 222 | case R.id.tv_confirm: 223 | Toast.makeText(DiffentDialogActivity.this, "执行优惠券兑换逻辑", Toast.LENGTH_SHORT).show(); 224 | tDialog.dismiss(); 225 | break; 226 | } 227 | } 228 | }) 229 | .create() 230 | .show(); 231 | } 232 | 233 | public void loadingDialog(View view) { 234 | tDialog = new TDialog.Builder(getSupportFragmentManager()) 235 | .setLayoutRes(R.layout.dialog_loading) 236 | .setHeight(300) 237 | .setWidth(300) 238 | .setCancelableOutside(false) 239 | .create() 240 | .show(); 241 | handler.sendEmptyMessageDelayed(WHAT_LOADING, 5 * 1000); 242 | } 243 | 244 | public void progressDialog(final View view) { 245 | tDialog = new TDialog.Builder(getSupportFragmentManager()) 246 | .setLayoutRes(R.layout.dialog_loading_progress) 247 | .setScreenWidthAspect(this, 0.8f) 248 | .setCancelableOutside(true) 249 | .setOnBindViewListener(new OnBindViewListener() { 250 | @Override 251 | public void bindView(BindViewHolder viewHolder) { 252 | progressBar = viewHolder.getView(R.id.progress_bar); 253 | tvProgress = viewHolder.getView(R.id.tv_progress); 254 | } 255 | }) 256 | .setOnDismissListener(new DialogInterface.OnDismissListener() { 257 | @Override 258 | public void onDismiss(DialogInterface dialog) { 259 | handler.removeMessages(WHAT_PROGRESS); 260 | currProgress = 5; 261 | } 262 | }) 263 | .create() 264 | .show(); 265 | handler.sendEmptyMessageDelayed(WHAT_PROGRESS, 1000); 266 | } 267 | 268 | public void dialogView(View view) { 269 | TextView textView = new TextView(this); 270 | textView.setText("DialogView"); 271 | textView.setTextSize(25); 272 | textView.setTextColor(getResources().getColor(android.R.color.holo_red_dark)); 273 | textView.setBackgroundColor(getResources().getColor(android.R.color.holo_green_dark)); 274 | 275 | tDialog = new TDialog.Builder(getSupportFragmentManager()) 276 | .setLayoutRes(R.layout.dialog_loading) 277 | .setDialogView(textView) 278 | .setHeight(400) 279 | .setWidth(600) 280 | .setCancelableOutside(true) 281 | .create() 282 | .show(); 283 | } 284 | 285 | public void homeBannerDialog(View view) { 286 | new TDialog.Builder(getSupportFragmentManager()) 287 | .setLayoutRes(R.layout.dialog_home_ad) 288 | .setScreenHeightAspect(this, 0.7f) 289 | .setScreenWidthAspect(this, 0.8f) 290 | .setOnBindViewListener(new OnBindViewListener() { 291 | @Override 292 | public void bindView(BindViewHolder viewHolder) { 293 | //可对图片进行修改 294 | } 295 | }) 296 | .addOnClickListener(R.id.iv_close) 297 | .setOnViewClickListener(new OnViewClickListener() { 298 | @Override 299 | public void onViewClick(BindViewHolder viewHolder, View view, TDialog tDialog) { 300 | tDialog.dismiss(); 301 | } 302 | }) 303 | .create() 304 | .show(); 305 | } 306 | 307 | public void updateHead(View view) { 308 | new TDialog.Builder(getSupportFragmentManager()) 309 | .setLayoutRes(R.layout.dialog_change_avatar) 310 | .setScreenWidthAspect(this, 1.0f) 311 | .setGravity(Gravity.BOTTOM) 312 | .setDialogAnimationRes(R.style.animate_dialog) 313 | .addOnClickListener(R.id.tv_open_camera, R.id.tv_open_album, R.id.tv_cancel) 314 | .setOnViewClickListener(new OnViewClickListener() { 315 | @Override 316 | public void onViewClick(BindViewHolder viewHolder, View view, TDialog tDialog) { 317 | switch (view.getId()) { 318 | case R.id.tv_open_camera: 319 | Toast.makeText(DiffentDialogActivity.this, "打开相机", Toast.LENGTH_SHORT).show(); 320 | tDialog.dismiss(); 321 | break; 322 | case R.id.tv_open_album: 323 | Toast.makeText(DiffentDialogActivity.this, "打开相册", Toast.LENGTH_SHORT).show(); 324 | tDialog.dismiss(); 325 | break; 326 | case R.id.tv_cancel: 327 | 328 | tDialog.dismiss(); 329 | break; 330 | } 331 | } 332 | }) 333 | .create() 334 | .show(); 335 | } 336 | 337 | public void listDialog(View view) { 338 | new TListDialog.Builder(getSupportFragmentManager()) 339 | .setHeight(600) 340 | .setScreenWidthAspect(this, 0.8f) 341 | .setGravity(Gravity.CENTER) 342 | .setAdapter(new TBaseAdapter(R.layout.item_simple_text, Arrays.asList(data)) { 343 | 344 | @Override 345 | protected void onBind(BindViewHolder holder, int position, String s) { 346 | holder.setText(R.id.tv, s); 347 | } 348 | }) 349 | .setOnAdapterItemClickListener(new TBaseAdapter.OnAdapterItemClickListener() { 350 | @Override 351 | public void onItemClick(BindViewHolder holder, int position, String s, TDialog tDialog) { 352 | Toast.makeText(DiffentDialogActivity.this, "click:" + s, Toast.LENGTH_SHORT).show(); 353 | tDialog.dismiss(); 354 | } 355 | }) 356 | .create() 357 | .show(); 358 | } 359 | 360 | public void bottomListDialog(View view) { 361 | new TListDialog.Builder(getSupportFragmentManager()) 362 | .setScreenHeightAspect(this, 0.5f) 363 | .setScreenWidthAspect(this, 1.0f) 364 | .setGravity(Gravity.BOTTOM) 365 | .setAdapter(new TBaseAdapter(R.layout.item_simple_text, Arrays.asList(data)) { 366 | @Override 367 | protected void onBind(BindViewHolder holder, int position, String s) { 368 | holder.setText(R.id.tv, s); 369 | } 370 | }) 371 | .setOnAdapterItemClickListener(new TBaseAdapter.OnAdapterItemClickListener() { 372 | @Override 373 | public void onItemClick(BindViewHolder holder, int position, String s, TDialog tDialog) { 374 | Toast.makeText(DiffentDialogActivity.this, "click:" + s, Toast.LENGTH_SHORT).show(); 375 | tDialog.dismiss(); 376 | } 377 | }) 378 | .setOnDismissListener(new DialogInterface.OnDismissListener() { 379 | @Override 380 | public void onDismiss(DialogInterface dialog) { 381 | Toast.makeText(DiffentDialogActivity.this, "setOnDismissListener 回调", Toast.LENGTH_SHORT).show(); 382 | } 383 | }) 384 | .create() 385 | .show(); 386 | } 387 | 388 | //评价 弹出输入框 389 | public void evaluateDialog(View view) { 390 | new TDialog.Builder(getSupportFragmentManager()) 391 | .setLayoutRes(R.layout.dialog_evaluate) 392 | .setScreenWidthAspect(this, 1.0f) 393 | .setGravity(Gravity.BOTTOM) 394 | .addOnClickListener(R.id.btn_evluate) 395 | .setOnBindViewListener(new OnBindViewListener() { 396 | @Override 397 | public void bindView(BindViewHolder viewHolder) { 398 | final EditText editText = viewHolder.getView(R.id.editText); 399 | editText.post(new Runnable() { 400 | @Override 401 | public void run() { 402 | InputMethodManager imm = (InputMethodManager) DiffentDialogActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE); 403 | imm.showSoftInput(editText, 0); 404 | } 405 | }); 406 | } 407 | }) 408 | .setOnViewClickListener(new OnViewClickListener() { 409 | @Override 410 | public void onViewClick(BindViewHolder viewHolder, View view, TDialog tDialog) { 411 | EditText editText = viewHolder.getView(R.id.editText); 412 | String content = editText.getText().toString().trim(); 413 | Toast.makeText(DiffentDialogActivity.this, "评价内容:" + content, Toast.LENGTH_SHORT).show(); 414 | tDialog.dismiss(); 415 | } 416 | }) 417 | .create() 418 | .show(); 419 | } 420 | 421 | //底部分享 422 | public void shareDialog(View view) { 423 | new TListDialog.Builder(getSupportFragmentManager()) 424 | .setListLayoutRes(R.layout.dialog_share_recycler, LinearLayoutManager.HORIZONTAL) 425 | .setScreenWidthAspect(this, 1.0f) 426 | .setGravity(Gravity.BOTTOM) 427 | .setAdapter(new TBaseAdapter(R.layout.item_share, Arrays.asList(sharePlatform)) { 428 | @Override 429 | protected void onBind(BindViewHolder holder, int position, String s) { 430 | holder.setText(R.id.tv, s); 431 | } 432 | }) 433 | .setOnAdapterItemClickListener(new TBaseAdapter.OnAdapterItemClickListener() { 434 | @Override 435 | public void onItemClick(BindViewHolder holder, int position, String item, TDialog tDialog) { 436 | Toast.makeText(DiffentDialogActivity.this, item, Toast.LENGTH_SHORT).show(); 437 | tDialog.dismiss(); 438 | } 439 | }) 440 | .create() 441 | .show(); 442 | } 443 | 444 | } 445 | -------------------------------------------------------------------------------- /app/src/main/java/com/timmy/tdialogdemo/ui/NormalDFActivity.java: -------------------------------------------------------------------------------- 1 | package com.timmy.tdialogdemo.ui; 2 | 3 | import android.support.v4.app.DialogFragment; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentTransaction; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.view.MenuItem; 9 | import android.view.View; 10 | 11 | import com.timmy.tdialogdemo.R; 12 | import com.timmy.tdialogdemo.dialogfragment.MyAlertDialogFragment; 13 | import com.timmy.tdialogdemo.dialogfragment.MyDialogFragment; 14 | 15 | /** 16 | * DialogFragment的使用 17 | */ 18 | public class NormalDFActivity extends AppCompatActivity { 19 | int mStackLevel = 0; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_normal_df); 25 | if (getSupportActionBar() != null) { 26 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 27 | getSupportActionBar().setDisplayShowHomeEnabled(true); 28 | } 29 | } 30 | 31 | @Override 32 | public boolean onOptionsItemSelected(MenuItem item) { 33 | if (item.getItemId() == android.R.id.home) { 34 | onBackPressed(); 35 | return true; 36 | } 37 | return super.onOptionsItemSelected(item); 38 | } 39 | 40 | public void showDialogFragment(View view) { 41 | mStackLevel++; 42 | // DialogFragment.show() will take care of adding the fragment 43 | // in a transaction. We also want to remove any currently showing 44 | // dialog, so make our own transaction and take care of that here. 45 | FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 46 | // Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog"); 47 | // if (prev != null) { 48 | // ft.remove(prev); 49 | // } 50 | // ft.addToBackStack(null); 51 | 52 | // Create and show the dialog. 53 | DialogFragment newFragment = MyDialogFragment.getInstance(mStackLevel); 54 | newFragment.show(ft, "dialog"); 55 | } 56 | 57 | public void showAlertDialogFragment(View view) { 58 | DialogFragment newFragment = MyAlertDialogFragment.newInstance("showAlertDialogFragment000"); 59 | newFragment.show(getSupportFragmentManager(), "dialog"); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/com/timmy/tdialogdemo/ui/SystemDialog.java: -------------------------------------------------------------------------------- 1 | package com.timmy.tdialogdemo.ui; 2 | 3 | import android.app.ProgressDialog; 4 | import android.content.DialogInterface; 5 | import android.support.v7.app.AlertDialog; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.view.KeyEvent; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.widget.ProgressBar; 12 | import android.widget.Toast; 13 | 14 | import com.timmy.tdialogdemo.R; 15 | 16 | import static android.support.v4.os.LocaleListCompat.create; 17 | 18 | /** 19 | * 系统Dialog使用 20 | * List 21 | * 多选 22 | * 单选 23 | * 自定义 24 | */ 25 | public class SystemDialog extends AppCompatActivity { 26 | 27 | private int selectPosition; 28 | String[] fruitArray = new String[]{"西瓜", "芒果", "哈密瓜", "荔枝", "火龙果", "波罗蜜"}; 29 | boolean[] selectArray = new boolean[]{true, false, true, true, true, false}; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | setContentView(R.layout.activity_system_dialog); 35 | // android.app.AlertDialog 36 | } 37 | 38 | public void btnDialog1(View view) { 39 | AlertDialog.Builder builder = new AlertDialog.Builder(this) 40 | .setMessage("内容") 41 | .setIcon(R.mipmap.ic_launcher_round) 42 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 43 | @Override 44 | public void onClick(DialogInterface dialog, int which) { 45 | Toast.makeText(SystemDialog.this, "确定Click", Toast.LENGTH_SHORT).show(); 46 | } 47 | }); 48 | 49 | AlertDialog alertDialog = builder.create(); 50 | alertDialog.show(); 51 | 52 | } 53 | 54 | public void btnDialog2(View view) { 55 | new AlertDialog.Builder(this) 56 | .setTitle("标题") 57 | .setMessage("内容") 58 | .setIcon(R.mipmap.ic_launcher_round) 59 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 60 | @Override 61 | public void onClick(DialogInterface dialog, int which) { 62 | Toast.makeText(SystemDialog.this, "确定Click", Toast.LENGTH_SHORT).show(); 63 | } 64 | }) 65 | .setNegativeButton("取消", new DialogInterface.OnClickListener() { 66 | @Override 67 | public void onClick(DialogInterface dialog, int which) { 68 | Toast.makeText(SystemDialog.this, "取消Click", Toast.LENGTH_SHORT).show(); 69 | } 70 | }) 71 | .setNeutralButton("下次提醒", new DialogInterface.OnClickListener() { 72 | @Override 73 | public void onClick(DialogInterface dialog, int which) { 74 | Toast.makeText(SystemDialog.this, "下次提醒Click", Toast.LENGTH_SHORT).show(); 75 | } 76 | }) 77 | .create() 78 | .show(); 79 | } 80 | 81 | public void btnDialog3(View view) { 82 | new AlertDialog.Builder(this) 83 | .setTitle("你喜欢吃下列哪种水果?") 84 | .setIcon(R.mipmap.ic_launcher) 85 | .setItems(fruitArray, new DialogInterface.OnClickListener() { 86 | @Override 87 | public void onClick(DialogInterface dialog, int i) { 88 | Toast.makeText(SystemDialog.this, "你选择了" + fruitArray[i], Toast.LENGTH_SHORT).show(); 89 | dialog.dismiss(); 90 | } 91 | }) 92 | .setNegativeButton("取消", new DialogInterface.OnClickListener() { 93 | @Override 94 | public void onClick(DialogInterface dialog, int i) { 95 | dialog.dismiss(); 96 | } 97 | }) 98 | .create() 99 | .show(); 100 | } 101 | 102 | public void btnDialog4(View view) { 103 | new AlertDialog.Builder(this) 104 | .setTitle("你喜欢吃下列哪种水果?") 105 | .setIcon(R.mipmap.ic_launcher) 106 | .setSingleChoiceItems(fruitArray, 0, new DialogInterface.OnClickListener() { 107 | @Override 108 | public void onClick(DialogInterface dialogInterface, int i) { 109 | selectPosition = i; 110 | } 111 | }) 112 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 113 | @Override 114 | public void onClick(DialogInterface dialog, int i) { 115 | Toast.makeText(SystemDialog.this, "你选择了" + fruitArray[selectPosition], Toast.LENGTH_SHORT).show(); 116 | dialog.dismiss(); 117 | } 118 | }) 119 | .setNegativeButton("取消", new DialogInterface.OnClickListener() { 120 | @Override 121 | public void onClick(DialogInterface dialog, int i) { 122 | dialog.dismiss(); 123 | } 124 | }) 125 | .create() 126 | .show(); 127 | } 128 | 129 | public void btnDialog5(View view) { 130 | new AlertDialog.Builder(this) 131 | .setMultiChoiceItems(fruitArray, selectArray, new DialogInterface.OnMultiChoiceClickListener() { 132 | @Override 133 | public void onClick(DialogInterface dialogInterface, int i, boolean b) { 134 | selectArray[i] = b; 135 | } 136 | }) 137 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 138 | @Override 139 | public void onClick(DialogInterface dialog, int i) { 140 | Toast.makeText(SystemDialog.this, "你选择了", Toast.LENGTH_SHORT).show(); 141 | dialog.dismiss(); 142 | } 143 | }) 144 | .setNegativeButton("取消", new DialogInterface.OnClickListener() { 145 | @Override 146 | public void onClick(DialogInterface dialog, int i) { 147 | dialog.dismiss(); 148 | } 149 | }) 150 | .create() 151 | .show(); 152 | } 153 | 154 | public void btnDialog7(View view) { 155 | LayoutInflater layoutInflate = LayoutInflater.from(this); 156 | View customView = layoutInflate.inflate(R.layout.dialog_custom, null); 157 | AlertDialog customDialog = new AlertDialog.Builder(this) 158 | // .setTitle("标题") 159 | .setIcon(R.mipmap.ic_launcher) 160 | .setView(customView) 161 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 162 | @Override 163 | public void onClick(DialogInterface dialog, int i) { 164 | dialog.dismiss(); 165 | } 166 | }) 167 | .setNegativeButton("取消", new DialogInterface.OnClickListener() { 168 | @Override 169 | public void onClick(DialogInterface dialog, int i) { 170 | dialog.dismiss(); 171 | } 172 | }) 173 | .create(); 174 | customDialog.show(); 175 | } 176 | 177 | public void btnDialog8(View view) { 178 | View customTitle = LayoutInflater.from(this).inflate(R.layout.view_simple_text, null); 179 | new AlertDialog.Builder(this) 180 | // .setTitle("标题") 181 | .setMessage("内容") 182 | .setCustomTitle(customTitle) 183 | // .setCancelable(true) 184 | .setOnCancelListener(new DialogInterface.OnCancelListener() { 185 | @Override 186 | public void onCancel(DialogInterface dialog) { 187 | 188 | } 189 | }) 190 | .setOnDismissListener(new DialogInterface.OnDismissListener() { 191 | @Override 192 | public void onDismiss(DialogInterface dialog) { 193 | } 194 | }) 195 | .setOnKeyListener(new DialogInterface.OnKeyListener() { 196 | @Override 197 | public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { 198 | return false; 199 | } 200 | }) 201 | .setPositiveButton("OK", new DialogInterface.OnClickListener() { 202 | @Override 203 | public void onClick(DialogInterface dialog, int i) { 204 | dialog.dismiss(); 205 | } 206 | }) 207 | .create() 208 | .show(); 209 | } 210 | 211 | public void progressDialog(View view) { 212 | ProgressDialog progressDialog = new ProgressDialog(this); 213 | // progressDialog.setTitle("加载中"); 214 | progressDialog.setMessage("拼命加载中..."); 215 | progressDialog.show(); 216 | 217 | // ProgressBar progressBar = new ProgressBar(this); 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /app/src/main/java/com/timmy/tdialogdemo/目标: -------------------------------------------------------------------------------- 1 | //该项目是为创建一个可以通用的Dialog框架作为目标名字叫TDialog 2 | 抓哟使用的技术点是对DialogFragment进行封装 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/anim/enter_scale_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/anim/enter_translate_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/anim/exit_scale_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/anim/exit_translate_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_solid_topic.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_solid_topic.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_solid_white_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_solid_white_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_stroke_gray_99.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_dialog_encap.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 |