In order to enter information into my database, I'm currently using a scrollview (with a table layout, iirc). However, looking at the api demos, I'm wondering if I should switch to a listview. It seems a bit of a strange way to do it, as I'd have to hard code the numbers of items, it would all have to be in java rather than xml, and each one would need a separate onclicklistener, but as far as layout is concerned it sounds like by far the easier to maintain.
(I'm considering the switch now as I'm doing a major rewrite anyway, so now would be a good time)
Anyone have any opinions that they wouldn't mind sharing? Would this be a horrific abuse of a listview, and should I stick with what I have? Or should I move to something that I can much more easily theme later on (my current layout is pretty ugly)?
I think of ListView as being the exact opposite.
You don't have to hard code list items: they come from various adapters like CursorAdapter and ArrayAdapter.
You can use a single OnItemClickListener to handle the click events for all of your items. onItemClick provides you with the position of the item that was clicked.
Even your presentation can be dynamic, since you can easily switch out a GridView for the ListView later.
I would recommend trying ListView; it will give you another tool to work with and inform your design decisions in the future.
Related
I'm trying to make a android app with a scrollable list like this one...
When I made this app in iOS, I used a UICollectionView. What`s the best way to make this in android studios?
I tried using a list view, but I can't seem to customize it to my needs?
Any Ideas?
ListView was a great way to start and it is customizable to your needs.
However I would recommend to use RecyclerView which works almost on the same principle as ListView but it is a newer concept in Android. It handles the usage of the ViewHolder pattern for you which makes everything super easy.(With ListView, you would've had to implement your own ViewHolder pattern)
All you need to do is to have the RecyclerView in your activity/fragment as the view to hold your data. Then, the key component is to implement the RecyclerView's Adapter which will handle the inflation and setup of each list item.
Here is a really great and short tutorial to get you started with RecyclerView.
If you're done with that here is a bit more advanced video material on RecyclerView from Dave Smith explaining a lot of ways on how to understand and use RecyclerView in your apps.
A ListView fed by an ArrayAdapter of custom objects can do the job.
You might have a class that contains the text and the image of a single item.
Then you can create an ArrayList with items of that class, where you put in all the data.
This ArrayList can be used as dataset for a custom ArrayAdapter, which overrides the getView()-method.
The getView()-method must inflate the xml-layout for each item and attach the data from the ArrayList to the inflated view.
You might want to implement the Viewholder-pattern to achieve a good performance and avoid unnecessary inflations and getViewByID()-calls.
You can also use the new CardView, which can make it a lot easier, since it is made for the new material design in android 5, which looks similar to your item list.
This is not a code problem, I interpret the guidelines as that being OK.
I've been researching a way of building an infinitely scrolling calendar-like view in Android, but I've reached an impasse.
Right now my dilemma is that most of the similar views available have their children placed relative each other in a recurring style. With this I mean:
item 4 comes after item 3, which comes after item 2, and there is constant padding/margin between all items.
What I need is a way to produce an infinitely long scrollable view that may, or may not, contain items. The items should be placed at variable positions within the view. The best way I can describe a similar looking view is a one-day calendar-like view that is infinitely scrollable.
So far my best two bets are using the new RecyclerView with a custom LayoutManager (this seems very complex and still not perfectly documented by Google though). I like this approach because, among other things, it is optimized for displaying large sets in a limited view.
My other solution would be to build a completely custom View. However, with that solution I loose the adapter unless I build a container view (which is probably more complex than building a layout manager).
How would you go about solving such a problem? Tips are appreciated, I don't need code examples, just ideas which path is the best to solve this problem.
Thanks.
Apologies if I've misunderstood the guidelines
Edit: How I resolved this problem
My first solution to use RecyclerView with a special Decorator seemed promising, but it remained a "hack" so we decided not to go for that solution since we were afraid of the complications that it would create down the line.
To solve the problem I went with a SurfaceView instead of an Adapter, this means having to rewrite all the adapter-functionality for my SurfaceView but it seemed to be the best way of solving this issue of very custom drawing and layout managing for my use-case.
It still would be nice to build a custom Viewgroup that can handle this kind of layout problems.
ListView and ListAdapter are based on a fixed list, so the current infinite-scrollers just keep adding more and more data to the end of the list.
But what you want is scroller similar to Google's Calendar app which has a bi-directional infinite scroller. The problem with using ListView and ListAdapter in this case is that if you add data to the front of the list, the index of any one item changes so that the list jumps.
If you really start thinking about this from the MVC perspective, you realize that ListAdapter does not provide a model that fits this need.
Instead of having absolute indexing (i.e. 1, 2, 3, 4, etc), what you really want is relative indexing, so instead of saying "Give me the item at index 42" you want to say "here's an item, give me the five items before it". Or you have something like a calendar date which is absolute; yet — unlike your device's memory — it has effectively no beginning or end, so what you really want here is a "window" into a section of that data.
A better data model for this would be a kind of double-ended queue that is partly a LRU cache. You place a limit on the number of items in the structure. Then as prior items are loaded (user is scrolling up) the items at back end are pushed off, and when subsequent items are added (user is scrolling down), items at the front are pushed off.
Also, you would have a threshold where if you got within a few items of of one edge of the structure, a "loadNext" or "loadPrevious" event would fire and invoke a callback that you set up to push more data onto the edge of the structure.
So once you've figured out that your model is completely different, you realize that even RecyclerView isn't going to help you here because it's tied to the absolute indexing model. You need some sort of custom ViewGroup subclass that recycles item views like a ListView, but can adapt to the double-ended queue. And when you search code repos for something like this, there's nothing out there.
Sounds like fun. I'll post a link when I get a project started. (Sadly, it won't be done in any timely manner to help you right now, sorry.)
Something that might help you a little sooner: look at Google's Calendar implementation and see how they did it: Google Calendar Git repo
What you may be searching for is a FragmentStatePagerAdapter , where you can implement a swiped view, meaning when the user (for example)swipes to the right, a completely new view is displayed.
Using a FragmentStatePagerAdapter , you can handle a huge amount of views without overflowing the memory, because this specific PagerAdapter only keeps the views' states and is explicitly meant to handle large sets of views.
Keeping your example of a calendar, you can implement swiped navigation between for example weeks and generate the week views on demand while only keeping for example the year and the week's number as identifiers.
There are plenty of online tutorials for Android, maybe you have a look at this one
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Android Docs say:
The RecyclerView widget is a more advanced and flexible version of
ListView. This widget is a container for displaying large data sets
that can be scrolled very efficiently by maintaining a limited number
of views. Use the RecyclerView widget when you have data collections
whose elements change at runtime based on user action or network
events
Actually ListView can do all of the above if efficiency doesn't matter, and we have found many issues when we use RecyclerView to replace ListView:
There is no onItemClickListener() for list item selection - solution
No divider between list items - solution
No built-in overlap selector, there is no visual feedback when you click list item - solution
No addHeaderView for list header - solution
Maybe more issues ...
So when we use RecyclerView to replace ListView, we have to do much extra coding to reach the same effect as ListView.
QUESTION:
Is it worth that we replace ListView with RecyclerView totally ?
if not then in which case should we better use RecyclerView instead ListView, and vice versa ?
If ListView works for you, there is no reason to migrate.
If you are writing a new UI, you might be better off with RecyclerView.
RecyclerView is powerful when you need to customize your list or you want better animations. Those convenience methods in ListView caused a lot of trouble to people which is why RecyclerView provides a more flexible solution to them.
The major change you need to make for migration is in your adapter. If you want to keep calling notifyDataSetChanged, you lose most of the animation & binding benefits. But if you can change your adapter to dispatch detailed notify events (added/removed/moved/updated), then you get much better animations and performance. These events let RecyclerView choose correct animations and it also helps it avoid unnecessary onBind calls. You'll get a huge benefit if your item views are complex. Also, going forward, there will be more components around RecyclerView.
1 You can use an interface to provide a click listener. I use this technique with ListViews, too.
2 No divider: Simply add in your row a View with a width of match_parent and a height of 1dp and give it a background color.
3 Simply use a StateList selector for the row background.
4 addHeaderView can be avoided in ListViews, too: simply put the Header outside the View.
So, if efficiency is your concern, then yes, it's a good idea to replace a ListView with a RecyclerView.
I had until recently still been using ListView for very simple lists. For example if I want to display a simple list of text options...
I based that decision on 'human factors', that creating a simple ListView with less code is better if performance is immaterial. I often think of a professor in college that was fond of saying: "My teacher the great Niclaus Wirth, the inventor of Pascal, used to say if a program has more than 50 lines of code it is sure to be wrong..."
But what has convinced me to stop using ListView is that it has recently been moved into the "Legacy" category in the Android Studio design tool along with RelativeLayout.
I think this is 'soft' form of 'deprecation'. It would be too disruptive if it was actually deprecated and all conscientious developers moved their code to RecyclerView.
Further, the intro to ListView warns right at the top that RecyclerView is a better option: "For a more modern, flexible, and performant approach to displaying lists, use RecyclerView."
https://developer.android.com/reference/android/widget/ListView
Also, the guide to ListView is still talking about cursor loaders, but then getSupportCursorLoader() itself has just been deprecated in API 28.
https://developer.android.com/guide/topics/ui/layout/listview
Recent enhancements to Android Studio:
File -> New -> Fragment -> Fragment (List)
This gives us a fully working RecylerView populated with basic text. That gets rid of my last real reason for using ListView because it is now just as easy to set up a basic RecylerView.
In summary, I don't intend to use ListView at all for new development because labelling it has 'legacy' is one step away from deprecating it.
The only case when it's still fine to use ListView is when the list is static . For example: navigation.
For everything else use RecyclerView. Since RecyclerView deals with recycling it will be easier to do visual related things that were tightly coupled in ListView, like changing position / rearrangement, animation (in fact it comes with RecyclerView.ItemAnimator), custom layouts.
Also if you want to use CardView I believe it's the only way to go.
A great alternative is using the BaseAdapter. It supports the use Viewholder pattern and mine contains 100+ rows with bitmaps and buttons and it runs very smooth.
When you are working with a long, big list, certainly one should use ListView because it handles cell recycling.
Notice here, for example Can i use nested linearlayouts instead of list view, for a big list? the OP is asking about ListView verses a dynamic LinearList -- the answer is "have to use a ListView, because of recycling"
Now, say you are making a short list -- imagine say a popup with only 10 or 20 items. It may even fit all on the one screen, so there's no recycling.
In fact, is there any difference between using a ListView and just using a LinearLayout, and dynamically populating the little views inside it?
It seems to me that the latter is in many cases much simpler, more elegant, and easier to work with. But I could well be missing something that seasoned Android engineers know about.
Should I just use an ordinary LinearList (populate it dynamically) for lists where recycling is not relevant? What's the usual, and why? Cheers!
{Incidentally, for popup cases, is there some better, lightweight method for "choose one from a popup-list" that I'm too silly to know about?! :) )
ListView(and other lists) supports very useful idea: splitting data and view. These parts could be changed at any time so it's important to support flexibility. And it could be solved by special mediator object: Adapter. Adapter roughly speaking says how to fill your view with particular data item.
So I'm sure that if you decide to use LinearLayout sooner or later you will implement you own Adapter.
If you used dynamic linear view then rendering the view will take more time as compare to listview. In listview we are rendering views which are visible only but if you used dynamic linear view then its problem.
I am having trouble using an ExpandableListView because the type of childItems in each group varies greatly. In one section there are contacts from the phone box, another has a view with a progressBar in and the last one has a TextView in.
I have thought about using 3 individual ExpandableListViews, each with their own adapter and handlers, but this seems a bit crazy too, particularly when some of the 'lists' only have one item in and it never changes. Essentially I am using ExpandableListViews to create expandable sections in my UI, and it doesn't really feel right.
Is there a better UI element to use?
If they are completely distinct like it sounds like they are, you may want to look into using Fragments. It's a lot of new stuff you learn if you're not familiar with them, but you can then easily reproduce the collapsing mechanic using Animations coupled with hiding the Fragments. This also decouples the 3 UI elements (contacts, progress bar, text view) from each other, so you can reuse the Fragments pretty much anywhere you want.