Elena Elena - 1 year ago 399
Android Question

invalidate() does not call onDraw(), Android Studio

I'm new in Android and need help.
In my code I use onTouchEven() to move ImageView, but invalidate() doesn't call onDraw(). I'm looking for solution all over the Internet and stil can't see my mistake. Please, help.

map - this is my ImageView I want to drag.

public class MainActivity extends AppCompatActivity {
TextView infoSpace;
ImageView map;
ImageButton updateButton;
String currentDateTimeString;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(com.example.eleizo.firstapplication.R.layout.activity_main);

map = (ImageView) findViewById(R.id.map);

map.setWillNotDraw(false);
map.setOnTouchListener(new View.OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event){
Context context = getApplicationContext();
new CustomImageView(context).onTouchEvent(event);
return true;
}
});

}

private class CustomImageView extends View {

private float mLastTouchX;
private float mLastTouchY;
private float mPosX;
private float mPosY;

//the active pointer is one currently moving object
private static final int INVALID_POINTER_ID = -1;
private int mActivePointerId = INVALID_POINTER_ID;

public CustomImageView(Context context) {
super(context);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getActionMasked();


switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
Log.d("DEBUG","MotionEvent.ACTION_DOWN");
final float x = ev.getX();
final float y = ev.getY();
mLastTouchX = x;
mLastTouchX = y;
mActivePointerId = ev.getPointerId(0);
break;
}

case MotionEvent.ACTION_MOVE: {
Log.d("DEBUG","MotionEvent.ACTION_MOVE");
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
final float x = ev.getX(pointerIndex);
final float y = ev.getY(pointerIndex);
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
this.setX(x+mPosX);
this.setY(y+mPosY);

invalidate();
Log.d("DEBUG",String.format("AFTER invalidate(): %f %f", mPosX, mPosY));

mLastTouchX = x;
mLastTouchY = y;

break;
}

case MotionEvent.ACTION_UP: {
Log.d("DEBUG","MotionEvent.ACTION_UP");
mActivePointerId = INVALID_POINTER_ID;
break;
}

case MotionEvent.ACTION_CANCEL: {
Log.d("DEBUG","MotionEvent.ACTION_CANCEL");
mActivePointerId = INVALID_POINTER_ID;
break;
}

case MotionEvent.ACTION_POINTER_UP: {
Log.d("DEBUG","MotionEvent.ACTION_POINTER_UP");
final int pointerIndex = ev.getActionIndex();
final int pointerId = ev.getPointerId(pointerIndex);

if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
}
break;
}
}
return true;
}

@Override
protected void onDraw (Canvas canvas){
Log.d("DEBUG","OnDraw()");
super.onDraw(canvas);
canvas.save();
canvas.translate(mPosX,mPosY);
canvas.restore();

}
}


When I touch map I can see log "AFTER invalidate():.."

But never can see log "OnDraw()".

Answer Source
new CustomImageView(context).onTouchEvent(event);

You're not saving a reference to your CustomImageView object. You're creating an object, calling onTouchEvent yourself, but you're not storing a reference or giving a reference to whichever class calls onDraw.

Maybe make your map object of type CustomImageView rather than ImageView

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download