What is the best way to implement Header support in GridView? - android

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.

Related

How to make evenly spaced Grid Layout with dynamically added square items

I would like to create a grid layout in which each item is taking as much space as possible (minus padding), but only as long as there are columns available (after that the next item would be inserted in the next row while keeping the size). Additionally, each item must be a square and is added dynamically.
Example layout with 10 items would be as follows:
I have tried to achieve this by setting weights, ratio constraints, overriding onMeasure - but I just can't get it to work. I would be happy with either a programmatic or an XML-based solution (as long as each item can be added programmatically). I would prefer the solution to be in Kotlin, but I would be happy with a Java-based one as well.
It's probably worth saying that each item in the grid layout is a layout (RelativeLayout as of now) to make inflating it and setting a layered background drawable programmatically easy.
I think you might be able achieve what you want with a different Layout
Have a look at https://github.com/google/flexbox-layout it has lots of methods to control how the cells grown or shrink and includes automatic or manual wrapping of cells.
Take a look at RecyclerView. You would need to pass GridLayoutManager. This tutorial may or may not help you. For square items, I suggest using CardView but it's not necessary. If you are targeting tablets as well as smartphones, check this out. And for dynamically adding new items, you should notify recyclerView's adapter. See this link. You can also extend RecyclerView or GridLayoutManager for more control over items.

How to make the entire screen containting a (LinearLayout + ListView) scrollable

I have an Android fragment in which contains a Vertical LinearLayout with two layouts inside it: Another inner Vertical LinearLayout (which takes at least half of the screen) and a ListView (which shows a number of smaller Views). A good way to think about it is something like a facebook post along with several comments showing below it.
The problem I am facing is that the the inner LinearLayout is not scrollable and therefore parts of the ListView stays outside of the screen and there is no way to scroll the screen up to see the entire ListView (the inner layout could possibly take up the entire screen). Placing the entire layout inside a ScrollView is also known to be a bad practice.
I know one solution is to make the entire layout to be a ListView with the first cell to be the inner LinearLayout, followed by the cells from the original ListView. That however has its own issues: It is harder to recycle the views in the ListView, and generally I also see it as a bad practice where one cell has a different behavior from all other cells in the ListView.
Is there a better solution to this? I can imagine this is a typical problem and I hope to find a better solution than above.
This may help you:
ListView yourListView = new ListView(this);
yourListView.addHeader(getHeaderView());
You can also add footer to a ListView. When you do this, the header(or footer) will become part of the ListView, and so it will be scrollable. You can find the document here: http://developer.android.com/reference/android/widget/ListView.html.

Make Header View (not Section Header) of ListView Stick on Top

I have a ListView with a HeaderView.
I want one of the views in the HeaderView to stick on top.
I've seen a lot of examples for sticky Section Headers.
I also looked at StickyScrollViewItems but since I'm using a ListView, I cannot use a ScrollView.
Is there a library available for this or should I just override the OnScrollListener of the ListView?
Thanks.
I have just written a load of code that does this that I cant share for contractoral reasons. Basically follow the approach outlined here and apply to a listview rather than a scroll view.
Main points are
Create a wrapper view that contains your floating/sticky header and your listview as siblings
Use a proxy method when adding headers with an isSticky boolean - if is sticky then add a fake blank header to the listview of the same size and your intended header view to the floating header wrapper (use a relative layout here)
Set a scroll listener of the listview that tracks the top px position of the dummy header view in the list and setting this as a top margin of the floating header that sits inside a relative layout
Handle all the annoying edge cases / OEM overscroll crap to get it to work in all situtions (like this for samsung)
Remember to set the initial position of the floating/pinned header after the listview has been layed out.
I feel its a little bit involved and takes some tweaking to get right - this is a time where i envy iOS and any iOS devs will think your slacking as it takes a while to implement :D
All the Open libs out there at time of writing are using scroll views or list view headers. This issue with these approaches are that list views recycle views (so unlike scroll views you cant just keep a ref to the dummy view) and also the current libs seem duplicate the sticky views using adapter getView methods and so on - which is no good for dynamic list view header views as they are not recycled and can only have one parent, so reparenting would be annoying (and in my case has a lot of functionality so I defo dont want to create two views of the same type and shoehorn the current libs to fit my solutions)
I don't know of any library that lets you do this but what I do for a header is to use a RelativeLayout for my xml that will have the ListView. Then create your header view however you want and give it the property
android:layout_alignParentTop="true"
then give your ListView
android:layout_below="#id/idOfHeaderView
This is the easiest way I know of to dock a header view at the top. It has worked for me every time. I hope this helps.

