Android 如何立即刷新图像视图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11893826/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to refresh image view immediately
提问by user1583075
In my android app, I download an image from the cloud. The download is performed in a thread and in that same thread I also set an image view with the newly downloaded image. After setting the image, I then call postinvalidate()
.
在我的 android 应用程序中,我从云端下载了一张图片。下载是在一个线程中执行的,在同一个线程中,我还使用新下载的图像设置了一个图像视图。设置图像后,我然后调用postinvalidate()
.
However the image does not immediately show up. Is there a way to make the redraw happen immediately? I need a way to trigger a drawing cycle.
然而,图像并没有立即显示出来。有没有办法让重绘立即发生?我需要一种触发绘图周期的方法。
回答by K_Anas
Each class which is derived from the View class has the invalidate()
and the postInvalidate()
method. If invalidate()
gets called it tells the system that the current view has changed and it should be redrawn as soon as possible. As this method can only be called from your UIThreadanother method is needed for when you are notin the UIThreadand still want to notify the system that your View has been changed. The postInvalidate()
method notifies the system from a non-UIThreadand the View gets redrawn in the next eventloopon the UIThread as soon as possible.
每个派生自 View 类的类都有invalidate()
和postInvalidate()
方法。如果invalidate()
被调用时,告诉系统,目前看来已发生变化,它应该是重绘尽快。由于这种方法只能从被称为UIThread需要你时的另一种方法不是在UIThread,仍然要通知系统,你的观点已经发生了变化。该postInvalidate()
方法从非 UIThread通知系统,并尽快在 UIThread 上的下一个事件循环中重新绘制视图。
In your case you can achieve what you want with the help of AsyncTask
(an intelligent backround thread).AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations (download image in background in your case) and publish results (set your bitmap to your ImageView) on the UI thread without having to manipulate threads and/or handlers.
在您的情况下,您可以在AsyncTask
(智能后台线程)的帮助下实现您想要的。AsyncTask 可以正确且轻松地使用 UI 线程。此类允许在 UI 线程上执行后台操作(在您的情况下在后台下载图像)并发布结果(将位图设置为 ImageView),而无需操作线程和/或处理程序。
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called begin, doInBackground, processProgress and end.
异步任务由在后台线程上运行且其结果发布在 UI 线程上的计算定义。异步任务由3 个泛型类型(称为 Params、Progress 和 Result)和4 个步骤(称为 begin、doInBackground、processProgress 和 end)定义。
The 4 steps
4个步骤
When an asynchronous task is executed, the task goes through 4 steps:
当一个异步任务被执行时,任务会经过 4 个步骤:
onPreExecute()
, invoked on the UI thread immediately after the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface before downloading the image from cloud and that's used to provide a good user experience .
onPreExecute()
,在任务执行后立即在 UI 线程上调用。此步骤通常用于设置任务,例如在从云下载图像之前在用户界面中显示进度条,用于提供良好的用户体验。
doInBackground(Params...)
, invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
doInBackground(Params...)
, 在 onPreExecute() 完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数传递到这一步。计算的结果必须由这一步返回,并将传递回最后一步。这一步也可以使用 publishProgress(Progress...) 来发布一个或多个进度单元。这些值发布在 UI 线程上的 onProgressUpdate(Progress...) 步骤中。
onProgressUpdate(Progress...)
, invoked on the UI thread after a call to publishProgress(Progress...)
. The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing.
onProgressUpdate(Progress...)
, 调用后在 UI 线程上调用publishProgress(Progress...)
。执行的时间是不确定的。此方法用于在后台计算仍在执行时在用户界面中显示任何形式的进度。
onPostExecute(Result)
, invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter in that method you can set the bitmap to your imageView and invalidate your views
onPostExecute(Result)
, 在后台计算完成后在 UI 线程上调用。后台计算的结果作为该方法中的参数传递给这一步,您可以将位图设置为您的 imageView 并使您的视图无效
回答by Ratul Doley
Invalidate doesn't work. Changing the uri or url or the path of the image temporarily and changing back to the required path works. For example, if i have
无效不起作用。临时更改 uri 或 url 或图像的路径并更改回所需的路径有效。例如,如果我有
image_url="myhost/img.png";
himg.setImageURI(image_url, imageLoader);
I can refresh this as:
我可以将其刷新为:
himg.setImageURI(null, imageLoader);
himg.setImageURI(image_url, imageLoader)
回答by Korcholis
Did you try using invalidate()
? It forces the view to be redrawn immediately and not during the next cycle
你试过用invalidate()
吗?它强制立即重绘视图,而不是在下一个循环中重绘
回答by Furqi
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (!socket.isClosed()) {
imgArray = receiveImagebytes();
}
}
}).start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (!socket.isClosed()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
imageView.setImageBitmap(BitmapFactory.decodeByteArray(imgArray, 0, imgArray.length));
imageView.invalidate();
}
});