2012-11-24 139 views
1

我有一個應用程序,允許用戶在屏幕上拖動形狀。我使用自定義表面視圖進行拖動。每次表面視圖獲取OnTouchEvent時,它都會更改圖形圖像的位置並調用OnDraw來更新屏幕。無效不更新屏幕

因此,位圖圖像直到觸發事件發生時纔會被繪製。我試圖使服裝表面視圖無效,但根據調試器,OnDraw永遠不會被調用。

所以現在我的屏幕是空白的,直到有人觸摸屏幕

//代碼

public class cPlay extends cBase implements OnClickListener { 
    /** Called when the activity is first created. */ 
    // sound 
    private SoundPool soundPool; 
    private int soundID; 
    boolean loaded = false; 

    @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
     //  setContentView(R.layout.play); 


      int w=getWindowManager().getDefaultDisplay().getWidth(); 
      int h=getWindowManager().getDefaultDisplay().getHeight(); 

      BallView ballView=new BallView(this,w,h); 
      setContentView(ballView); 

      // Does not update screen?????? 
      ballView.invalidate(); 
       .... 
... 
....} // end of class 

public class BallView extends SurfaceView implements SurfaceHolder.Callback { 
    private Bitmap bitmap ; 
    private int x=20,y=20;int width,height; 
    cShapeParent MyShapes; 
    cTarget MyTargetShapes; 
    Context context; 
    int counter=0; 

    // sound 
    private SoundPool soundPool; 
    private int soundID; 
    boolean loaded = false; 

    public BallView(Context InContext,int w,int h) { 
     super(InContext); 

     context=InContext; 
     int counter=0; 
     int Page=0; 
     width=w; 
     height=h; 
     getHolder().addCallback(this); 
     setFocusable(true); 
     MyShapes=new cShapeParent(context,w,h); 
     MyTargetShapes= new cTarget(context,w,h); 
     MyShapes.SetTargets( MyTargetShapes); 
     // load in bitmaps 



    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 




     bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.ball_green); 
     canvas.drawColor(Color.BLUE);//To make background 
    //  canvas.drawBitmap(bitmap,x-(bitmap.getWidth()/2),y-(bitmap.getHeight()/2),null); 

     // See if we shoyld drag it 
     for(int i=MyShapes.Amount-1; i>=0; i--) 
     { 
      if (MyShapes.Intersect(i,x,y))   
      { 
      // see if we can drag it 
       if (MyShapes.getDragFlag(i)==false) 
       break; 

       // yes drag this image 
       MyShapes.SetCenter(i, x, y); 

       // if the target was found 
       // make it so we can no loner drag it 
       if (MyShapes.CheckTarget(i)) 
       { 
        MyShapes.SetDrag(i,false); 
        MyShapes.SetToTarget(i); 
        if (++counter>2) 
         DisplayNextScreen(); 
       } 
       break; 
      } 
     }  

     // Draw target shapes 
     // NOTE: draw these first so they are on the bottom 
     for(int i=0; i<MyShapes.Amount;i++) 
     { 
      int x=MyTargetShapes.GetX(i); 
      int y=MyTargetShapes.GetY(i); 
      int w=MyTargetShapes.GetW(i); 
      int h=MyTargetShapes.GetH(i); 

      Rect br=new Rect(x, y,w+x, h+y); 
      Bitmap m= MyTargetShapes.MyImages[i]; 
      canvas.drawBitmap(m, null, br, null); 
     }  

     // Draw shapes that can be dragged 
     for(int i=0; i<MyShapes.Amount;i++) 
     { 
      int x=MyShapes.GetX(i); 
      int y=MyShapes.GetY(i); 
      int w=MyShapes.GetW(i); 
      int h=MyShapes.GetH(i); 
      Rect br=new Rect(x, y, x+w,y+h); 
      Bitmap m= MyShapes.MyImages[i]; 
      canvas.drawBitmap(m, null, br, null); 
     } 




    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     x=(int)event.getX(); 
     y=(int)event.getY(); 

