论__AlertDialog自定义布局回调修改的正确方式


本文由 Luzhuo 编写,请尊重个人劳动成果,转发请保留该信息.
原文: http://blog.csdn.net/Rozol/article/details/50441057
微博: http://weibo.com/u/2524456400


这几天写了个应用,自定义了AlertDialog布局,加入了TextView和进度条展示,但是不管怎么调,Dialog就是不显示出来,即时显示出来也不更新,只在程序执行完了才更新.
于是没辙了,换成Android自带的ProgressDialog试试,结果还是老样子.(也是要么不显示,即时显示了也不更新,只在程序执行完了才更新.)
于是亲自动手写个Demo看看到底是什么问题.(反复折腾,终于折腾出结果来了,先下结论吧.)
这篇文章没有插图,下面有Github的链接,下载里面的apk就能很清楚的知道这篇文章在讲什么啦!!!

结论

  • 一定要在辅助线程里执行的回调才能修改Dialog的界面; (第1,2的案例)
  • 在ui线程里执行的回调不能修改Dialog的界面.(准确的说:能修改,但是不是你想要的效果) (第3,4的案例)

详细分析

先看MainActivity里的代码:

public class MainActivity extends Activity implements OnClickListener {// ... 省略private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case Start:dialog.show();// 显示Log.i(TAG, "start");break;case Back:textview.setText((String)msg.obj);Log.i(TAG, (String)msg.obj);break;case End:dialog.dismiss();Log.i(TAG, "end");break;}}};// ... 省略private void initData() {dialog_view = View.inflate(this, R.layout.dialog, null);textview = (TextView) dialog_view.findViewById(R.id.textview);// AlertDialogAlertDialog.Builder builder = new Builder(this);builder.setCancelable(false);dialog = builder.create();dialog.setView(dialog_view, 0, 0, 0, 0);}private void threadStart() {DialogThread dialogThread = new DialogThread();dialogThread.setOnBackListener(new OnBack() {@Overridepublic void onStart() {Message msg = Message.obtain();msg.what = Start;handler.sendEmptyMessage(Start);}@Overridepublic void onBack(String backName) {Message msg = Message.obtain();msg.what = Back;msg.obj = backName;handler.sendMessage(msg);}@Overridepublic void onEnd() {Message msg = Message.obtain();msg.what = End;handler.sendEmptyMessage(End);}});dialogThread.start();}

从上诉代码可以看出,我是让 子线程/异步任务/ui线程 里执行的任务通过回调方式.
然后在回调里发送Message的方式更新ui.
由于 子线程/异步任务 都不能修改ui,所以使用发送Message的方法,但是ui线程是可以直接修改Dialog里的布局的,所以我会增加一个通过回调直接修改Dialog的案例.

1.子线程里回调,修改dialog界面

第一种,通过开启子线程方式,然后回调修改dialog的界面.
由于子线程不能修改ui界面,所以使用handler方式.

public class DialogThread {// ... 省略public void start(){new Thread(){public void run() {if(onBack != null) onBack.onStart();while(x<10){if(onBack != null) onBack.onBack(String.valueOf(x));SystemClock.sleep(1000);x++;}if(onBack != null) onBack.onEnd();};}.start();}
// ... 省略
}

子线程通过执行回调,回调里发送Message修改Dialog的界面.
执行的结果是可行的,完全可以修改Dialog的显示.效果非常好.

2.异步任务里回调,修改dialog界面

第二种,通过异步任务方式,然后回调修改dialog的界面.
由于辅助线程不能修改ui界面,所以使用handler方式.

public class DialogAsync extends AsyncTask<Context, Void, Void> {// ... 省略@Overrideprotected Void doInBackground(Context... params) {if(onBack != null) onBack.onStart();while(x<10){if(onBack != null) onBack.onBack(String.valueOf(x));SystemClock.sleep(1000);x++;}if(onBack != null) onBack.onEnd();return null;}
// ... 省略
}

异步任务通过执行回调,回调里发送Message修改Dialog的界面.
执行的结果是可行的,完全可以修改Dialog的显示.效果非常好.

3.UI线程里回调,修改dialog界面

第三种,通过ui线程方式,然后回调修改dialog的界面.
由于为了与上面的例子做个参照物,所以还是使用handler方式.

public class DialogThread {// ... 省略public void start(){new Thread(){public void run() {if(onBack != null) onBack.onStart();while(x<10){if(onBack != null) onBack.onBack(String.valueOf(x));SystemClock.sleep(1000);x++;}if(onBack != null) onBack.onEnd();};}.start();}
// ... 省略
}

ui线程通过执行回调,回调里发送Message修改Dialog的界面.
执行的结果是糟糕的,Log在程序执行完后才打印,而且是一起快速打印,而且根本没看到Dialog的显示.

4.UI线程里回调,修改dialog界面

第四种,通过ui线程方式,然后回调修改dialog的界面.
由于为了与第三个例子做个参照物,所以直接回调然后修改Dialog的方式.
由于还是执行第三个例子的DialogThread类的方法,代码这里不再粘贴.
这里粘贴MainActivity里的部分主要代码.

public class MainActivity extends Activity implements OnClickListener {// ... 省略private void mainStart1() {DialogMain dialogMain = new DialogMain();dialogMain.setOnBackListener(new OnBack() {@Overridepublic void onStart() {dialog.show();// 显示Log.i(TAG, "start");}@Overridepublic void onBack(String backName) {textview.setText(backName);Log.i(TAG, backName);}@Overridepublic void onEnd() {dialog.dismiss();Log.i(TAG, "end");}});dialogMain.start();}
}

ui线程通过执行回调,回调里直接修改Dialog的界面.
执行的结果是糟糕的,Log能完美的打印,但是根本没看到Dialog的显示.

