- 浏览: 261423 次
- 性别:
- 来自: 西安
最新评论
-
Nabulio:
Java之线程停止 -
语儿123:
...
C++之tinyXML使用 -
lzmrex:
按照你的步骤,失败了额。
Weblogic远程调试 -
one_is_all:
真心不错,就是太多了看的有点乱,要多看几遍估计才行啊
Android中Message机制的灵活应用 -
yong7356:
学习了。。。。。。。。
Android中Message机制的灵活应用
android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。
以下是我在android文档中找到的说明,
public void invalidate()
Invalidate the whole view. If the view is visible, onDraw(Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate().
public void postInvalidate ()
Cause an invalidate to happen on a subsequent cycle through the event loop. Use this to invalidate the View from a non-UI thread.
google的文档的说明实在是简单,往往看了开发中都会遇到这两个问题:
1. 没有任何异常,view没能刷新。
2. android应用异常终止,打开logcat会看到这样的异常信息, Only the original thread that created a view hierarchy can touch its views。
最后,通过查文档,上网查询才知道,invalidate和postInvalidate方法需要使用android提供的handler,才能实现重绘,而在文档的说明中却只字不提,真是简单啊。具体是在需要重绘的地方调用handler的sendMessage方法发送消息,紧接着会os会触发handler中的handlerMessage方法,在handlerMessage方法中再调用view的invalidate或者postInvalidate方法就能实现重绘。
下面是我分别针对invalidate方法,给出view重绘代码,仅供参考:
或者这样实现也可以。
我的例子是在linux下面,现在那个系统起不了,呵呵。你可以把你的异常信息发给我,我帮你看看。
好的。。。谢谢咯!不过我觉得我的方法有问题。。我现要的效果是像玩棋牌游戏,点击开始按钮时在该页面中显示玩家的牌。
我的思路:先在ondraw()方法里把bitmap都画出来,,当用户点击开始按钮后我再用实现重画的方法里new 一个新的bitmap把之前画的bitmap覆盖。。所以20张牌我就要new40个对象。。而且页面的bitmap远远不止这些。。所以导致内存泄露。。我想知道你有没有好的思路。。
10-16 13:58:44.461: ERROR/dalvikvm-heap(811): 617376-byte external allocation too large for this process.
10-16 13:58:44.461: ERROR/(811): VM won't let us allocate 617376 bytes
10-16 13:58:44.481: ERROR/AndroidRuntime(811): Uncaught handler: thread main exiting due to uncaught exception
10-16 13:58:44.511: ERROR/AndroidRuntime(811): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:439)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:322)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:344)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:364)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.hk.ddz.TableView.createBitmap(TableView.java:190)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.hk.ddz.TableView.onDraw(TableView.java:156)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.View.draw(View.java:6274)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.View.draw(View.java:6277)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.widget.FrameLayout.draw(FrameLayout.java:352)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.View.draw(View.java:6277)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.widget.FrameLayout.draw(FrameLayout.java:352)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1883)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewRoot.draw(ViewRoot.java:1332)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewRoot.performTraversals(ViewRoot.java:1097)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewRoot.handleMessage(ViewRoot.java:1613)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.os.Handler.dispatchMessage(Handler.java:99)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.os.Looper.loop(Looper.java:123)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.app.ActivityThread.main(ActivityThread.java:4203)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at java.lang.reflect.Method.invokeNative(Native Method)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at java.lang.reflect.Method.invoke(Method.java:521)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at dalvik.system.NativeStart.main(Native Method)
我的例子是在linux下面,现在那个系统起不了,呵呵。你可以把你的异常信息发给我,我帮你看看。
回复你好,我上面提供的代码,只是一个架子,这个架子里面只能实现两种情形:
1)其一就是android控件延时刷新,修改方法就是在UIUpdateThread类的run方法在呼出Handler的post方法之前增加一个延迟。
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
e.printStackTrace();
}
举个例子说明一下它在什么场合应用吧,比如启动游戏前的动画,是不是Imageview就可以通过这个延时刷新来实现启动动画的效果,刚开始加载一幅画,过会换一幅画。
2)其二就是android控件定时刷新,那就得在修改CustomizeView构造方法,将UIUpdateThread添加到Timer中,这样就可以实现定时刷新。
那么如果你需要不定时刷新的话,那我提供的这个架子就不适用了,你得自己去调用Handler的post方法。这种情况应该是最常见的。
呵呵!希望我的回复对你能有所帮助。
以下是我在android文档中找到的说明,
引用
public void invalidate()
Invalidate the whole view. If the view is visible, onDraw(Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate().
public void postInvalidate ()
Cause an invalidate to happen on a subsequent cycle through the event loop. Use this to invalidate the View from a non-UI thread.
google的文档的说明实在是简单,往往看了开发中都会遇到这两个问题:
1. 没有任何异常,view没能刷新。
2. android应用异常终止,打开logcat会看到这样的异常信息, Only the original thread that created a view hierarchy can touch its views。
最后,通过查文档,上网查询才知道,invalidate和postInvalidate方法需要使用android提供的handler,才能实现重绘,而在文档的说明中却只字不提,真是简单啊。具体是在需要重绘的地方调用handler的sendMessage方法发送消息,紧接着会os会触发handler中的handlerMessage方法,在handlerMessage方法中再调用view的invalidate或者postInvalidate方法就能实现重绘。
下面是我分别针对invalidate方法,给出view重绘代码,仅供参考:
class CustomizeView extends WhichView { public CustomizeView(Context context) { super(context); final Handler handler = new Handler(); new Thread(new Runnable() { @Override public void run() { // delay some minutes you desire. /*try { Thread.sleep(3000); } catch (InterruptedException e) { }*/ handler.post(new Runnable() { public void run() { concreteUpdateUI(); invalidate(); } }); } }).start(); } protected void concreteUpdateUI() { // Add concrete movement for UI updates. // ... } }
或者这样实现也可以。
class CustomizeView extends TextView { public CustomizeView(Context context) { super(context); new Thread(new UIUpdateThread()).start(); } class UIUpdateThread implements Runnable { final Handler mHandler = new Handler(); final Runnable mUpdateResults = new Runnable() { public void run() { concreteUpdateUI(); invalidate(); } }; public void run() { // delay some minutes you desire. /*try { Thread.sleep(1000 * 5); } catch (InterruptedException e) { e.printStackTrace(); }*/ mHandler.post(mUpdateResults); } } protected void concreteUpdateUI() { // Add concrete movement for UI updates. // ... } }
评论
9 楼
kkmike999
2013-04-16
用handler麻烦啊~~ 用AsyncTask更简单(这方法能运行,不过不知道view有没变化)
//AsyncTask三个参数,分别是输入、updateUI时传递的参数、返回的参数 class MyTask extends AsyncTask<Integer, Integer, Void> { @Override protected Void doInBackground(Integer... params) { publishProgress(params[0]);//之后会调用onProgressUpdate方法 return null; } @Override protected void onProgressUpdate(Integer... values) { //mView是View子类 mView.invalidate(); } }
8 楼
kkmike999
2013-04-16
用handler麻烦啊~~ 用AsyncTask更简单(这方法能运行,不过不知道view有没变化)
//AsyncTask三个参数,分别是输入、updateUI时传递的参数、返回的参数 class MyTask extends AsyncTask<Integer, Integer, Void> { @Override protected Void doInBackground(Integer... params) { publishProgress(params[0]);//之后会调用onProgressUpdate方法 return null; } @Override protected void onProgressUpdate(Integer... values) { //mView是View子类 mView.invalidate(); } }
7 楼
bsxy
2012-08-27
楼主给出的两段代码均有问题,
代码一:
class CustomizeView extends WhichView {
public CustomizeView(Context context) {
super(context);
final Handler handler = new Handler(); //这里的new操作已把handler和ui线程的消息队列绑定了.
new Thread(new Runnable() {
@Override
public void run() {
// delay some minutes you desire.
/*try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}*/
handler.post(new Runnable() {
public void run() {
//这里的代码其实是执行在handler所在的ui线程的
concreteUpdateUI();
invalidate();
}
});
}
}).start();
}
protected void concreteUpdateUI() {
// Add concrete movement for UI updates.
// ...
}
}
代码二和线程完全没关系.所有代码都是执行在ui线程的
就这两份代码而言,如果concreteUpdateUI是绘制动作的话,那都是运行在主线程中.不需要开线程.
代码一:
class CustomizeView extends WhichView {
public CustomizeView(Context context) {
super(context);
final Handler handler = new Handler(); //这里的new操作已把handler和ui线程的消息队列绑定了.
new Thread(new Runnable() {
@Override
public void run() {
// delay some minutes you desire.
/*try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}*/
handler.post(new Runnable() {
public void run() {
//这里的代码其实是执行在handler所在的ui线程的
concreteUpdateUI();
invalidate();
}
});
}
}).start();
}
protected void concreteUpdateUI() {
// Add concrete movement for UI updates.
// ...
}
}
代码二和线程完全没关系.所有代码都是执行在ui线程的
就这两份代码而言,如果concreteUpdateUI是绘制动作的话,那都是运行在主线程中.不需要开线程.
6 楼
Qaohao
2009-10-20
回复:
你的思路我明白了,使用40个对象是因为,前20个对象是前一个游戏的残局,另外20个对象是新游戏的中牌。思路没问题,但是你这个使用的手机,因此这么考虑就不对了。我现在说说我的思路吧。
第一,不要完全将所有图片的信息读入到手机内存中,因为你得到自己的牌时也只能看到一张牌的五分之一,或者更少。因此你只需要将你要表示的部分存到一个数组里面就可以了,这里我建议你不要使用image对象。
第二,在你打出一张牌时,在真正读那张牌的内容。此外打出去的一张牌可以用一张图片来表示,一般游戏都是这么做的。
第三,适当压缩牌图片的bitmap信息,只要能清晰表示图片就行了。网上有些图片压缩算法,你可以找找。
最后,没有必要20张牌new40个对象,图像信息可以共享的。
以上是我的一些建议,希望对你有所帮助。
你的思路我明白了,使用40个对象是因为,前20个对象是前一个游戏的残局,另外20个对象是新游戏的中牌。思路没问题,但是你这个使用的手机,因此这么考虑就不对了。我现在说说我的思路吧。
第一,不要完全将所有图片的信息读入到手机内存中,因为你得到自己的牌时也只能看到一张牌的五分之一,或者更少。因此你只需要将你要表示的部分存到一个数组里面就可以了,这里我建议你不要使用image对象。
第二,在你打出一张牌时,在真正读那张牌的内容。此外打出去的一张牌可以用一张图片来表示,一般游戏都是这么做的。
第三,适当压缩牌图片的bitmap信息,只要能清晰表示图片就行了。网上有些图片压缩算法,你可以找找。
最后,没有必要20张牌new40个对象,图像信息可以共享的。
以上是我的一些建议,希望对你有所帮助。
5 楼
android_learner
2009-10-16
Qaohao 写道
android_learner 写道
呵呵! 谢谢了。
你有没有重画的一些可以看到效果的代码,,简单的一个列子就行。。我想在虽然之前的问题解决了,但我重画区域的地方有点多,new的对象多了。vm抛出oom异常。。我不知道怎么解决!! 希望你给点意见。。谢谢啦!
你有没有重画的一些可以看到效果的代码,,简单的一个列子就行。。我想在虽然之前的问题解决了,但我重画区域的地方有点多,new的对象多了。vm抛出oom异常。。我不知道怎么解决!! 希望你给点意见。。谢谢啦!
我的例子是在linux下面,现在那个系统起不了,呵呵。你可以把你的异常信息发给我,我帮你看看。
好的。。。谢谢咯!不过我觉得我的方法有问题。。我现要的效果是像玩棋牌游戏,点击开始按钮时在该页面中显示玩家的牌。
我的思路:先在ondraw()方法里把bitmap都画出来,,当用户点击开始按钮后我再用实现重画的方法里new 一个新的bitmap把之前画的bitmap覆盖。。所以20张牌我就要new40个对象。。而且页面的bitmap远远不止这些。。所以导致内存泄露。。我想知道你有没有好的思路。。
10-16 13:58:44.461: ERROR/dalvikvm-heap(811): 617376-byte external allocation too large for this process.
10-16 13:58:44.461: ERROR/(811): VM won't let us allocate 617376 bytes
10-16 13:58:44.481: ERROR/AndroidRuntime(811): Uncaught handler: thread main exiting due to uncaught exception
10-16 13:58:44.511: ERROR/AndroidRuntime(811): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:439)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:322)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:344)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:364)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.hk.ddz.TableView.createBitmap(TableView.java:190)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.hk.ddz.TableView.onDraw(TableView.java:156)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.View.draw(View.java:6274)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.View.draw(View.java:6277)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.widget.FrameLayout.draw(FrameLayout.java:352)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.drawChild(ViewGroup.java:1526)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.drawChild(ViewGroup.java:1524)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1256)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.View.draw(View.java:6277)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.widget.FrameLayout.draw(FrameLayout.java:352)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1883)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewRoot.draw(ViewRoot.java:1332)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewRoot.performTraversals(ViewRoot.java:1097)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.view.ViewRoot.handleMessage(ViewRoot.java:1613)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.os.Handler.dispatchMessage(Handler.java:99)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.os.Looper.loop(Looper.java:123)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at android.app.ActivityThread.main(ActivityThread.java:4203)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at java.lang.reflect.Method.invokeNative(Native Method)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at java.lang.reflect.Method.invoke(Method.java:521)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
10-16 13:58:44.511: ERROR/AndroidRuntime(811): at dalvik.system.NativeStart.main(Native Method)
4 楼
Qaohao
2009-10-15
android_learner 写道
呵呵! 谢谢了。
你有没有重画的一些可以看到效果的代码,,简单的一个列子就行。。我想在虽然之前的问题解决了,但我重画区域的地方有点多,new的对象多了。vm抛出oom异常。。我不知道怎么解决!! 希望你给点意见。。谢谢啦!
你有没有重画的一些可以看到效果的代码,,简单的一个列子就行。。我想在虽然之前的问题解决了,但我重画区域的地方有点多,new的对象多了。vm抛出oom异常。。我不知道怎么解决!! 希望你给点意见。。谢谢啦!
我的例子是在linux下面,现在那个系统起不了,呵呵。你可以把你的异常信息发给我,我帮你看看。
3 楼
android_learner
2009-10-15
呵呵! 谢谢了。
你有没有重画的一些可以看到效果的代码,,简单的一个列子就行。。我想在虽然之前的问题解决了,但我重画区域的地方有点多,new的对象多了。vm抛出oom异常。。我不知道怎么解决!! 希望你给点意见。。谢谢啦!
你有没有重画的一些可以看到效果的代码,,简单的一个列子就行。。我想在虽然之前的问题解决了,但我重画区域的地方有点多,new的对象多了。vm抛出oom异常。。我不知道怎么解决!! 希望你给点意见。。谢谢啦!
2 楼
Qaohao
2009-10-12
android_learner 写道
楼主:你好。。
请问concreteUpdateUI()里怎么实现。。我重画时concreteUpdateUI方法内实现根本没有重画成功??应该怎么实现呢??
protected void concreteUpdateUI() {
Toast.makeText(this.getContext(),"haha" + point.x+ " " + point.y, Toast.LENGTH_SHORT).show();
Paint p = new Paint();
p.setColor(Color.RED);
// Rect r = new Rect(50, 12, 73, 30);
// canvas.drawRect(tempRect, p);
// 桌子变色
Bitmap table = loadImage(R.drawable.table4_light, table1);
Canvas canvas = new Canvas();
canvas.drawBitmap(table, 0, 0, paint);
// 画人
Bitmap bitmap = Bitmap.createBitmap(topChair.right + 10,
topChair.bottom + 10, Config.ARGB_8888);
Resources r = this.getContext().getResources();
Drawable drawable = r.getDrawable(R.drawable.person);
drawable.setBounds(topChair);
drawable.draw(canvas);
canvas.drawBitmap(bitmap, 0, 0, p);
}
请问concreteUpdateUI()里怎么实现。。我重画时concreteUpdateUI方法内实现根本没有重画成功??应该怎么实现呢??
protected void concreteUpdateUI() {
Toast.makeText(this.getContext(),"haha" + point.x+ " " + point.y, Toast.LENGTH_SHORT).show();
Paint p = new Paint();
p.setColor(Color.RED);
// Rect r = new Rect(50, 12, 73, 30);
// canvas.drawRect(tempRect, p);
// 桌子变色
Bitmap table = loadImage(R.drawable.table4_light, table1);
Canvas canvas = new Canvas();
canvas.drawBitmap(table, 0, 0, paint);
// 画人
Bitmap bitmap = Bitmap.createBitmap(topChair.right + 10,
topChair.bottom + 10, Config.ARGB_8888);
Resources r = this.getContext().getResources();
Drawable drawable = r.getDrawable(R.drawable.person);
drawable.setBounds(topChair);
drawable.draw(canvas);
canvas.drawBitmap(bitmap, 0, 0, p);
}
回复你好,我上面提供的代码,只是一个架子,这个架子里面只能实现两种情形:
1)其一就是android控件延时刷新,修改方法就是在UIUpdateThread类的run方法在呼出Handler的post方法之前增加一个延迟。
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
e.printStackTrace();
}
举个例子说明一下它在什么场合应用吧,比如启动游戏前的动画,是不是Imageview就可以通过这个延时刷新来实现启动动画的效果,刚开始加载一幅画,过会换一幅画。
2)其二就是android控件定时刷新,那就得在修改CustomizeView构造方法,将UIUpdateThread添加到Timer中,这样就可以实现定时刷新。
那么如果你需要不定时刷新的话,那我提供的这个架子就不适用了,你得自己去调用Handler的post方法。这种情况应该是最常见的。
呵呵!希望我的回复对你能有所帮助。
1 楼
android_learner
2009-10-11
楼主:你好。。
请问concreteUpdateUI()里怎么实现。。我重画时concreteUpdateUI方法内实现根本没有重画成功??应该怎么实现呢??
protected void concreteUpdateUI() {
Toast.makeText(this.getContext(),"haha" + point.x+ " " + point.y, Toast.LENGTH_SHORT).show();
Paint p = new Paint();
p.setColor(Color.RED);
// Rect r = new Rect(50, 12, 73, 30);
// canvas.drawRect(tempRect, p);
// 桌子变色
Bitmap table = loadImage(R.drawable.table4_light, table1);
Canvas canvas = new Canvas();
canvas.drawBitmap(table, 0, 0, paint);
// 画人
Bitmap bitmap = Bitmap.createBitmap(topChair.right + 10,
topChair.bottom + 10, Config.ARGB_8888);
Resources r = this.getContext().getResources();
Drawable drawable = r.getDrawable(R.drawable.person);
drawable.setBounds(topChair);
drawable.draw(canvas);
canvas.drawBitmap(bitmap, 0, 0, p);
}
请问concreteUpdateUI()里怎么实现。。我重画时concreteUpdateUI方法内实现根本没有重画成功??应该怎么实现呢??
protected void concreteUpdateUI() {
Toast.makeText(this.getContext(),"haha" + point.x+ " " + point.y, Toast.LENGTH_SHORT).show();
Paint p = new Paint();
p.setColor(Color.RED);
// Rect r = new Rect(50, 12, 73, 30);
// canvas.drawRect(tempRect, p);
// 桌子变色
Bitmap table = loadImage(R.drawable.table4_light, table1);
Canvas canvas = new Canvas();
canvas.drawBitmap(table, 0, 0, paint);
// 画人
Bitmap bitmap = Bitmap.createBitmap(topChair.right + 10,
topChair.bottom + 10, Config.ARGB_8888);
Resources r = this.getContext().getResources();
Drawable drawable = r.getDrawable(R.drawable.person);
drawable.setBounds(topChair);
drawable.draw(canvas);
canvas.drawBitmap(bitmap, 0, 0, p);
}
发表评论
-
Android中Message机制的灵活应用
2009-11-03 12:08 37015引用来自easyandroid论坛,原文:http://www ... -
Android之个性化ListView实现
2009-10-29 13:45 9458Android中提供的ListV ... -
Android之界面设计器
2009-09-27 15:09 3216今天发现一款android界面设计器-droidDraw,用s ... -
Android之获取画面大小
2009-09-27 14:06 3476我们在做ui开发通常都会有这样的需求,取得画面的大小,以下这段 ... -
Android初次使用遇到的两个问题
2009-09-01 08:18 18666Android是谷歌在自己手机上面推出的一个开发平台, ...
相关推荐
当地图数据发生变化时,可以通过调用`invalidate()`或`postInvalidate()`方法请求重绘。`invalidate()`会立即触发`onDraw()`,而`postInvalidate()`则会在UI线程的下一次遍历时执行。 二、自定义ViewGroup 自定义...
在Android开发中,View的旋转是一项常见的操作,用于实现各种动态效果或用户交互。本文将深入探讨Android View...在实际编程过程中,还需要注意性能优化,合理利用硬件加速以及避免不必要的重绘,以保证应用的流畅性。
1. 减少不必要的重绘:合理使用View的可见性属性,避免在不需要绘制的地方调用invalidate()。 2. 使用硬件加速:开启硬件加速可以提高View的绘制性能,但并非所有情况都适用,需谨慎使用。 3. 适当使用ViewStub:当...
可以使用硬件加速(`setLayerType(View.LAYER_TYPE_HARDWARE, null)`),避免不必要的重绘(`setWillNotDraw(false)`或`setWillNotDraw(true)`),以及合理使用`invalidate()`来仅刷新需要更新的部分。 7. **绘图...
可以通过`invalidate()`或`postInvalidate()`方法请求重绘View,以反映温度变化。 5. **布局与测量**: - 在`onMeasure()`方法中,我们需要指定自定义View的大小。可以根据需求设置固定尺寸或者基于内容计算尺寸。...
- **invalidate()**和`postInvalidate()`:这两个方法用于触发View的重绘。当View的状态改变需要更新界面时,调用它们通知系统View需要重新绘制。 - **Choreographer**:Android系统的动画和绘制调度器,负责协调...
`invalidate()`方法是触发View重绘的关键。当调用`invalidate()`时,Android系统会把该View添加到待绘制队列中,稍后在UI线程的空闲时间进行重绘。这个过程会重新执行上述的测量、布局和绘制三个步骤。`invalidate()...
比如,如果扫描线只在一定范围内移动,那么我们只需要重绘这部分区域,而不是整个View。这可以通过`clipRect()`方法实现。 最后,作者可能分享了如何在布局文件中添加自定义View,并在运行时根据需要调整参数,如...
在优化性能时,避免频繁操作根View,以减少不必要的布局重绘,提高应用效率。 在提供的“RootActivity”示例中,可能包含了一个展示如何获取和使用根View的Activity实例。通过阅读源代码,开发者可以更深入地理解...
例如,减少不必要的重绘,避免在主线程进行耗时操作等。 在`awesome-view-master`这个项目中,你可能会发现各种自定义View的示例,它们涵盖了上述提到的技术点,包括自定义图形绘制、触摸事件处理、动画实现等。...
避免不必要的重绘,使用硬件加速,合理使用Bitmap缓存,以及利用View的复用机制(例如,RecyclerView的ViewHolder模式)都是提高性能的关键。 6. **源码分析**:标签中的"android view 源码"暗示这个资源可能包含对...
在Android开发中,我们使用自定义View来实现Checkbox的重绘。首先,我们需要创建一个新的类,继承自`AppCompatCheckBox`或`CompoundButton`。然后,我们覆盖`onDraw()`方法,这是绘制View的核心函数。在这个方法里,...
可以考虑使用`postInvalidate()`而不是`invalidate()`来避免不必要的重绘,或者使用`ObjectAnimator`来平滑地过渡动画效果。 6. 将自定义View添加到布局: - 在XML布局文件中,将自定义View包含进来,指定其宽度、...
可以利用硬件加速、减少不必要的重绘,以及合理使用`invalidate()`和`postInvalidate()`刷新视图。 8. **样式和主题**:自定义View也可以接受属性,这些属性可以设置在XML布局中,通过`attr.xml`定义,然后在`...
- 使用`Canvas.save()`和`Canvas.restore()`保存和恢复绘制状态,减少不必要的重绘。 - 使用硬件加速(`android:hardwareAccelerated="true"`),可以提高复杂的图形绘制性能。 10. **视图状态与样式** - View的...
通常,一个自定义进度条可能涉及到对View的重绘和动画处理。当进度条开始加载时,如果绘制逻辑出现问题,可能会导致在短时间内看到一个未填充的矩形形状,而不是预期的平滑过渡。这可能是由于初始状态的绘制不完整...
当进度值改变时,可以调用`invalidate()`方法触发视图重绘,这样`onDraw()`就会再次执行,更新进度条的显示。 此外,我们还可以添加触摸事件监听器,使用户可以通过滑动手指来改变进度。通过重写`onTouchEvent()`...
- 使用`ViewCompat.postInvalidateOnAnimation()`代替`invalidate()`,以在下一帧动画时更新视图,减少不必要的重绘。 5. **动画支持**: - 自定义View可以利用Android的动画框架实现平移、旋转、缩放等效果。...
由于自定义View需要频繁重绘,特别是在动画运行时,性能优化是必要的。开发者可能使用`invalidate()`方法合理地请求重绘,避免不必要的计算。同时,通过使用硬件加速和避免在`onDraw()`中执行耗时操作,可以提高...
无效化和重绘是View更新的关键,只有当View被标记为无效时,系统才会调用`onDraw()`进行重绘。 文件名称列表中的"TestLeavesLoading-master"可能是一个项目源码仓库,包含了一个完整的LeavesLoading自定义View的...