onDraw not being called

Put problem concerning Views, Layouts and other XML-Resources (like AndroidManifest) here.

onDraw not being called

Postby spirolateral » Tue Oct 14, 2008 5:20 am

hey,

i have a custom view derived from SurfaceView which i'm trying to draw on. at the moment i just fill it in a solid color and have a menu item which i'm trying to make change the color. so when the menu item is pressed, the function called changes the color value and then calls invalidate. my onDraw function then uses this value and tries to fill in with a new color. i call invalidate() after changing the value to force onDraw to be called, but it never is called. i put a log line in onDraw to see if it's being called and the log is never being printed out any ideas on what i could be doing wrong? thanks.
spirolateral
Developer
Developer
 
Posts: 25
Joined: Tue Oct 14, 2008 5:15 am

Top

Postby MrSnowflake » Tue Oct 14, 2008 7:16 am

Check my 2D tutorial or my DroidGaming system for some code on how to do this.
User avatar
MrSnowflake
Moderator
Moderator
 
Posts: 1439
Joined: Sat Feb 16, 2008 3:11 pm
Location: Flanders, Belgium

Postby spirolateral » Tue Oct 14, 2008 7:57 am

thanks for the reply. so i looked at your examples. it seems like you're doing all the drawing in a separate thread. is that correct? is that the only way to accomplish this? i thought if i changed some aspect about the view then invalidated it that it should call its onDraw method to redraw the view. is that not correct?
spirolateral
Developer
Developer
 
Posts: 25
Joined: Tue Oct 14, 2008 5:15 am

Postby MrSnowflake » Tue Oct 14, 2008 7:59 am

Yes I do the drawing in another thread. As I don't want the ui-thread to be looping over my drawing code (to get the highest fps as possible), because then I'm affraid, I won't get anykey input. Don't know if this is true.

And about the invalidate() stuff: That's stuff I don't really know a lot about :).
User avatar
MrSnowflake
Moderator
Moderator
 
Posts: 1439
Joined: Sat Feb 16, 2008 3:11 pm
Location: Flanders, Belgium

Postby spirolateral » Tue Oct 14, 2008 8:04 am

your approach makes sense because you're doing a lot of drawing for a game. for me i don't want any drawing done unless the screen needs updating, which is when the OS determines the screen needs redrawing or if i make a change and want it redrawn. i just don't understand why onDraw is not being called...

thanks anyway. anyone else have any ideas?
spirolateral
Developer
Developer
 
Posts: 25
Joined: Tue Oct 14, 2008 5:15 am

Postby MrSnowflake » Tue Oct 14, 2008 8:15 am

Are you sure you added the View to the ContentView?

I only experimented with drawing directly in a View, and soon switched to thread/SurfaceView based drawing, so I don't really know how to do the stuff you want. Could you maybe post some snippets of your code and the layout xml?
User avatar
MrSnowflake
Moderator
Moderator
 
Posts: 1439
Joined: Sat Feb 16, 2008 3:11 pm
Location: Flanders, Belgium

Top

Postby c3r13e12u5 » Tue Oct 14, 2008 11:37 am

hi Spirolateral!

