我目前正在开发一个自定义视图,它在画布上绘制一些图块 . 这些图块从多个文件加载,并在需要时加载 .
它们将由AsyncTask加载 . 如果它们已经加载,它们将被画在画布上 . This is working properly!
如果这些图片被加载,AsyncTask正在触发 view.postInvalidate() 问题是我每次触发view.postInvalidate()时自定义View is not firing onDraw(Canvas画布) .
view.postInvalidate 仅在加载图片时触发onDraw()方法 the first time ,然后仅在我在CustomView内的onTouchEvent中触发this.invalidate()时触发
是否有可能视图决定是否再次绘制画布?有没有办法让 FORCE 视图重绘?我认为invalidate方法告诉View,如果View考虑重绘,那将会很酷.-
这些无效方法是否有可能有限制?
我希望你们中的任何人都能更多地了解这个问题 .
edit:
我刚刚将 every postInvalidate() 更改为 invalidate() 因为图像全部由从主线程执行的AsyncTask加载但仍然存在执行 invalidate() 未执行 onDraw() 方法的问题 . 我发现 view.invalidate() 是通过覆盖原始方法来解雇的:
@Override
public void invalidate() {
super.invalidate();
Log.d(TAG, "invalidate executed");
}
我现在不知道该怎么办 . 我正在触发view.invalidate()和view.postInvalidate(),但绝对没有任何组合 .
5 回答
只为了将来保存这个以及可能的谷歌搜索者;)
我创建了一个新的Class,为我的View提供数据 . 这个类扩展了Thread并在后台运行 . 它会检查我的视图必须显示哪些图块 .
长话短说:每次必须显示新的磁贴时,我的提供者类会收集一些更新请求 . 如果“收集”3个或更多更新请求,或者自第一个更新请求起超过1秒,则视图将获得view.postInvalidate() .
问题是,如果一次触发多个请求,视图将忽略一些无效请求 . 如果你收集那些无效的请求并用一个invalidate()激活其中几个,你可以看到最新的信息只有一小段时间 - 但你可以看到它;)
这里有一点误会 . invalidate和postInvalidate方法用于告诉View它需要在最早的绘图周期中刷新和重绘 . 不同之处在于应该从UI线程中调用invalidate方法,并且应该从UI线程外部调用postInvalidate .
这里简要描述了这些方法:
http://developer.android.com/reference/android/view/View.html#postInvalidate()
http://developer.android.com/reference/android/view/View.html#invalidate()
另一方面,AsyncTask是一个专为您在UIThread中运行're facing. When you need to perform a big task in the background, asynchronously you need the AsyncTask for that, but! the AsyncTask'回调方法的问题设计的类!
在这里看一下AsyncTask方法的解释:
执行异步任务时,任务将执行4个步骤:
这意味着在onPostExecute方法中,您应该尝试使用invalidate方法而不是从UIThread调用的postInvalidate方法 .
你听说过方法调用setWillNotDraw(boolean)吗?
看看here
将它设置为false,你会看到
我已经解决了请求
view.invalidate()
或view.postInvalidate()
的问题,而不是单独使每个子视图无效(这些子视图中的每一个都包含其自己的AsyncTask),但是为了使它们的公共父ViewGroup无效 .现在详细说明 . 我有
其中有几个视图,每个视图如下:
对
invalidate();
的调用有时是有效的,有时则没有(如果来自不同的AsyncTask
的调用属于不同的mView
,但是在非常接近的时刻时间) .更改
至
mContext.invalidate(); //i.e. invalidating the whole ViewGroup
解决了这个问题 .
在我的情况下,目标自定义View在那时具有height = 0属性 . (我的错误)和postInvalidate()和invalidate没有触发onDraw()和Log .
当我当前改变高度时,所有问题都解决了 .