Is it possible & efficient to put a LinearView and ExpandableListView inside a ScrollView

I'm making a GUI with two different parts. The first part (at the top) is composed of some banners, several fixed buttons. So I think using LinearLayout is the most straightforward way to implement. The second part is composed of several similar items grouped together which can be implemented by using ExpandableListView, I think.
However the problem is that the content exceeds the screen size. So I intend to put two of them into a ScrollView. I checked several sources, it seems that putting "ExpandableListView" inside a ScroolView is NOT possible, or not efficent, so I'm afraid...
Would you help to confirm if this is possible? efficient ?
If no, would you give me some recommendations for this layout design?
I'm indeed looking forward to your supports.
Sincerely.
If you have a fixed header at the top of a list, use ListView's header view feature.
Putting ListViews in ScrollViews fundamentally makes no sense and here is why:
ListView has one purpose: to efficiently display unbounded data sets. Since these can be extremely large (tens of thousands of items and more) you do not want to create a View for each item up front. Instead, ListView asks its Adapter for Views only for the items that currently fit in the ListView's measured space on screen. When an item's View is scrolled out of sight, ListView disconnects that View and hands it back to the adapter to fill out with new data and reuse to show other items. (This is the convertView parameter to an Adapter's getView method.)
ScrollView also has one purpose: to take a single child view and give it "infinite" vertical space to fit within. The user can then scroll up and down to see the full content.
Now given this, how many item Views would a ListView create for a 100,000 item Adapter if it had infinite height available to fill? :)
By putting a ListView inside a ScrollView you defeat ListView's key purpose. The parent ScrollView will give the ListView effectively infinite height to work with, but ListView wants to have a bounded height so that it can provide a limited window into a large data set.
Well Expandable List View itself has scrollable property by placing it in scroll view is really undesirable.As the both scroll would contradict and smooth scrolling can't be obtained in that case..
If we have any data to be shown prior or later to list...
Best way is to use header and footer view to list...
I recommend you use header and footer in your case.

SimpleCursorAdapter within a ScrollView

I'm having abit of an issue and i'm not too sure how to go about solving it.
Essentially i have an activity which has a base xml layout of ScrollView and i want this activity to list some results from a Cursor. So i thought i'd use SimpleCursorAdapter... however when i got it all set up it appears that the ListView that the SimpleCursorAdapter goes into doesn't play nice being within another scrollable layout element.
I've sorta got it working programmically but i'd much rather use a ListAdapter as it will make each list entry look like a button and keep it inline with the design of the rest of the application and can handle the ids of each item and where to send the user upon clicking.
So my question is this: is there anyway to either make ListView show all the items such that it never needs to scroll, or can i change the ListView to something like a LinearLayout?
I hope that makes sense!
Any help / insight / ideas are welcome!
Cheers!
You can NEVER use a scroll view and a ListView together. Its a mess! and illogical as well.
Here are some of the approaches you can use:
Theres no screen big enough to show all the content of you listView you can try wrapping up your content but as I said it won't help as scroll view and list view don't work together. So you can either remove your or
If your list items are simple you can dynamically add your views to LinearLayout with specified location
Another tip I can give you is you can always use an relative layout and place your listView alignParentBottom="true" and emit the scrollView approach this will make you listview alwyas scrollable.
It doesn't really make sense to have a ListView inside a ScrollView at all. The ListView implements it's own scroll function so it should not be used in conjunction with a ScrollView anyway.
You should rethink your UI design.
I agree with Shardul; trying to put a listview with a scrollview will make it impossible to scroll. Have a look at the links below to see what you can accomplish with just a ListView -
a.
custom backgrounds info.
custom adapters

Categories

Resources