I'm trying to convert the RealViewSwitcher based on the work from Marc Reichelt into one that is backed up with a ListAdapter. A horisontally scrollable ViewGroup that contains multiple views, where one is visible at a time.
My current solution adds at the most 3 views to the ViewGroup at a time. One (in the middle) which is visible and two buffered views, one on each side. When a user scrolls, say to the right, the left-most View is removed and a new View is added to the right. In order for the ViewGroup to be scrollable both to the left and right I need to always focus on the View in the middle. So, when a View is being switched, I arrange the Views correctly and sets focus on the View in the middle. The issue with this approach is that it suffers with a flickering effect when the Views are arranged. Let me illustrate the issue with a picture I drew:
A, B and C are three different views in my ViewGroup (the ListAdapter backing up the ViewGroup contains of more elements though, but only three are loaded at a time). The larger rectangle represents where focus is at the moment. I scroll to the left and at (3) I snap to the destination which is the left-most View. Then I re-arrange the view. I.e. Add a new view X to the left and remove View C to the right, placing A in the middle. Finally I center on the View in the middle (A) which was the one I scrolled to from the beginning.
So, when I do the last re-arranging of Views and center on A in the middle, the content of the View which was previously in the middle (B in this case) flashes a few milliseconds causing a flicker effect which is uncalled-for. Any ideas of how I can go around that?
Problem solved. The issue seems to be related to changing the childs in a ViewGroup and then call the scrollTo method. If I instead use a Scroller to move to the right view/child, the flickering issue disappears.
Related
I am developing an app that has a recyclerview, where a view needs to be at the top depending on the current time. I did a lot of research on how to leave a view at the top, however, the solution found (scrollToPositionWithOffset) just leaves that view visible, and not necessarily at the top. I need this view to always be at the top, even when the number of views is less than the height of the recyclerview or the top view is the last (with views prior to it). In such cases, the previous views would be visible only if scrolled up.
For example:
As can be seen, each view is ordered by time, so I can't just insert a view in the first position. In addition, there are times when the visible part of the recyclerview will be smaller than its size, even if there are items before the top view, so the scroll methods do not work here, since they only scroll until the view is visible, and not until it gets to the top. I am implementing this list with Recyclerview and LinearLayoutManager
My layout is a bit complex.
I have a SwipeRefreshLayout in which I host a ListView. Whenever the user drags the Listview's top, the SwipeRefreshLayout performs a refresh. I also listen for the last visible item of the ListView to load next page of records (Endless scroll)
In the list's adaptor I have 2 views that I am using. The first one will only be visible in first row, the other view will remain the same for all other rows.
What I want to achieve:
On top of the row with position = 1 I want to have a sticky header. This means that when I scroll Up, the header will scroll to the top of the screen and will remain in there.
This sticky header will only be at one row
if possible I'd like to use a simple implementation as my layouts and adapters are already complex enough.
Waiting for your suggestions.
I didnt quite get your question the first time, heres the answer attempt round 2.
In your layout add an empty viewgroup (whichever you prefer, though linearlayout seems to work just great), add a scrollListener to your listView and check the position of your sticky view. If its top anchor is below (meaning its visible in the listview) the top of the screen you set the viewgroup visibility to gone, if the top anchor is either touching the top of the screen or below it, you add that view or one just like it to the viewgroup and set its visibility to visible.
You can adjust the position 2 view visibility accordingly to allow for this change to appear seamless. Can help you a bit more once you have some code and are on your way with this change.
I'm working on a custom ViewGroup.
This ViewGroup has a bunch of children. I need to animate a few and change their position. I understand that Android animations move just the bitmap and not the real object. I've been trying to MOVE them by following various resources but have failed.
What I'm doing with ViewGroup so far:
Measure children and the ViewGroup
Position children in onLayout
What I'm trying to do further
Use a custom animation to move a small subset of the children. I'm using a custom Animation object because I need to move a bunch of Views and I'm applying translationX on all of them together. The other option that I know is to start a separate Animation on all of them and the thought of which makes me think it's gonna be unoptimized.
Problem
Views animate fine, but their real position remains unchanged. So the next time I'm trying to do the same kind of animation, but on the new co-ordinates, it doesn't work. Because, their positions haven't updated.
What did I try
Use onAnimationEnd to layout each of the children to the new left, top, right and bottom position. All views vanished
On onAnimationEnd, reset translationX to zero and then start re-positioning the views. No effect of calling view.setTranslationX(0f)
Can someone please help me with the correct way of doing this? Thanks
when animating call layout() on your child Views
For example, top level LinearLayout view has 300 child view. But device screen dimension only show 11 child view once. How android compute how many child views can show once? How a view know that it will be draw?
Edited
In my work, one case like this:
An parent LinearLayout view may be has hundreds child view. In order to better performance , my solution like this:like lazy load.
List list = new ArrayList();//contain entity object that use construct View object
Default load 5 child view.
Parent LinearLayout view last child view is custom Loading View, I have override it`s onDraw() method. If loading View is draw, that means i need get next 5 child view(get next 5 object from list,and create correspond view).
I want to know how android framework handle this case?
Have u used scroll bar inside the top level LinearLayout view and add child view on that layout that's simple...
An parent LinearLayout view may be has hundreds child view. In order
to better performance , my solution like this:like lazy load.
LinearLayout with(possible) hundreds of child views kind of contradicts better performance. I think what you're looking for is a ListView with an endless adapter(a simple google search will show how to implement it, not something that difficult). This adapter will start loading views(with a loading view showing while the new content loads) as soon as you get to the last loaded element.
If you still want to use a LinearLayout:
If you just want to make the LinearLayout fill the content of the screen when it's first laid out you could post a Runnable on one of your views in the onCreate method (if this is where you'll first populate the LinearLayout). In that Runnable find the height of the LinearLayout and compare it with the combined height of its currently present children. If the combined child height is smaller then the LinearLayout height then add more views to compensate.
If the LinearLayout is in a ScrollView and you want to add additional children when the loading view becomes visible then monitor the scrolling of the ScrollView and when the loading view becomes visible add new children. Seeing when the loading view becomes visible would be done by checking how much the user has scrolled compared with the combined height of the currently present children of the LinearLayout.
Initial response:
Your question is a bit ambiguous regarding what you want to know. If you have a specific problem you should start with that.
For example, top level LinearLayout view has 300 child view. But
device screen dimension only show 11 child view once.
Please don't get yourself in a scenario like this. That number of views is to big an will result in poor performance or even the app crashing if you run out of memory(as all those views will be kept in memory).
How android compute how many child views can show once?
Each View and ViewGroup has the onMeasure method to measure itself and its children if available. The LinearLayout will have its onMeasure method called and in this method it will measure its children(with the measure method) giving them some suggestions on how big should they be(the LinearLayout receives some suggestions on how big it should be from its parent). If you want to see how this is done have a look at the source code of the LinearLayout.
How a view know that it will be draw?
I don't understand what you want to know. To draw the view on the screen its onDraw method will be called.
I have two Views that are positioned on top of each other. The first stays in position and is visible at all times. The second has its visibility toggled by the user and slides in (and out) (using an animation) from (and to) the right of the screen. The problem is that the two Views when showing together, get merged such that you can see bits of the first View beneath the second View. Is there a property I can set on the second View such that it covers the first View totally out of sight?
Have you considered using ViewSwitcher?http://developer.android.com/reference/android/widget/ViewSwitcher.html