I have some suggestions and remarks of how to improve the code of the library.
Here are things i've modified to the code and added a link to download:
many of the files on the library itself aren't needed or doesn't belong to it, and many aren't even used.
in fact, no resource is really needed by the library.
the jar file of the support library isn't needed here, as it's already provided in ABS. This can (and will) cause compilation errors when using newer versions of the support library (or of ABS).
there are many Lint warnings about too-new APIs. I really hope they are false positives. I've already tested the sample project and it works fine on Android 2.3 .
There are also other less-important warnings (like un-needed check of null, double ";" characters,...) .
The color resource "white" wasn't found anywhere. It should either be declared or something else should be used (like
"@android:color/white" instead of "@color/white" ) .
Here are things I think should be added:
the SimpleSectionedGridAdapter is too hard to customize, especially the header part. it could be nice to be able to have an abstract function called "handleHeaderView" instead of using a layout resource Id and an id of the textview within it.
there is no usage of the ViewHolder design pattern (watch "the world of listView" lecture for more information). this could make a smoother experience.
HeaderLayout isn't really needed. you can change the layout of whatever view that was used there, and update it, for example:
layoutParams = header.getLayoutParams();
layoutParams.width = getHeaderSize();
For some reason I can't find out how to upload files here, so I've uploaded to a third party website (google drive). Here is a minimized version of the projects:
Please let me know what you think about it.
Will try the code. Although it would be great if you could send a pull request instead of zipped project.
@1hakr sorry. i did it while being at work, modifying as much as i can since i need to customize it.
another thing i think (i'm not sure since i don't fully understand the code) that is weird is that on the getView, it creates new views instead of using the convertView, or at least (as i've written) it should avoid calling findViewById .
I think it's better to avoid wrapping the adapter with another adapter.
most of the solutions just extend from the adapter and set some abstract methods that whoever uses the extended class, must implement them.
for example, you could have a function for the normal cells and a function for the header.
The code I've published seems to work fine, but it still not as customized as it could be, and I think it can remove a lot of code while making it more customizable and easier to understand.
removed dependency with resources closes #5
made some changes and merged code of @AndroidDeveloperLB
The header customization is not that hard, all you have to do is wrap any layout with the HeaderLayout(FrameLayout). I really didnt want to use a custom view but couldn't do with out it.( The whole logic depends on HeaderLayout).
I use ViewHolder pattern but in a very different way. Checkout ViewHolder static class.
I would be happy if you could remove the HeaderLayout and make it work. As i have already mentioned the whole logic of headers for GridView depends on that.
Coming to wrapping, the best part is there is no need to change you custom adapter. If you are writing your adapater fresh, then also just wrapping it will work and can be easily removed at any point of time. No complexity in implementation and no understanding of the library is required for bare minimum implementation. Its always better to keep the library code as independent as possible.
@1hakr please try to improve the code and make it easier to customize the headers, and make the adapter avoid wrapping another one.
it should be as general as possible when you prepare the views...
only the sample code should have layouts and logic of what and how to put data into them.
the library shouldn't assume that the header will have a textView and it shouldn't force you to use one and tell you what to put there.
@1hakr but why should you wrap anything? you don't need to do it, both in code and by layouts...
you can extend things instead.
the HeaderLayout, as i've already shown, doesn't need to have any special functions (it already has what it needs - getLayoutParams and setLayoutParams) . Therefore, it's not needed.
about customizing the header view, i don't see how that's possible via the baseAdapter that i'm making, or outside of it, when creating a new instance of SimpleSectionedGridAdapter .
instead, i will need to dig through SimpleSectionedGridAdapter and change it myself, so i need to take care of 2 adapters instead of one.
another problem with wrappers vs extending-classes is that for each function that exists on the baseAdapter, you need to create one on yours. that's a lot of un-needed code and it causes extra operations (and in future APIs, you will always have to add more and more functions).
in my opinion, wrapping solutions are only good for when there is no standard way of doing things, where the API is just too closed to changes and isn't flexible enough.
@AndroidDeveloperLB Did you try removing the HeaderLayout replacing with code your? Did it work?
If it worked, i will work on the same and make the change.
As for customizing, you are correct. But in the latest commit, this has been solved. And SectionedGridAdapter expects a TextView along side anything in the header_layout
As you have already said wrapping solutions are only good when there is no standard way of doing things and In android there is no standard way of adding headers to GridView.
The whole point of wrapping is to make the use of the library as easy as possible, i agree it was not easy for you but with the latest commit it should be. Not just an expert but even a novice user should be able to use the library without any difficulty. There is only one more library which does GridHeaders which customizes the gridView iteself which makes it useless for future improvements of GridView.
@1hakr are you talking about this solution:
it worked very nice, but it also has serious bugs.
but as for code design, it's quite good. it doesn't limit you to what you put on the header view. it requires you for an interface to implement and that's it...
also, just like in your solution, they extend from GridView...
about what i did, it's a work in progress. i remove every little thing, one after another, and that's because i don't understand all of the code.
about wrapping, i don't think an adapter should wrap another adapter, and i don't think an adapter should expect for a very specific view (textView or HeaderLayout) or layout within it. an adapter should make the "link" between the data and how it's shown to the user.
wrapping solution should be last resort solutions.
As I think your code works, it makes empty cell near the header cell, and makes the header cell expand to the empty cells. is this correct?
Maybe you could achieve a similar solution to the pinnedHeaderListView https://github.com/JimiSmith/PinnedHeaderListView
Yes, you are correct. thats how it works.
Coming to extending GridView My library and StickyGridHeader extend GridView for very different reasons the last time i checked. I extend only to support Sticky Headers, If you use just a GridView instead of PinnedSectionGridView, it will just work with headers not sticking. Anyways outside of the discussion
The scope of the library was to have a header label for grid items. What you are suggesting is future scope, where you have the default simplified adapter, the current one and also a Parent adapter which can be extended to fully customize the adapter.
Will do that when ever i get time. Thanks for the suggestions.
@1hakr when creating an SDK , i agree it's hard to know where it will go to, but you can think beforehand about how general things can be.
for the headers, for example, you can check out how google-plus shows the grid of photos.
they have not just textViews, but also a button to check/uncheck all of the photos on the album.
for whoever is outside of the SDK, it's better to only give the killer feature itself, and leave the customization to him.
of course, the sample can show whatever you wish to show.
your sdk killer features are not how the text is shown on the header. it's the grid being able to show headers that are also pinned. it doesn't matter what the headers contain...
@1hakr OK, I've removed the fillerView and the HeaderLayout , but I had to add some special things .
here are the changes:
the adapter needs to know the height of the headers and of normal cells.
however, this can be removed by making the gridView a bit smarter, and making it consider each row as a whole, so you won't need to set the height of the empty cells at all. for now i had to set their height .
in fact, this can be improved a lot, by making the gridView aware of the empty cells , so it will skip them and go to the next row , and if it's a headerView , let it take the whole row.
so again, in order to improve the code, you can do it by making the gridView aware of what is the type of each item via its own adapter , and handle it correctly, instead of letting the adapter making workarounds by creating special views and setting their layoutParams...
it's a special gridView, so it can afford having a special adapter that knows what it needs. the adapter shouldn't need to create fake views in the first place.
you should not set custom colors in gridview implementations... i've removed it (used for the header).
also, you should not override internal resources of ABS. i've changed their names.
i didn't make the adapter extend BaseAdapter and have all the logic i've talked about. the reason is that i don't have time for this at work. i still think it's much better than wrapping things.
didn't touch the listView. it still works as before.
the adapter had classes declaration both on the upper area and the bottom area. i've put them all on the bottom area...
in the sample of the grid, i didn't add the viewHolder design pattern (for the header), but it should be no problem to add one.
i've updated the link with the modified project.
please let me know if you've understood what i've done and please let me know if you've updated your library to be a bit better.
sadly i don't think i can customize the header. i've tried adding a button to the right, but I can't see the button , let alone click on it. only when scrolling, i can see it , but only for the top header.
why does it happen?
@1hakr about the revision you have now, if i download the projects, i can see there are missing files ("grid_item_header", "list_item_header") .
you've removed them from the library, but you forgot to add them to the project that uses it.
@1hakr in case you wish to ask how would a nice API work , here's a post i've made, including a simple solution i've written (though it's not as efficient as it could be) :