Ondraw的自定义视图循环无限的android

时间:2011-10-12 03:34:09

标签: android ondraw

我的自定义View的OnDraw函数被无限调用并且正在循环!可能的原因是什么?

这是我的自定义视图: -

public class Balls extends View{

    private static final String TAG = "BallsView";

    private int mMode = READY;
    public static final int PAUSE = 0;
    public static final int READY = 1;
    public static final int RUNNING = 2;
    public static final int LOSE = 3;

    private final Paint mPaint = new Paint();
    private double mUx = 0.1;
    private double  mUy = 2;
    private double mVy;
    private double mVx;
    private double mSx;
    private double mSy;
    private double mRange;
    private float mX1;
    private float mY1;
    private int mX2;
    private int mY2;
    private int mDx;
    private int mDy;
    Time t;
    float mAngle;
    private final double mGravity = -9.8;

    private long mLastTime;

    private double mT;

    private Canvas mCanvas = null;



    public Balls(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);
        setFocusable(true);
        setWillNotDraw(false);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE); 
        mPaint.setStrokeWidth(10); 
        mPaint.setAntiAlias(true); 
        mPaint.setStrokeCap(Cap.ROUND); 
        //mPaint.setColor(0xff00ffff);
        mPaint.setARGB(255, 0, 255, 0);

        mLastTime = System.currentTimeMillis();


    }
    public Balls(Context context, AttributeSet attrs) {
        super(context, attrs);
         setFocusable(true);
         setWillNotDraw(false);
          mPaint.setStyle(Paint.Style.FILL_AND_STROKE); 
          mPaint.setStrokeWidth(10); 
          mPaint.setAntiAlias(true); 
          mPaint.setStrokeCap(Cap.ROUND); 
          mPaint.setColor(0xff00ffff);

    }

     @Override
    public void onDraw(Canvas canvas) {
         Log.w(this.getClass().getName(),"onDraw of Balls called");
      super.onDraw(canvas);
      mCanvas = canvas;

      if(mCanvas!= null)
          Log.w(this.getClass().getName(),"Canvas is not null");

    }

此观点在另一项活动中夸大如下: -

mBalls = (Balls) findViewById(R.id.balls);

此视图位于相对视图内的xml文件中,相对视图是水平滚动视图的子视图。

4 个答案:

答案 0 :(得分:5)

这里没有无限循环。发生的事情是操作系统正在尽快重新绘制您的活动。当您的活动重新绘制时,它会重绘其所有子视图。由于你的代码计算量很少,从我在这里看到的,它运行速度非常快,并且可能以大于30 FPS的速率重绘。您的日志消息使其看起来好像存在无限循环。事实上,onDraw方法中甚至没有循环。

为了说明发生了什么,试试这个。将受保护的成员drawCount添加到Balls类并将其设置为0:

protect int drawCount = 0;

然后将drawCount附加到onDraw日志消息的末尾

 public void onDraw(Canvas canvas){
       drawCount++;
       Log.w(this.getClass().getName(),"onDraw of Balls called. Total draws:" + Integer.toString(drawCount));
  ...
  }

您应该看到的是每条日志消息都会显示不同的drawCount。

如果你想得到想象并计算你的应用程序的帧率,你可以测量自第一次抽奖以来的时间,然后将drawCount除以已经过了多少时间,这将估计你的活动帧率

答案 1 :(得分:3)

onDraw()在invalidate处调用。当视图或其父级感觉需要更改并且必须更改其状态时,会调用Invalidate()。

答案 2 :(得分:2)

onDraw(Canvas)经常被称为无限循环,这是不正常的。 通常,如果没有跟随invalidate或布局更改,则应调用1到3次。 无限循环的原因可能是:
1,您在某处注明了invalidatepostInvalidate 2,父母或兄弟姐妹的布局一直在变化 3,使用View.LAYER_TYPE_SOFTWARE,es。 setLayerType(View.LAYER_TYPE_SOFTWARE,null)。
值得注意的是,LAYER_TYPE_SOFTWARE将导致onDraw()被调用,就像在循环中一样。

答案 3 :(得分:0)

之所以如此,是因为我有一些代码正在修改被覆盖的DispatchDraw中的UI。