Fully expanded nested lists - Android - android

I am attempting to create a nested list view for an android app. What I essentiall want is some thing like
nested list entry 1
Outer List Entry1 nested list entry 2
nested list entry 3
nested list entry 1
Outer List Entry 2 nested list entry 2
nested list entry 3
Where I have an outer list, which has two entries, and then have a nested list view which has detailed entries (if you imagine a calendar that has days of the week as the outer list, and with each day there is a list of 0 or more appointments listed vertically as above). Further more, I want the nested list items to be clickable/highlighted in the same way a top level list would be.
Most info I find having looked for nested list views is suggestions to use ExpandableListViews - Which I implemented, but it seems like a bit ugly to use this as its clearly not the same purpose (I dont want anything expandable - everything should always be fully expanded and non-collapsible - also, couldn't find info on laying out horizontally as above rather than vertical - but I assume that is possible relatively easily?).
I also used the selected answer here: android nested listview which works ok in terms of presentation, but doesn't offer the same list scroll/highlighting/click behavior for each individual item in the nested list.
Can anyone suggest any alternatives? ever implemented a similar layout with either of the above?
UPDATE
I want the layout of the lists to actually be like the above text representation - in an attempt to clarify the layout I want, here is an image (yes, I know I should probably be downvoted for the lame screenshot of a diagram in open-office :)
So you can see, I actually want the screen to look like that - the parent/outer list being a list of time periods (in this case its days of the week, but it could be hours of the day etc), and for each row in that outer list, I want the inner list (appointments for that given timeslot) to appear as a nested list aligned horizontally to the parent.

To make ExpandableListView not collapse ,use
expandableList.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
return true; // This way the expander cannot be collapsed
}
});

Updated answer:
If you want a table then you should probably split it to Fragments.
The root View should be ScrollView.
The child must be horizontal LinearLayout
Every next column is a Fragment.
Every Fragment container should have some weight.
Every Fragment's root view should be vertical LinearLayout
Make sure Frament with days item has the height of exactly three "tasks" item height.
Hardcode them in dimen.xml.
For convinience, make every Fragment's LinearLayout extended class that can have ListAdapter set. Populate the every row based on ListAdapter.
That way you can achieve a list with fixed content.
Or you can do without Fragments if you don't want to be flexible.
Adding new column will be just a matter of Fragments that encapsulate the logic.

Related

Section headers next to items in SectionedRecyclerView

I'm trying to implement SectionedRecyclerView everything works perfectly. I would only like section headers to be next to items, not above,
like it's shown here and I have no idea how to do it.
There is no easy or quick solution to this.
a) If you just want to show the header section next to your items you can have a look at RecyclerView.ItemDecoration to just draw the headers next to your items. You won't be able to click on them or some other interaction, as it is litterally only drawn there. Just a drawing. No View. (Can't emphasize this enough)
b) If you want actual RecyclerView support for this layout, you will have to create your own LayoutManager. Neither LinearLayoutManager nor GridLayoutManager has support for such behavior. This is probably by far the most difficult approach.
c) If you want to get hacky you could return a different view type for your first item of every section, inflating the section header along with the first item or try working with a GridLayoutManager, and using SpanSizeLookup to align your elements, working with dummy (empty) views filling in the blanks below your section headers.
d) As a last alternative you can just inflate the whole section as one item, which would only be recommended if every section has very few items, since it negates the idea of a recyclerview. You can even inflate recyclerviews within the recyclerview if you want, although keep in mind that they would not actually be "recycling" any views since their whole content gets added at once (when the section is visible)

RecyclerView/StaggeredGridLayoutManager: Force group of consecutive views into the same span/column

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!!

Using nested ListView or something else?

I have an layout like this:
I have almost 10 category to display, and each category have 10 books to display.
So it seems that I have to use the ListView for category with nested ListView for each book.
But I wonder if this will cause the measure problem? The inner book listivew does not need the scroll feature while the outer listview needs.
I have thought use the LinearLayout instead of ListView at all by adding each book and category dynamically , however I am not sure about the performance since the ListView can reuse some view, while LinearLayout cannot(or hard to).
Any suggestion?
Have you tried using ExpandableListView. Hope this helps..
You should not have problems, your inner ListView will not have limited height.
Consider using a ExpandableListView, the header will be the category and the childs the books. If you use this remember to override the method isChildSelectable to keep all the items expanded and remove the group indicator with setGroupIndicator(null).

How to get all children (visible and invisible) from a ListView?

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.

How to use a ListView inside a ExpandableList?

I've been working with a custom ExpandableList (see example picture below) where each item always has one child. This child consists of three parts. Each part has a header (red bars) and below that an Empty item OR a list of items. The length of this list will vary.
The first way I tried to do this is by adding a ViewStub below the empty item, which I inflated with a custom view, which also contained a ViewStub at the end which I inflated in turn for the next item, thus adding items recursively to create this sort of list of items. Sadly this resulted in StackOverflowError's when the list became too long (With short lists this worked perfectly).
So on my second try I tried using a ListView with a custom adapter instead. Sadly this list only used a small part of my screen and the rest of the items where occluded behind the header of the next part (This mini list looked scrollable as a second scrollbar appeared next to it, but it did not scroll. Not that I would consider this scrolling inside a scrolling list to be a good solution, but just wanted to mention this).
Can anyone tell me how I can tell this list of items to not be scrollable and take up all the room that it needs (does it know what size it is going to be when the child node is created??) or help me with a alternative solution to my problem? (Ooh, and I have considered putting an unholy amount of ViewStubs inside my layout, but that just seems idiotic and really bad practice. Correct me if I'm wrong)
If I understood you correctly, then why don't you just take an ExpandableList + Adapter that implements ExpandableListAdapter? It's a somewhat ugly approach but it works and isn't much hassle.
MyAdapter implements ExpandableListAdapter
#Override
public View getChildView(int groupPosition, int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {
}
In this method you could simply figure out if the current childPosition would be one of the headers or one of the children and inflate the appropriate View from xml.

Categories

Resources