I'm working on a project that using custom views created with Android Canvas. And I'm stuck in the next part: How to create custom animations for elements on Android Canvas (the idea), where I cannot use the already-supported-animations. Any idea or example is appreciated! Thanks!
The simplest approach is to hold some state variables in your View. Then you can use ValueAnimator or ObjectAnimator. Former will trigger ValueAnimator.AnimatorUpdateListener where you can modify view state in proper way and then invalidate(), which trigger redrawing. Latter will update view state via setSmth() methods, that you should implement on your view. At the end of these setters you should call invalidate() too. And in your onDraw() you need to draw proper things depending on actual values of state variables
Related
I want to show an animation when a certain action happens in my application. This animation shall overlay a listview. From what I understand, this should be possible with a ViewOverlay, but I'm struggling with getting the basics to work currently.
What I tried is to simply display a vector drawable that I already have on top of my list view. In my activity's onCreate() I have the following code:
Drawable d = getResources().getDrawable(R.drawable.backspace);
d.setBounds(0,0, listview.getMeasuredWidth(), listview.getMeasuredHeight());
listview.getOverlay().add(d);
Shouldn't this display my drawable somewhere on top of my listview? For me it doesn't - what am I missing?
Solution: listview.post(() -> listview.getOverlay().add(d));
There was no layout pass happen yet at onCreate so your views are not measured yet. Defer overlay operation into post method - your view will have been measured at that time so you will have correct values to use.
I have a custom Transition used in shared elements between my two Activities.
My transition doesn't work because the TransitionValues parameters has the same View with same attributes in both methods, captureStartValues and captureEndValues. So, my transition doesn't have what to do once the start and end values are the same.
Why is this happens?
In my case i wanted to transition between two element's background drawable.
After a lot of digging i ended getting to the realization that the view delivered to the onCaptureStartValues method is not the actual view from the first activity but rather a representation of it created in the second activity from a parcel passed down by the transition framework.
This is counter intuitive but eventually lead me to the following article which have an informative example on how to accomplish what you're after.
https://medium.com/#belokon.roman/custom-transitions-in-android-f8949870bd63
In general you use SharedElementCallback to inject custom properties into your transition object.
I really hope this kind of behavior will change in the future as it feels hack-ish.
You must set a SharedElementCallback using setEnterSharedElementCallback and override the onSharedElementStart and onSharedElementEnd and set the scroll at both the start and end. When it reverses, the end is called before the start to invert the transition.
For some reason (that I can develop if you want/need) I have to redraw all the chart periodically. So, I use removeAllSeries then addSeries, plus removeAllViews then addView. It works but the problem is that addView adds the view not by simply refreshing all pixels of the tablet but with a sort of "animation" that puts firstly the View a little bit (2 or 3 pixels) shifted to the right and then it takes the right place. The consequence is that, everytime I redraw my graph, it looks as if there is a "vibration" (it's not fluid).
Do anyone have some issue? Could this undesired "animation" be related to how the addView method is done?
there are three ways:
redrawAll() method. Maybe it is protected, but you can overwrite and
make it public
change the data in series (appendData or resetData). The Graph will
automatically rerender.
removeAllSeries + add new series. No need to call
removeAllViews/addView. Take a look at the GraphViews-Demos project,
there is an example about that.
Cheers
Thank you for your answer ! I actually just simply overrided the ValueDependentColor() method directly in my main activity. The color depends on a timer. So, when I reset data after x seconds the graph rerenders as you said in your "2."
i'm building my interactive map and i find myself really confused:
I have an extend of ItemizedOverlay class which i'm managing the overlays.
when shell i use its populate() function in order to update the overlays in the mapView and when should i use invalidate() or postInvalidate() in order to get the map to update.
i found that sometimes this works, and sometimes the other.
if someone will be kind to explain exactly what each of the function does - i will be thanks full because i couldn't find a decent explanation.
populate() should be used when you want to populate the overlay. If all you want to do is have it redrawn, then you should use invalidate() if you're on the UI thread, and postInvalidate() if you're on another thread. The invalidate methods are applicable to any View, be it a button or a text view or anything. They basically tell Android that something has changed related to the View, like the data being shown or the button's state or colour or whatever. Android will then attempt to redraw the View as soon as possible by calling the View's onDraw() method.
I always use invalidate() and never had a problem with it... (i.e. always refreshes)
Here's the basic UI i intend:
There is central circle:CENTER. As the view is rotated, new circles:NAME are generated on the circumference. The circle at the top is a newly generated circle, i.e. if an already generated circle passes the top it fetches a new name.
I don't know the Android API well enough yet, so can someone point me in the right direction? What classes should I look at? How can I create that sort of pathing? Do I generate circle programmatically or have the views already in the xml layout but invis?
Thanks.
EDIT: Currently I'm working on the custom views that will be each circle.
I think you could do it by extending AdapterView. I would start by looking at the source code for it and some of its decedents to see how they implemented them.
The functionality you are after I don't think is very far removed from a ListView or some of the other simple Adapter ready View widgets.
The main difference is going to be your onDraw() method, you'll need to override that to draw the circles for you. Whether you make the circles programmatically or define your own views in xml is going to depend on how you want to appear visually.
I don't have any sample code for the rotation effect you are after but surely it can be accomplished with a canvas and some geometry.
Once you've got the AdapterView built you'll also probably want to subclass an Adapter to hold your names and override its getView() method to populate the names into the circles for you.
If you have not ever implemented any of the ViewGroup widgets I suggest you start by exploring some of those. ListView, GridView, etc.. Learn how to use it with an adapter and some data to create the dynamic layout. Once you have a good understanding of how to use the ones that are already built then start trying to tackle the one you want to make.