1

ユーザーが画面上で図形をドラッグできるアプリがあります。ドラッグにはカスタム サーフェス ビューを使用します。サーフェス ビューは OnTouchEvent を取得するたびに、グラフィック イメージの位置を変更し、OnDraw を呼び出して画面を更新します。

そのため、ビットマップ イメージは touchevent が発生するまで描画されません。コスチューム サーフェス ビューを無効にしようとしましたが、デバッガーによると、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
4

2 に答える 2

0

私は自分のアプリで同様の問題に直面しました。invalidate()は図形を再描画しません。したがって、私が見つけた解決策は、UIにコンポーネントを表示するクラスに形状を抽出し、UIクラスからコンポーネントにアクセスしてメインアクティビティからコンポーネントを更新することでした。

SurfaceViewクラス:

@Override public void onDraw(Canvas canvas){

    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クラス:

public void show(Viewアンカー、int色){preShow();

    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);


        }
    });

これにより、必要に応じてビューが更新されます。お役に立てれば

于 2012-11-24T09:24:00.920 に答える
0

別のクラスから呼び出すのではなく、コンストラクターinvalidate();の最後に呼び出しを追加しようとする場合があります。BallView(Context InContext,int w,int h)

于 2012-11-24T04:30:12.690 に答える