My issue is that no matter what I do, no matter how many questions and answers I read through on the internet, I cant get a simple rectangle to draw on my android device screen. Let me rephrase that, it shows up on screen but it wont change. I cant get an animation to update. onDraw() never calls multiple times, just once on startup. why? Here is my view objects code:
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");
}
}
Here is my main class which has a few methods for other things Im working on as well as a timer which calls the update() method inside of my test view object.
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
}
}
}
Lastly, here is the xml layout file which loads in the test view object.
<?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>
I have been looking all over stackExchange for hours but I cant fix my problem, onDraw is only called once and never again no matter what I do. Right now the rectangle should be expanding out but it isnt being redrawn.