Maybe the demo I made below could help you:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.  
  3.  
  4. public class myActivityName extends Activity {
  5.  
  6.         public static sview sv;
  7.  
  8.         public static Activity instance;
  9.  
  10.         public Handler handler = new Handler(){
  11.  
  12.                 public void handleMessage(Message msg) {
  13.  
  14.                         sv.changeBG(0, 255, 0);
  15.  
  16.                         sv.invalidate();
  17.  
  18.                 }
  19.  
  20.         };
  21.  
  22.        
  23.  
  24.         @Override
  25.  
  26.         public void onCreate(Bundle savedInstanceState) {
  27.  
  28.                 super.onCreate(savedInstanceState);
  29.  
  30.                 instance = this;
  31.  
  32.                 sv = new sview(this);
  33.  
  34.                 setContentView(sv);
  35.  
  36.                 Timer t = new Timer();
  37.  
  38.                 TimerTask task = new TimerTask() {
  39.  
  40.                         @Override
  41.  
  42.                         public void run() {
  43.  
  44.                                 handler.sendEmptyMessage(0);
  45.  
  46.                         }
  47.  
  48.                 };
  49.  
  50.                 t.schedule(task,3000);
  51.  
  52.                 sv.changeBG(0, 0, 255);
  53.  
  54.                 sv.invalidate();
  55.  
  56.         }
  57.  
  58.        
  59.  
  60.         class sview extends SurfaceView{
  61.  
  62.  
  63.  
  64.                 public sview(Context context) {
  65.  
  66.                         super(context);
  67.  
  68.                         changeBG(255, 0, 0);
  69.  
  70.                 }
  71.  
  72.                 @Override
  73.  
  74.                 protected void onDraw(Canvas canvas) {
  75.  
  76.                         super.onDraw(canvas);
  77.  
  78.                 }
  79.  
  80.                 public void changeBG(int r, int g, int b){
  81.  
  82.                         System.out.println("change bg: "+r+","+g+","+b);
  83.  
  84.                         setBackgroundColor(Color.rgb(r, g, b));
  85.  
  86.                         invalidate();
  87.  
  88.                 }
  89.  
  90.         }
  91.  
  92.                
  93.  
  94. }
Parsed in 0.033 seconds, using GeSHi 1.0.8.4


Basically I use Handler to made the changes and to invalidate the view.
In the demo I put BG color as red when the view is created.
change to blue right after it create timer and run it.
and change to green when the timer trigger the task.
c3r13e12u5
Developer
Developer
 
Posts: 28
Joined: Wed Oct 08, 2008 7:33 am

Postby spirolateral » Tue Oct 14, 2008 9:13 pm

so here is an example of what i have:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. public class MyView extends SurfaceView implements SurfaceHolder.Callback
  3.  
  4. {
  5.  
  6.         protected static final int STATE_OFF=0;
  7.  
  8.         protected static final int STATE_ON=1;
  9.  
  10.         private static final int onColor = Color.WHITE;
  11.  
  12.         private static final int offColor = Color.BLACK;
  13.  
  14.  
  15.  
  16.         protected int mState;
  17.  
  18.         protected SurfaceHolder mHolder;
  19.  
  20.        
  21.  
  22.         @Override
  23.  
  24.         protected void onDraw(Canvas canvas)
  25.  
  26.         {      
  27.  
  28.                 canvas.drawColor(mState == STATE_ON ? onColor : offColor);
  29.  
  30.         }
  31.  
  32.  
  33.  
  34.         public MyView(Context context)
  35.  
  36.         {
  37.  
  38.                 super(context);
  39.  
  40.                 initialize();
  41.  
  42.         }
  43.  
  44.  
  45.  
  46.         public MyView(Context context, AttributeSet attrs)
  47.  
  48.         {
  49.  
  50.                 super(context, attrs); 
  51.  
  52.                 initialize();
  53.  
  54.         }
  55.  
  56.  
  57.  
  58.         public MyView(Context context, AttributeSet attrs, int defStyle)
  59.  
  60.         {
  61.  
  62.                 super(context, attrs, defStyle);               
  63.  
  64.                 initialize();
  65.  
  66.         }
  67.  
  68.        
  69.  
  70.         private void initialize()
  71.  
  72.         {
  73.  
  74.                 mState = STATE_OFF;
  75.  
  76.                 mHolder = this.getHolder();
  77.  
  78.                 mHolder.addCallback(this);
  79.  
  80.         }
  81.  
  82.  
  83.  
  84.         public void surfaceCreated(SurfaceHolder holder)
  85.  
  86.         {
  87.  
  88.                 mState = STATE_ON;
  89.  
  90.         }
  91.  
  92.  
  93.  
  94.         public void surfaceDestroyed(SurfaceHolder holder)
  95.  
  96.         {
  97.  
  98.                 mState = STATE_OFF;
  99.  
  100.         }
  101.  
  102.        
  103.  
  104.         public void changeState()
  105.  
  106.         {      
  107.  
  108.                 if(mState == STATE_ON)
  109.  
  110.                         mState = STATE_OFF;
  111.  
  112.                 else
  113.  
  114.                         mState = STATE_ON;
  115.  
  116.                
  117.  
  118.                 invalidate();
  119.  
  120.         }
  121.  
  122.        
  123.  
  124.         public int getState()
  125.  
  126.         {
  127.  
  128.                 return mState;
  129.  
  130.         }
  131.  
  132.        
  133.  
  134.         public void setState(int state)
  135.  
  136.         {
  137.  
  138.                 mState = state;
  139.  
  140.                 invalidate();
  141.  
  142.         }
  143.  
  144. }
  145.  
  146.  