     if(x<25) 
      x=25; 
     if(x> width) 
      x=width; 
     if(y <25) 
      y=25; 
     if(y > height) 
      y=height; 

     updateBall(); 

     return true; 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // TODO Auto-generated method stub 
    } 

    private void updateBall() { 
     Canvas canvas = null; 
     try { 
      canvas = getHolder().lockCanvas(null); 
      synchronized (getHolder()) { 
       this.onDraw(canvas); 
      } 
     } 
     finally { 
      if (canvas != null) { 
       getHolder().unlockCanvasAndPost(canvas); 
      } 
     } 
    } 

    void DisplayNextScreen() 
    { 
      ///////////////////////////////////// 
     // call up dialog 
     final Dialog dialog = new Dialog(context); 
     dialog.setContentView(R.layout.custom); 
     dialog.setTitle("Title..."); 

     // set the custom dialog components - text, image and button 
     TextView text = (TextView) dialog.findViewById(R.id.text); 
     text.setText("Android custom dialog example!"); 
     ImageView image = (ImageView) dialog.findViewById(R.id.image); 
     image.setImageResource(R.drawable.ic_launcher); 

     Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK); 
     // if button is clicked, close the custom dialog 

     dialogButton.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       dialog.dismiss(); 
       MyTargetShapes.SetUp(1); 
       MyShapes.SetUp(1); 
       MyShapes.SetTargets( MyTargetShapes); 
       counter =0; 
      } 
     }); 

     dialog.show(); 
    } // end methed 


    void StartSound(int soundID) 
    { 
     AudioManager audioManager = (AudioManager) context.getSystemService("audio"); 
     float actualVolume = (float) audioManager 
       .getStreamVolume(AudioManager.STREAM_MUSIC); 
     float maxVolume = (float) audioManager 
       .getStreamMaxVolume(AudioManager.STREAM_MUSIC); 
     float volume = actualVolume/maxVolume; 
     // Is the sound loaded already? 

      soundPool.play(soundID, volume, volume, 1, 0, 1f); 
     // Log.e("Test", "Playe"); 

    } 

} // end class 

回答

0

我在我的應用程序中遇到過類似的問題。 invalidate()不重繪形狀。所以我找到的解決方案是將形狀提取到顯示UI上組件的類中,然後通過從UI類訪問該組件來從主活動更新組件。

SurfaceView類:

@Override 公共無效的onDraw(帆布帆布){

Log.d("check","="+color); 
    Log.e("check","after set:"+buf); 
    Log.i("new view ", " on draw "); 
    paint.setStyle(Paint.Style.STROKE); 
    paint.setStrokeWidth(5); 
    paint.setColor(Color.WHITE); 

    path = new Path(); 
    path.moveTo(0, 30);        /*For Borders*/ 
    path.lineTo(30, 0); 
    path.lineTo(-30, 0); 
    path.close(); 
    path.offset(20, -5); 
    canvas.drawPath(path, paint); 

UI類:

公共無效節目(觀看錨,INT顏色){ 預演( );

int xPos, yPos, arrowPos; 

    mDidAction = false; 
    } 

    showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), arrowPos,color); 

    setAnimationStyle(screenWidth, anchorRect.centerX(), onTop); 
    mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos); 


} 

R.id.arrow_down是使用NewView類繪製的形狀。

在對事件的主要活動調用該函數是這樣的:

btn1 = (Button) this.findViewById(R.id.btn1); 
    btn1.setOnClickListener(new View.OnClickListener() { 

     public void onClick(View v) { 


      Log.d("In","View"); 
      quickAction.show(v,Color.BLUE); 


     } 
    }); 

要求這將更新視圖。 希望這會有幫助

0

您可以嘗試invalidate();添加調用,而不是從調用它來BallView(Context InContext,int w,int h)構造年底,一個不同的班級。