I have a ListView in my Android application. The individual views in the list are a little bit smaller than the size of the screen.
I want the list to always show one item centered in the screen, with just a small sliver of the previous and next items showing above and below it.
When the user scrolls, I need to reposition the child view at position 0 or 1 (depending on which way they are scrolling). Currently I am doing this by calling "setSelectionFromTop" in my onScrollStateChanged method. This works, but the transition is immediate, not smooth. It is jarring and confusing in a lot of cases.
What's the best approach to fixing this? I want to animate the process of scrolling the list into the position I want, but I can't find any methods in ListView or its superclasses that let me directly control the scroll position of the entire list.
I think I could animate it using multiple calls to setSelectionFromTop(int position, int y) with progressive values of y, but I don't know how to determine the initial value of y. Is there some way to get that by interrogating the view object at the designated position?
Another challenge I have in front of me is that I want to animate the removal of an item from the list - by having it either disappear or slide away to the left, and then having the surrounding views move up and down to fill the space. Is there a straightforward and reliable way to do this with a ListView? Should I just give up on the ListView and write the whole thing as a custom view from scratch?
Thanks.
This definitely should be possible. Does smoothScrollToPosition() work?
Otherwise, you can try simulating the touches using TouchUtils.
Related
I need a component that works like the picture below but I'm having trouble coming up with some kind of decent solution that works.
I want the list to have a center locked selection but being scrollable with the d-pad. This is for an application running on a TV so no need for touch scroll. So when pressing down on the remote d-pad the list will scroll and a new item will size up and the current selected one will size down and the new selection will still be in the middle.
I've tried doing this using a ListView that I extended and programmatically scrolling when pressing down or up. On scroll finished I called notifyDatasetChanged() on the ListView for re-inflating of the childs and in the ListViews adapters getView() I made the animation of the view located at the current selected position.
This is not optimal since I need to call notifyDatasetChanged(), which re-inflates all visible views, for the animation to apply. The UI becomes laggy when doing this and scrolling fast. It's also not possible to make som kind of compress animation when current selected item goes out of selection. There is also some trouble with the end items (read views) such the first or last in the list when doing animation of them, the may sometimes go out of screen.
I think that his must have been done before and maybe I'm missing it when searching for an answer.
Have anyone done something similar or do you have some suggestions of how this can be achieved? Maybe I'm just starting of with the wrong component here..
Regards,
Kristoffer
I want an expandable list in which I can drag a child item and drop it over some other parent list item which will result in child moving from one parent to other. I only need a direction how we can achieve this in general listview (let alone exapandable). Examples are available for picking up a listitem to change the order of listview i.e. to sort that list. How can I accomplish dropping over a view in order to group them.
Your best bet will be putting your effort on customizing and making your own listview, Consider extending AdapterView, this will give you more power over controlling child display and organizations, Putting animation such and drag and drop will be easier for you in this case, Otherwise with simple list view it might work but i doubt if it would generate the required result you want.
Here is a link for exending AdapterView and customizations, go through it it will give you enough confidance to put in your animation. I tried almost similar stuff and was succesfull by same way, unfortunately I dont have implemented code with me.
http://developer.sonymobile.com/2010/05/20/android-tutorial-making-your-own-3d-list-part-1/
Else with list view try doing following,
Your listview should be wrapped inside a framelayout, you will need layers
Enable drawing cache for childrens, coz animation you seek requires playing with bitmaps
Second, when you touch a child in listview, get the bitmap of child, and inflate it at same coordinates of touched child, you can get position of Child easily.
Now time for some animation, you enable drag and drop over inflated bitmap, now when you move it, first thing you need to do is, shifting all the childrens in list view either Up or Down depending upon movement of finger, you can define somekind of threshold like unless half the height of children is moved you wont shift childs in listview up or down.
Moving child will be easy, all you need to do is applying Transformation animation to all the currently visible child in listview, use childCount and ChildAt api for the same, and animation set for playing them together.
Thats it when you build space by shifting child, user will feel like drag drop and shift, all the thing you need, when user places it a place, just modify your dataset underneath listview reposition it based on recent changes by user and refresh it,so that listview reorders itself.
I've been trying to work out how to calculate the y-position of scrolled content inside an Android ListView. The consensus seems to be that Android simply doesn't give you this information and you have to work it out by doing all sorts of calculations based on the getChildAt(0).top and getFirstVisiblePosition() methods.
My question is to try to understand why Android doesn't give you this information. It would seem to that the the list view must actually know this value somehow in order to draw the scrollbars. Or at least know it as a percentage? The ViewPager's onPageScrolled() method seems to do the same thing. And it's a trivial matter in iOS as well.
ListView is not same as ScrollView as you thought of.
For example, if you have 10 items with use 2048px hight. If you wrap them in scroll view, the inside content is 2048px height. However, in ListView, the 10 items will be populated dynamically. It is always in the displaying area, thus the scrollY = 0.
If you really want to calculate the ScrollY of ListView, you might need to take care of it by yourself. You can getFirstVisiblePosition() to get the index of the current top visible item. And consider the height of each list item and list divider, you might be able to get the total scrollY value.
I am trying to make a ListView for showing lyrics. I have very little experience with making custom compound views. So I would like to know what my approach should be to make this view. The ListView must have these features
auto-scrolling based on the song (the timing information will be stored in the list adapter)
highlighting the current line which is being played on the audio
indentation on some lines to make it look more like a nicely formatted poem
users should not be able to scroll the list when the song is playing (i.e. the list is being auto-scrolled) but it should be scrollable when the song is paused
I don't know if the view should extend list view or not. If not then what should it extend and what should be my approach?
Frankly, I really don't have enough information to answer this completely, but this is what I would do:
If it were up to me, since you don't want a scroll capability at all (you want to make it appear as if it is scrolling, not to actually allow the user to scroll), I would not use any of the complex views like ListView or ScrollView, I would just write a custom view, simply extending View. I would override it's onDraw() method and use Canvas.drawText(...) to draw the words, having two different Paints, one for the current word and another for all other words. As for the "scrolling" effect, you can keep a number that represents the current top line that you can see, and add one to this number when you want to scroll to the next line. However to make it smooth you can manipulate where exactly you start drawing the texts and move it slowly upwards, so that it would appear that everything is scrolling down.
** Maybe it would be better to use SurfaceView here instead of just View, especially if you want a background image and smooth blending and better a look, since SurfaceView is much better for complex drawings **
If that is too complicated for you and you want to use existing views entirely without doing any of the drawing yourself, I would recommend a vertical ScrollView, you fill the ScrollView with horizontal LinearLayouts for each line, and each of those is filled with TextViews for every specific word. You can programatically build the TextViews and the LinearLayouts. Use ScrollView's scrollTo(...) or SmoothScrollTo(...) to scroll to the right location. You can prevent the user from scrolling by capturing all the motion events before they are used to scroll.
Both approaches will of course require you to maintain some form of data structure to hold the times each word is selected.
I have a text view where in i have to keep ages between 1-99. I also have two buttons ^ and v(i mean up and down arrows) on clicking them the values of the age should smoothly scroll to next or previous value.
I have been trying different ways but couldnt achieve smooth scrolling. Can anyone please give me any idea of how to achieve the task.
I think the easiest way is to simply put the TextView within a ScrollView, and let the arrows interact with the ScrollView, by using things like the fling method and playing around with the velocity parameter to suit your needs.
Use the animation framework.
When pressing down, start the 'down'-animation.
When pressing up, start the 'up'-animation.
Read more about animation here: http://developerlife.com/tutorials/?p=343
View animation is not much matured and hence i am noy sure if that can be used for moving the views.
Please find the description below:
Another disadvantage of the view
animation system is that it only
modified where the View was drawn, and
not the actual View itself. For
instance, if you animated a button to
move across the screen, the button
draws correctly, but the actual
location where you can click the
button does not change, so you have to
implement your own logic to handle
this.
Source
To scroll smoothly you can try using the scroller component.
Reference
What you would need to do is pass the duration of the scroll in the constructor and then use the property
setFinalY(int newY)
to increment the counter position by 1 unit (equal to the height of the item).
Please let me know if that helps!