Parsed in 0.036 seconds, using GeSHi 1.0.8.4


this is not exactly what i have, i do some other stuff not related to this. from the activity i created a menu item that calls the changeState method which calls invalidate, which should call my onDraw, but never does. any ideas?
spirolateral
Developer
Developer
 
Posts: 25
Joined: Tue Oct 14, 2008 5:15 am

Postby MrSnowflake » Tue Oct 14, 2008 9:46 pm

How about doing it in draw() instead of onDraw()??
User avatar
MrSnowflake
Moderator
Moderator
 
Posts: 1439
Joined: Sat Feb 16, 2008 3:11 pm
Location: Flanders, Belgium

Postby spirolateral » Tue Oct 14, 2008 9:52 pm

is "draw" the method called when the screen needs to be repainted or is it "onDraw"? i'll try. i thought onDraw was what was called though.
spirolateral
Developer
Developer
 
Posts: 25
Joined: Tue Oct 14, 2008 5:15 am

Postby spirolateral » Tue Oct 14, 2008 10:01 pm

still nothing. i overrode SurfaceView's draw method and it's not getting called...
spirolateral
Developer
Developer
 
Posts: 25
Joined: Tue Oct 14, 2008 5:15 am

Postby MrSnowflake » Tue Oct 14, 2008 10:12 pm

I think the SurfaceView doesn't do the normal draw routine, but you should draw directly to the canvas of the SurfaceView in some routine using:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.             try {
  3.  
  4.                canvas = mSurfaceHolder.lockCanvas(null);
  5.  
  6.                 synchronized (mSurfaceHolder) {
  7.  
  8.                   // Draw you stuff
  9.  
  10.                 }
  11.  
  12.             } finally {
  13.  
  14.                 // do this in a finally so that if an exception is thrown
  15.  
  16.                 // during the above, we don't leave the Surface in an
  17.  
  18.                 // inconsistent state
  19.  
  20.                 if (canvas != null) {
  21.  
  22.                     mSurfaceHolder.unlockCanvasAndPost(canvas);
  23.  
  24.                 }
  25.  
  26.             }
  27.  
  28.  
Parsed in 0.035 seconds, using GeSHi 1.0.8.4
User avatar
MrSnowflake
Moderator
Moderator
 
Posts: 1439
Joined: Sat Feb 16, 2008 3:11 pm
Location: Flanders, Belgium

Postby spirolateral » Tue Oct 14, 2008 10:27 pm

awesome! thanks. drawing directly works. this still seems weird to me though. i was under the impression that Views when invalidated would call their onDraw method.
spirolateral
Developer
Developer
 
Posts: 25
Joined: Tue Oct 14, 2008 5:15 am

Postby MrSnowflake » Tue Oct 14, 2008 10:29 pm

But SurfaceView IS a special case! :). If you want to make an ordinary view (not high on graphics), you should extend View
User avatar
MrSnowflake
Moderator
Moderator
 
Posts: 1439
Joined: Sat Feb 16, 2008 3:11 pm
Location: Flanders, Belgium

Postby spirolateral » Tue Oct 14, 2008 10:30 pm

ok :) thanks a lot for your help. i'm sure i'll need some more soon!
spirolateral
Developer
Developer
 
Posts: 25
Joined: Tue Oct 14, 2008 5:15 am

Top
Next

Return to View, Layout & Resource Problems

Who is online

Users browsing this forum: No registered users and 4 guests