我的onDraw()方法永远不会被调用

时间:2016-04-07 12:13:32

标签: android

我的问题是,无论我做什么,无论我在互联网上阅读了多少问题和答案,我都无法在我的Android设备屏幕上绘制一个简单的矩形。让我重新说一下,它显示在屏幕上但它不会改变。我无法获得动画更新。 onDraw()从不调用多次,只在启动时调用一次。为什么?这是我的视图对象代码:

package prospect_industries.es;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class TestView extends View {

    //Variables
    public static final int SIZE = 300;
    public float TOP = 0.0f;
    public float LEFT = 0.0f;
    public float RIGHT = 100f;
    public float BOTTOM = 100f;

    private Paint rectanglePaint;
    private RectF rect1;

    //Constructors
    public TestView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public TestView(final Context context, final AttributeSet attrs) {
        super(context, attrs, 0);
        init();
    }

    public TestView(final Context context) {
        super(context, null, 0);
        init();
    }

    //View methods
    @Override
    protected void onDraw(final Canvas canvas){
        canvas.drawRect(rect1, rectanglePaint);
        Log.i("test1", "in onDraw");
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        final int chosenWidth = chooseDimension(widthMode, widthSize);
        final int chosenHeight = chooseDimension(heightMode, heightSize);
        setMeasuredDimension(chosenWidth, chosenHeight);
        Log.i("test1", String.valueOf(chosenWidth));
        Log.i("test1",String.valueOf(chosenHeight));
    }

    //Class Methods
    private int chooseDimension(final int mode, final int size) {
        switch (mode) {
            case MeasureSpec.AT_MOST:
            case MeasureSpec.EXACTLY:
                return size;
            case MeasureSpec.UNSPECIFIED:
            default:
                return getDefaultDimension();
        }
    }

    private int getDefaultDimension() { return SIZE; }

    private void init(){
        requestFocus();
        rectanglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        rectanglePaint.setColor(-1);
        rectanglePaint.setStyle(Paint.Style.FILL);

        rect1 = new RectF(LEFT, TOP, RIGHT, BOTTOM);
    }

    public void update() {
        RIGHT += 10;
        BOTTOM += 10;
        rect1 = new RectF(LEFT, TOP, RIGHT, BOTTOM);
        invalidate();
        Log.i("test1", "in update");
    }
}

这是我的主类,它有一些方法用于处理我正在处理的其他事情,以及一个调用我的测试视图对象内部的update()方法的计时器。

package prospect_industries.es;

import android.app.Activity;
import android.content.Context;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;


public class MainActivity extends Activity {

    private boolean setup = false;
    public int waitDelay = 1000; //Milliseconds - currently 1 second
    private Timer checkTime;
    private TimerTask listen;
    private MediaRecorder mRecorder;

    //Splashscreen
    private Timer splashScreen;
    private int waitTime = 3000; //3 seconds

    private GaugeView mGaugeView;
    private final Random RAND = new Random();
    private TestView testview;
    private SurfaceHolder surfaceHolder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);

        //mGaugeView = (GaugeView) findViewById(R.id.gauge_view);
        testview = (TestView) findViewById(R.id.test_view);
    }


    @Override
    public void onStart() {
        super.onStart();
        //Timers
        //1 second wait tick
        checkTime = new Timer();
        checkTime.schedule(new TimerTask() {
            public void run() {
                MainActivity.this.runOnUiThread(new Runnable() {
                    public void run() {
                        //mGaugeView.setTargetValue(RAND.nextInt(101));
                        testview.update();
                    }
                });
            }
        }, 0, waitDelay);

        //Set splash screen wait timer
        splashScreen = new Timer();
        splashScreen.schedule(new TimerTask() {
            public void run() {
                MainActivity.this.runOnUiThread(new Runnable() {
                    public void run() {
                        setContentView(R.layout.content_main);
                    }
                });
                splashScreen.cancel();
            }
        }, waitTime);

        //set welcome screen
        setContentView(R.layout.activity_welcome);
    }

    @Override
    public void onStop() {
        super.onStop();
        if(checkTime != null) {
            checkTime.cancel();
            stop();
        }
    }

    public void stop() {
        if (mRecorder != null) {
            mRecorder.stop();
            mRecorder.release();
            mRecorder = null;
        }
    }

    public double getAmplitude() {
        if (mRecorder != null)
            return  mRecorder.getMaxAmplitude();
        else
            return 0;

    }

    public void checkSound(){
        if (mRecorder == null) {
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            mRecorder.setOutputFile("/dev/null");
            try {
                mRecorder.prepare();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mRecorder.start();
        }
    }

    private static class MainView extends SurfaceView implements SurfaceHolder.Callback {

        private SurfaceHolder surfaceHolder;

        public MainView(Context context) {
            super(context);
            surfaceHolder = getHolder();
            surfaceHolder.addCallback(this);
        }

        @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

        }
    }
}

最后,这是在测试视图对象中加载的xml布局文件。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#103681"
    tools:context="prospect_industries.es.MainActivity">

    <prospect_industries.es.TestView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:id="@+id/test_view"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

我一直在看堆栈交换几个小时,但我无法解决我的问题,onDraw只调用一次,不管我做什么都不会再次调用。现在,矩形应该展开,但它不会被重绘。

1 个答案:

答案 0 :(得分:0)

问题是您将矩形初始化为1px宽和1px高,并且从不调整它的大小。您应该能够在TestView的左上角看到1个白色像素。

尝试将rect1大小更改为0,0,100,100并查看问题是否仍然存在。

public static final float TOP = 0.0f;
public static final float LEFT = 0.0f;
public static final float RIGHT = 100.0f;
public static final float BOTTOM = 100.0f;