  • Q:如何知道当前线程是否是ui线程?
  • A:Log.i(“UIThread”, “当前线程”.concat(Thread.currentThread().getId() == 1 ? “是” : “不是”).concat(“UI线程”));

Github

GithubDemo代码

论__AlertDialog自定义布局回调修改的正确方式相关推荐

  1. UICollectionView 自定义布局教程: Pinterest

    原文: UICollectionView Custom Layout Tutorial: Pinterest 作者:Paride Broggi 译者:kmyhy 更新说明:本教程由 Paride Br ...

  2. Eclipse Theia技术揭秘——自定义布局

    在上篇文章 脚手架源码分析 文章中,我们分析了启动过程中前端页面是如何展示的,那么本篇文章我们介绍一下theia布局的相关内容以及如何自定义布局. PhosphorJS Theia的组件和布局系统是使 ...

  3. ViewGroup1——自定义布局

    平时开发时,系统提供的几个布局基本就能满足我们的需求了.如果系统提供的布局无法满足需求,我们可以扩展ViewGroup类来实现自定义布局控件.先看下ViewGroup的继承图 由上图可知,ViewGr ...

  4. iOS开发学无止境 - UICollectionView自定义布局之风火轮[译]

    现在有许多极具创造力的网站,几周前我碰巧浏览到一个名为Form Follows Function的网站,上面有各种交互动画.其中最吸引我的是网站上的导航转轮,转轮由各种交互体验海报组成. 原文:UIC ...

  5. 从自定义TagLayout看自定义布局的一般步骤[手动加精]

    从自定义TagLayout看自定义布局的一般步骤[手动加精] 我们常用的布局有LinearLayout,FrameLayout,RelativeLayout,大多数情况下都能满足我们的需求,但是也有很 ...

  6. 【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | Android 系统的渲染优化 | 自定义布局渲染优化 )

    文章目录 一. 背景设置产生的过度绘制 二. Android 系统的渲染优化 1. 透明组件数据传递 2. GPU 存储机制 3. Android 7.0 之后的优化机制 三. 自定义布局渲染优化 一 ...

  7. android 自定义布局 根据布局获取类,android自定义布局中的平滑移动之ViewGroup实现...

    在android应用程序的开发过程中,相信我们很多人都想把应用的交互做的比较绚丽,比如让界面切换平滑的滚动,还有热度灰常高的伪3D等界面效果,通常情况下,系统提供的应用在特效这方面只能为我们提供简单的 ...

  8. android 自定义布局 根据布局获取类,阿里高级Android面试题解析:Android自定义View—布局过程的自定义...

    自定义分三部分绘制.布局和触摸反馈,本篇主要讲的布局过程的自定义 布局过程的含义 布局过程,就是程序在运行时利用布局文件的代码来计算出实际尺寸的过程. 布局过程的工作内容 两个阶段:测量阶段和布局阶段 ...

  9. 使用AlertDialog自定义布局,解决自定义控件的监听事件无效的办法

    使用AlertDialog自定义布局,解决自定义控件的监听事件无效的办法 在很多情况下,Android自带对话框的样式满足不了我们项目的需求,这时候我们可以采用为对话框设置自定义布局.如果直接用Dia ...

最新文章

  1. 【一周论文速递】自然语言处理最新论文!
  2. 关于Ubuntu20.04 sudo vi找不到命令解决方法
  3. 量子计算机是二进制码,知识丨量子计算
  4. 深入浅出设计模式原则之接口隔离原则(ISP)
  5. linux双机ssh互信方法总结
  6. java中缓冲区和缓存_Java中的Google协议缓冲区
  7. linux 删除带a的文件格式,linux基础命令练习题
  8. MongoDB安装启动教程
  9. mysql root用户可以同时几个人连接_PHP安全:MySQL的使用安全
  10. Java写一个接口和两个类
  11. Struts2与传统模式的对比,核心控制器从servlet变成了过滤器,!!
  12. 微信小程序支付封装-复制即用
  13. python 条件查询_Python SQLAlchemy 不确定条件查询
  14. dell笔记本外接显示器_小桌面 笔记本外接显示器的正确姿势
  15. 中国人民银行征信中心登录时无法输入密码,控件安装无效
  16. 人工智能基础部分11-图像识别实战(网络层联想记忆,代码解读)
  17. 用turtle画奥运五环
  18. 如何在Word中的表上添加边框或更改边框
  19. Error occurred while trying to proxy request项目突然起不来了
  20. Cocos2d-X资源网站索引

热门文章

  1. 野火开发版屏幕_鸿蒙2.0手机开发者版发布,华为多数自研设备明年升级鸿蒙
  2. 网页遥控室内智能设备
  3. 跳过DOSBox映射的方法
  4. ant java xml文件,ant 学习(2)-ant开发java程序,buile.xml文件分离
  5. 只读数据文件损坏恢复
  6. P2617 Dynamic Rankings(主席树+树状数组)
  7. Socket 简易静态服务器 WPF MVVM模式(一)
  8. git克隆远程仓库的时候断电了,使用git-fetch断点续传
  9. 解决ASP.NET MVC 下使用SQLite 报no such table的问题
  10. JavaScript执行bat文件清理浏览器缓存