I'm trying to create a dynamical scrollable view. It will keep a list of elements downloaded from a server. This list could be thousands of elements. Because of this elements have to be downloaded to the list as it is scrolled downwards, and also should be deleted from the top of the list to keep memory usage low. I also need to be able to set different views as elements.
Would it be best to use a ScrollView or a ListView? And how would I go about adding elements to a list and keeping control of when to download more elemets?
I remember stumbling across an example or tutorial about how to do this. Especially about how to add elements as it is scrolled down, delete elements at the top, and create different xml views to use as elements. I cannot find this example tutorial now. It was something about how to reuse elements as they go out if scope when scrolled I think.
You should use a ListView, this is exactly what it is for and it does exactly what you describe. :)
See this for more info: http://www.google.com/events/io/2010/sessions/world-of-listview-android.html
This is quite a multi-part question, but I may be able to help with some part of it. You can use a ScrollView, and I prefer to do it that way as it allows you to define as many UI elements as you want.
Adding/Removing Elements
First I'd create an XML layout for each individual list element. When you need to add an element, you can inflate this layout like so:
LinearLayout clone = (LinearLayout)View.inflate(this, R.layout.sample, null)
Then you can set the element's information by accessing widgets in the XML you inflated
clone.findViewById(R.id.NameSpace).setText("This is element Johnny")
I would set the clone's ID to a randomly generated number or some kind of incremental index and store that number somehow (ie a List or int[]), keeping the ID of the "older" elements in the front of the storage device. Then, when you need to access elements to remove them you can just call ScrollView.removeView( findViewById( Storage.get(0) ) ) for the first element.
Related
Currently, I'm using a RecyclerView to display a set of views with different view types, where a group of consecutive items belongs together: a header, a variable set of content items, and a separator/footer.
Now I also want my UI to look good on bigger devices, aka use multiple panes, so I switched to a StaggeredGridLayoutManager. The problem here is that it spreads views evenly between all spans, means one group gets spread over multiple columns.
Thus, I would like to specify that the layout manager puts a consecutive set of views into the same span, and only then put the next group in the next one.
Is this somehow possible with the LayoutManager I use? Can I modify it to work like that without just duplicating and editing it? Support lib devs: are there any plans to introduce such behaviour?
Please tell me whether I should provide any other information, and when something isn't clear enough.
You can achieve your desired layout with the Support Library's StaggeredGridLayoutManager; you need to make each 'group' of items (e.g. header1 + 1-3 + footer) a single view returned by your adapter. This view could itself be a RecyclerView.
That is you'll have one outer RecyclerView with a StaggeredGridLayoutManager and multiple inner RecyclerViews with LinearLayoutManagers. You can likely share a single RecycledViewPool between the inner RVs. You'll have to do some gymnastics to create appropriate adapters for the inner RVs but this is likely simpler than writing your own LayoutManager!!
I'm working on an android project where I have a set of views (2 TextViews and some checkboxes in a checkbox group) to replicate many time in the same activity.
Is it possible to define the layout only for one set and instantiate it many time?
Also, the views are grouped in a Relative layout, is it possible to position the without the id attributes (to avoid id duplication)?
I would use a ListView for this. Even if you got like 5 items it workd fine. If you got many more items it still works perfect. Take a look at this example.
You can do this by defining the fields you want to reuse in their own xml. you can then use the 'include' tag for where you want them to display.
http://developer.android.com/training/improving-layouts/reusing-layouts.html
You do need to define the id's to position them in the relative layout. What is your concern about replicating the id's.
The other thing worth mentioning is how to use findById() when using 'include'. You can put a id on the include tag (which is effectively the relative layout viewgroup). Find that group first (Cast to viewgroup) and then do a findbyId on that group for what ever view you are after.
My problem is similar to ListView getChildAt returning null for visible children, but despite searching I cannot find a solution.
I have a ListView with a Scroll. The ListView has 10 items, 7 of which are visible and 3 are hidden by scroll. I also have an external method (out of adapter) that must get all of the children from this ListView (e.g. using getChildAt()).
I need all 10 of the items, but the last 3 are null objects. I've tried code like the following:
getListView().smoothScrollToPosition();
But this doesn't work.
I think that I don't need to post the rest of my code, as the description says everything?
As you have already seen you can't get all the child row views from a ListView simply because a ListView holds only the views for the visible rows(plus some recycled rows but you can't reach those). The correct way to do what you want is to store whatever data in the adapter's data and retrieve it from there.
But the ListView doesn't keep the current values from RadioGroup in
running time.
I've seen that you have some problems with this so I've adapted some old code to build a basic example, code that you can find here.
I don't think so you need to add scroll view for a listView. Scroll automatically works on ListView. Try your application without adding scroll view and I'm sure it'll work as you needed.
The reason those children are null it's because they really do not exist and they will never exist, if only 7 children are on the screen at one time, the system will only create 7 and re-use by passing the convertView back to the adapter getView() method.
If you want to grab information regarding your whole dataset you should search on the dataset itself, instead of the views on the screen. E.g. if it's an ArrayAdapter, loop the array; if it's a CursorAdapter, loop the cursor; etc.
The non-visible children of a listView don't actually exist. When they become visible, one of the redundant views is recycled or a new view is generated. So you can't actually access all the views. Why do you want to? Whatever changes you want to make should be made to the data that populates the views rather than the views themselves.
There are a few point that you need to take care of:
1. List view provides inbuilt scroll functionality, So don't use Scroll view. It will only mess up things.
2. List view doesn't contain ALL the children. When you scroll it, it creates only visible items on run time.
3. If you want to get all the children altogether, Better keep an ArrayList of the child objects that your list has. You can add or remove children to this ArrayList as per requirement.
I have created a custom adapter to display a list, there is an image that is displayed in each row ( the image is the same for all rows, except using an array i am assigning it different values depending on the position). An xml file defines the relative layout that i am using. My problem is that i can either get the entire row to be clickable or nothing at all, I only want this image to be clickable, instead of the entire row. How would i be able to do this ? i am new to android and am pretty much following different tutorials trying to create my list. Any help would be appreciated.
layout is like this :
TEXT:
[Image]
TEXT:
thats wat a row looks like...getting two texts from two different arrays and shows it, a third array is used to link to the image. I just want this image to be clickable instead of the entire row.
Thanks
Android's list component manages clicks per row. This makes it very difficult to achieve what you want to do. Two solutions come into mind:
1) If your list is never very long you could simply use linear layout and scroll view to build the list. This approach won't work if you fill in the list dynamically and you can't be sure that there won't be a very large number of rows as it would use too much memory in that case.
2) Other option is to use ListView but make your text components and images different view types in list ie. break you row into three.
That can be achieved overriding list adapter's getItemViewType(int)
http://developer.android.com/reference/android/widget/Adapter.html#getItemViewType(int)
In this approach you can make the image rows clickable but the text rows not.
I have a ListView that displays a set of notes, each with varying ammounts of data (i.e. some have a due date, others don't).
Currently, each view in the list is a RelativeLayout containing a TextView for each field, plus two Button and a CheckBox. I then simply hide the unused fields by setting visible false on each one.
This has worked well, but I'm about to add a lot more data fields to the notes and inflating that many unneeded views for each row will surely kill my app. I need a more dynamic solution.
I've decided the best way to go is to create a custom view. How can I implement/design my view so that it can display a variable number of text fields without creating/destroying textviews each time (which would be quite expensive and worse than my current situation), or maintaining a large pool of hidden textviews?
You can create a class that extends LinearLayout
and use addView to dynamically place your views.
Sounds like you might want to look into a view with a stub. The stubs will save space until they are inflated, so each row will be lighter until it is used on a heftier view. If you have a relatively low number of these larger views you might save a bit of overhead.