I have a ViewPager that contains ImageViews downloaded from the net and it slides just fine when my ListView (in another separate layout) is not initialized.
But the problems start when my ListView is created. The ViewPager still "slides" but only slides about 1/4 of the way, lags, then loads the next ImageView correctly.
All of the network and bitmap operations are done using AsyncTask. I've also used the RemoteImageCache API from Singly API which works pretty well.
Any ideas as to why ViewPager's swipe is lagging?
The slow down was caused by the ListView calling getView more than necessary (more than 3x per item in my list).
According to this solution, the ListView's width and height must be given specific values and not wrap_content or else getView() will be called multiple times.
it's just because of list view scroll is conflict with view pager scroll..
if you want to know about this just set list view visibility gone don't remove code listView.setAdapter(adapter) then try view pager will slide properly.
Recently (2020), must be to implement a ViewHolder class to you get speed, or, refactoring with RecyclerView, it depends of the size of your list and the time that you have to execute this methods, like my software was already production stage, i preferred use ViewHolder class, the speed gain came to be 40%, sufficient to me, if you need the more speed, must be to use RecyclerView (refactoring your listview, edit .xml, your adapter, use Linear or Grid layout manager...).
Related
I have a list view in which I want each list item will contain images. But the images will be displayed one at a time. SO, at a time for every list item only one image will be displayed. To view other images in the list item,one has to swipe horizontally. Is there any inbuilt widget that handles this in android?
EDIT1
My List item not only has Image but it also contains other views like textview, seekbar etc. So each list item will contain Image, textview, seekbar etc but the majority of the space will be occupied by the Image. Now, for each list item, when the image is swiped horizontally, another image has to be downloaded from a ulr and displayed.
EDIT2
I did a bit of research on ViewPager but many references like the answers here and this blog seem to suggest that using ViewPager inside a listview is not a good idea. Why is that? If it is not a good idea, what is a good alternative?
This problem can be solved by using ViewPager.
Link: http://developer.android.com/training/animation/screen-slide.html
ViewPager(for swiping between views) + UniversalImageLoader(for loading images from URLs, with caching etc)
If it is not, what is a good alternative?
I think you should use RecyclerView with LinearLayoutManager.HORIZONTAL. All things like recycling the views, view holder design pattern can be done easily with it and it is a new widget that google introduced and you can use it instead of ListView + ViewPager. because as you suggested it is not recommended to use viewpager inside listview. Although you can use horizontalScrollView but it dose not recycle the view. Other third party library like this exist but I recommend you use RecyclerView with LinearLayoutManager.HORIZONTAL because it is from google and it is normally tested more than people library. And another thing is you can use other layout manager like GridLayoutManager or having for example 3 rows that swiping horizontally or other good effects like adding animation and .... that google provided with RecyclerView.
For downloading the images you can use Picasso,Volley, Universal Image Loader or a lot of other libraries that exist.
Happy Coding :-)
Not sure I'm following you, but rather than a ListView wouldn't it be simpler to use ViewPager with simple Fragment that wraps a single image at a time. That way you get horizontal swiping "for free".
Do you just want swipe to change images? Or do you want the images to scroll as you swipe? For the former, you can just use a GestureDetector. For the latter you would probably use a ViewPager. See http://developer.android.com/training/animation/screen-slide.html
I have achieved the same functionality by using ViewPager, you can either put the SeekBar and TextView in the Fragment class off which you are gonna make multiple instances for each item and add to the pageradapter,
You can also add the TextView and SeekBar above the ViewPager Layout in your main fragment layout file and change the text and data on seekbar on viewpager's on item change listener, this looks more neat and this is the approach i've used
Everyone knows that GridView does not supports headers and footers like a ListView.
There is a few ways to implementing this:
Use a ListView and form columnt manually via ViewGroups. It not works for me, because it's require a lot of layout operations like measuring and layouting, and it's difficult to implement draw selector on top.
Use special adapter. It works fine with a footer: we should fill last cells with a Space and manually insert after them out footer with width that equals GridView width. But this not works with headers: although header is stretched, next cells float on it.
Use a GridLayout. GridLayout is good, but what about performance with 500-1000 cells? AdapterView supports caching and reusing Views, as far as I know, this is not possible with GridLayout.
Extend GridView and write custom class, that allows to draw a header before the grid content. It's difficult, but it's should work very fast. Let's try to figure out how to do this:
Measure the header. It's very simple, I have not questions about this.
Layout header in the top of the grid. We also should consider with scrolling position to allow move header with whole grid content, so my first question is: how to know where bottom border should be located while scrolling?
Layout whole grid content after the header. How to do that? I've newer do this before.
Dispatch draw to the header view too and resolve overscrolling effect if it's not work well.
Handle the scroll event and refresh header position.
So what you can suggest me? How to do header offset? Is it right to invoke relayouting with every scroll event?
I searched an answer on a same situation with a GridView (but for a FooterView).
I've read attentively your suggestions and some from other websites. I had the same reflexion. I found a simple way as your tip: "Use special adapter. It works fine with a footer..." and this answer by #RaulSoto helped me a lot. But when I tried to update my gridview, I had a NPE, because my footer was not like the layout of my items and I had a custom filter which recalculated the getCount() method, but without understand that another view was added.
Finally, I found only solution which works: a custom class.
Create your own class as you said: "Extend GridView and write custom class" but don't extend GridView. You should extend with ListView and measure the entire width, the column width and the number of columns. I think, it's less difficult that to extend GridView, calculate the height of the header view and move it as you move your gridview or refresh the header each time you handle a scroll event..
I searched to do it in this way and I took this little project on GitHub: HFGridView by Sergey Burish. It was exactly what I need, no more.
I only added a custom attrs file in my app and customize a bit his project to have the expected result (especially, it was to have one column in portrait, two in landscape mode, refering to the numColumns attribute in my layout).
And when I try, just for test, to add a HeaderView and refresh the content with adding new items, the header view stays at the top of my gridview list, without refreshing himself.
So, I think you should search to create your class as GridView extends ListView. Refer you to the HFGridView by SBurish, it is very simple to understand how it does.
Hope this helps you with your purpose.
In my main-activity layout (RelativeLayout), I display three listviews of vertical orientation among other Buttons and Textviews. My problem is that when one of the listviews (the one on the left side of the screen) updates, the other two update too, causing poor UI performance.
I understand that RelativeLayout can be tricky in cases when the size of one view affects the positioning of the other (causing the other to redraw), so I have made sure that the positioning of the two listviews is not associated with the left listview's size.
I have also checked out tips on how to make listview redrawing more efficient, using ViewHolders etc, but I'd rather resolve this problem to it's core.
More details:
For the left listview's adapter I subclass the ArrayAdapter class.
For the other two listviews' adapters I use subclass the CursorAdapter class.
You are right RelativeLayout in the culprit, use some other view in plase of it, like LinearLayout with android:weightSum etc...
If you set android:layout_height="wrap_content" to your ListView, then system try to find the best size of each elements and call getView many times. There is no way to around that other than using android:layout_height="fill_parent"
http://www.androiddevelopersolutions.com/2013/07/android-listview-adapter-getview-called.html
custom listview adapter getView method being called multiple times, and in no coherent order
Try to use same adapter class for the better performance because the execution time differs on what sort of data your are going to display.
I have an app which loads a boatload of images and displays them in a TableLayout which is inside a ScrollView. At run time I get the width of the layout parent and use that to determine how many images can go in each TableRow (all of the images are of a set size).
I'm concerned about memory issues when loading more and more images. I know ListView recycles its views but I don't know how to dynamically change number of views in each item. I am only aware of inflating XML which isn't going to change the number of views per item at run time.
So my question is what is easier - figuring out how to recycle views in my table by myself, or making a list's items change based on screen size? Just a link to a tutorial on how to do whichever is easier is good enough an answer for me.
I suggest you to use ListView with the ViewHolder approach (you can see it here: How to load the Listview "smoothly" in android).
The ListView, when scrolled, removes the views that are no more visible and gets the views that are about to become visible. This way, it's better than using a ScrollView and a TableLayout.
I have a vanilla "News" app, where the main page is a ListView that scrolls vertically with a list of articles (thumbnail, title..etc). This works just fine, but now I want to add a horizontal article/photo rotator as the top item in that list. I don't really care if it's technically in the list or not, but it should scroll up/off the screen when the list is dragged...etc. I assume(d) it should be in the list, but am quite new to Android and don't know if there's a better solution.
After an entire day of searching around, I'm still empty-handed - don't know how to add it or even if it's the right method. I'm using a ViewPager for my gallery view (when they click a photo), and that seems to be working fine...but that's the entire view... and this one already has an adapter that populates the listView... I hope I'm just over-complicating something.
TLDR:
1) Can I add a ViewPager as top item in a ListView?
2) How would one go about doing it?
3) Is there a better solution?
Note: android:minSdkVersion="8" android:targetSdkVersion="15"
You can use addHeaderView() from the ListView API to set a header. It can be any View, so also a ViewPager. I think you'll have to add it programmatically. Set the height of it correctly though.
i'm not sure i understand your question. ViewPager is a view like any other, so in your ListView's adapter's getView() method, return a view that contains a ViewPager.
ViewPager is a topic in itself, so if your problem is that you don't understand ViewPager, read these links,
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html
if you are using API level 8, you should use the ViewPager and friends from the compatibility package.
that all being said, i wonder if you will have trouble putting a scrollable view inside a scrollable view. i know ViewPager contains code to pass off any gestures to child views if it decides it cannot handle them. i can't say if ListView has the same smarts.