How can I redraw a View after a TouchEvent? - android

I subclassed View to get an View on which the user can "draw" with his fingers. I implemented the Interface View.OnTouchListener.
How can I trigger within the onTouch method the redraw of the View? Do I need to implement a Thread / Runnable? I thought that invalidate() triggers the redraw, but this doesn't work.

Just call this.invalidate in the onTouchEvent method of your view, it really should work unless you're not doing the proper thing in your onDraw method. Make sure you're referencing to the right canvas an draw the thing in your overridden onDraw method instead of for example the constructor.
#Override
public boolean onTouchEvent(MotionEvent event) {
this.invalidate();
return true;
}

Related

View draw complete callback

What event signifies that the draw of a View is complete?
I know about ViewTreeObserver listeners, but I couldn't find the 'final' one, which indicates, that the job is done.
yourView.post(someRunnable) ensures, that someRunnable will be executed after the view is laid out and drawn.
What event signifies that the draw of a TextView is complete?
There is no such hook for View class (or TextView). There is, however, onDraw() method which is called when the view should render its content.
So you can do:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Finished drawing. Do other stuff.
// However you must check if this is the first or subsequent call.
// Each call to "invalidate()" will trigger re-drawing.
}
If I understand your question correctly the method you are looking for is onWindowFocusChanged(boolean hasFocus). Or else you could try the onPostResume() method.

Listener when hovering view Android

The user can draw over view (with a pencil) and i want a listener to know if the user was drawn over other views. When the user is drawing over a view, i want to change the view's color.
I tried with OnTouchListener, OnHoverListener, OnFocusChangeListener i also tried to override the method onTouchEvent, but none of these were called.
Screenshot of the sample:
http://imgur.com/u3tkwRN
You should handle onTouchListener by calling ViewObject.setOnTouchListener the OnTouchListener passes to argument . The first is the Calling View and the second is a MotionEvent object . The motion event has a getAction() method than returns a integer you should write a if statement and check whether the getAction() value equals to MotionEvent.ACTION_DOWN . In the block of the if statement write your code . Also you can handle unhover event by write another if statement and check whether the getAction() integer equals to MotionEvent.ACTION_UP and write another code in if block statement . Your problem will be solved completely.

How do I disable onTouchEvent listener for custom view

I have a custom view that I created by extending the View class. My custom view overrides the onTouchEvent.
I want to be able to turn the view's ability to listen on and off. I need to do that from within the view. Does anyone know how I can accomplish this? Simply calling
setEnabled(false);
does not work.
Try by setting the following
setOnTouchListener(null)
I'm not sure if this is the right solution but it works:
this.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return true;
}
});
This blocks other touch related Listeners from receiving the Event, so onTouchEvent won't be invoked.
you can use setOnTouchListener(null) to go back to your normal state so that your onTouchEvent works again.
if you had figured out a better solution i hope that you post it.

Detecting when a View has been invalidated

In a custom View, I need to perform some additional work inside onDraw() if and only if the View was invalidated by the application; that is, my own code called invalidate() in the UI thread or postInvalidate() in a non-UI thread. If on the other hand onDraw() is being called because the system invalidated the View, I don't wish that additional work to be performed.
What's the best way to achieve this? My immediate thought is to simply override invalidate() and postInvalidate() and set a flag in both of those, but it would be nicer if there was a single UI-thread method I could override.
Any thoughts please?
Thanks, Trev
postInvalidate() ends up calling invalidate() so you don't need to override both. But if you override invalidate(), the system will call the overridden version.
There is a way to do that without extending view class.
view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
#Override
public void onDraw() {
//View was invalidated
}
});

setOnTouchListener not called on ViewFlipper

I want to listen to touch events for a viewFlipper. I've been able to listen to touch events in my activity and then modify the viewFlipper but these events are fired wherever the user is within the activity and I need to capture touch events specifically on the viewFlipper. I have tried adding setOnTouchListener but it is not called. I'm assuming the viewFlippers children (webviews) are 'consuming' the touch events.
One solution would be to setOnTouchListener's to each of the webviews but this feels like a hack. Does anyone know another way?
Thanks,
Ian
Sorry if this is a double post - but my previous post seems to have vanished.
Use ViewGroup.onInterceptTouchEvent(MotionEvent)
You should Reference the Android Documentation as it's usage is quite complicated.
Basic Summary of use:
You receive the touch event here. If you want to consume it, return true and control will be passed to the ViewFlipper's onTouchEvent(). Return false and it will continue to be passed to the child. onTouchEvent() should also return true to ensure all further events are returned to the ViewFlipper's method. The child will also receive the original event with the action ACTION_CANCEL.
Finally It worked for me. Return true by default to get multiple calls on this listener.
viewFlipper.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (this.gestureDetector.onTouchEvent(event)) {
return false;
}
return true;
}
});
I was having the same problem and found your page trying to google for an answer.
After a few very frustrating attempts I ended up finding a quite easy solution, I'm still listening to the touch on the whole activity just like you did, but on the OnTouchEvent I filter if the ViewFlippers is touched or not:
#Override
public boolean onTouchEvent(MotionEvent event) {
if(mFlip.isInTouchMode()){
return gestureDetector.onTouchEvent(event);
} else{
return super.onTouchEvent(event);
}
}
hope it helps!

Categories

Resources