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.
Related
Wanna implement the filling of my ListView with the effect like that: the first item rotates X and fades in, later the second one and so on.
One way to do it is clear - add items one by one to the adapter (just like in that post), while the animations are handled by LayoutTransition object, which I set in advance.
However, I have a strange feeling, like it'd be somewhat a crutch to add items asycnchoniously just in sake of animation effect. Does anybody know how to do it better?
UPD:
Some details: I want items to be animated only when the underlying data changes, for instance, the server sends new info and the list updates, just like the old departure boards in airports.
Use a LayoutAnimationController....
LayoutAnimationController lac = new LayoutAnimationController(AnimationUtils.loadAnimation(getActivity(), R.anim.table_row_appear), 0.5f); //0.5f == time between appearance of listview items.
listView.setLayoutAnimation(lac);
Whenever you want to run the animation :
listView.startLayoutAnimation();
Finally, I ended up with using the LinearLayout instead of ListView because of the view reusage, that reruns the animation for every view whenever it's showed up again.
But I did it just because I didn't have too many items to show. Another approach, as I guess, is to load animations in adapter, compute delay in accordance with item position and to store the map with the info, wether the view has already been animated in or not.
You can create an animation(transition + fade or any other effect you want) and add the animation to the Layout (view) that you return in "getView"
the animation shall take in consideration the "position" parameter to create the delay when the animation is started.
enjoy
daniel
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 using TableLayout. On the click of a Button, I am supposed to hide it and show a progress bar and once the progress bar is done (e.g. downloading a file), I need to hide that and show a different button. The UI gets messed up, if I define these UI elements in the XML layout file. The Progess bar and new button shows as a new column. Any clue how I could dynamically hide and replace a button with progress bar and later a new button?
When you create your button use yourButton.setTag(Object) to tag them, later you can find your desired button with findViewByTag(Object) function.
Take a look at this: What is the main purpose of setTag() getTag() methods of View?
For example you can tag every of your buttons with string positionX + "," + positionY
Android allows the use of a setVisibility method call on Views.
Set up the xml where you want it, you are actually able to put things
on top of each other but i wouldn't recommmend it.
In your onCreate() method ensure that the fields/Buttons/Views are
allcreated but then set the visibility to
setVisibility(View.INVISIBLE); followed by setEnabled(false);
Once you have figured out your UI flow (the actual progression
through the process), determine where each view/button/field are to
be displayed or hidden and code in where this needs to happen.
To ensure that the flow works, and reduce the chance of a user
entering a state in-which your views are loading in at the wrong time,
create boolean variables and maybe getters and setters to create
logic rules that are applicable.
setVisibility(View.VISIBLE), setVisibility(View.INVISIBLE) are what you are looking for.
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.
One of the requirements of the application I am currently working requires that the ListView should support drag and drop of child views. I am using the TouchInterceptor class from the Android Music app as reference, and while I have managed to adapt this to my app needs there is one issue which I am still struggling to resolve. Would really appreciate some comments from anyone who has used/adapted the TouchInterceptor class and has experience/knowledge of how the ListView works in conjunction with the adapter.
My ListView has circular edges at the top and bottom and also can have different color for each row depending on the type of data that row contains. This means that my adapter getView() method supplies the appropriate background resource for that view. Also, for the first and last rows, I supply the background resource that have the curved top and bottom edges.
Now, anyone familiar with the TouchInterceptor row expansion mechanism (doExpand() method) would know that when a row is dragged out, it's height is set to 1 and the row below that is expanded to give an illusion that space is being made for a new item. My problem is that when the first item (which has a curved edge) is moved below, the expansion logic causes its height to become 1 so that it becomes invisible and the next item becomes the first one (or appears to be the first one.) In this case, I would now like to supply the correct background resource for this item from the adapter. In terms of logic I was trying to do this is roughly in the getView() method of the adapter:
//do the row inflation logic and data setting
;
;
;
if ( position == 1 && mListView.getChildAt(0).getHeight()==1) {
//set background resource with curved top edge
}
However getHeight() never returns 1. It always seems to return 0. Is anyone able to point out if calling getChildAt() and getHeight from the getView() method of adapter is valid? Anyone familiar with the ListView and TouchInterceptor class could plese provide any guidance on when getView()is exactly called by the ListView in the context of above and what would be a good way to set the correct background resource?