I am working on a remote controlling app for a home automation system. The mobile and the home automation device communicate via WebSockets.
To display the functions of the automation device, I am currently using ListViews and Adapters with a varying cell layout. One adapter is displaying all of the device's functions.
The biggest problem I encountered: Adapters keep calling getView() very often, which triggers my functions to register themselves with my state handle and action dispatcher over and over again.
Please note:
There are about 20 different types of functions, all of them requiring a different cell layout. There are sliders, buttons, state text, ...
The functions have asynchronously updating states.
I need to find a way to display those functions in a ListView or a ListView-like layout.
Can you please help me?
Make sure to implement BaseAdapter.getViewTypeCount() which should return the count for the number of different view types your listView is expected to have for its enteries.
And also implement ListAdapter.getItemViewType(int position) to return an int that identifies a specific view and which view type it will be.
Following the above two recommendations will ensure that your ListView will be efficient and it will guarantee that your getView(...) method is called with the appropriate view type, if there is one already infalted.
That said, if you have a few fixed number of view in your list and they are all different, then consider using LinearLayout in a ScrollView.
Related
I am writing my self a ListView that will contain multiple types of items. I have done that using ArrayAdapter and a ListView now my issue is that I need to have some Items inside my Adapter that is gonna expand and that will have inner items of any type. Now the issue is how can I do this? I know I can use ExpandableListView but I don't need some items to be expanded. I saw this post about something similar, The person suggested to use ExpandableListView or a Custom Item, I would like to do the Custom Item but my concern is that the OP of the answer quoted this.
If the number of items is low consider using a linearlayout to look
like a listview and another linearlayout for the last item.
I'm not sure what they mean by "low" How many items can I have inside it? Would it cause lag?
so my question is what is the best way to do this? I need to put items
in a ListView that is of multiple types, and one of the types can
expand and have inner views that can again contain the same types and
so on.
Edit: Since 2 of you confused of what I want. I want to do the following inside my ArrayAdapter
Item
Item
Item
ExpandableItem {
Item
Item
Item
Item
}
Item
Item
I am trying to make some of the Items expand to have more items inside them and control the onClick of the inner items and such.
About the meaning of "low": I think it's about performance but devices today are better than devices were in 2013 when the linked post was written - maybe you'll never experience a sluggish UI with your approach. Of course this depends not only on your UI structure but also on the type of data you'll be showing (videos or just text?) and on other factors like does the device have to perform heavy work in the background or not.
RecyclerView was developed to be a "better ListView", so if performance can be an issue, then maybe it is a good choice. (The adapters for both ViewGroups can handle different View types but RecyclerView offers a better means of showing changes to single items and customizing change animations, another point in its favor)
How can I do this?
Have different View types for expandable and flat items
You can "manually" expand/ shrink a View (AFAIK your only choice when working with ListView) by using some type of animation (or the Transition framework) but you always have to...
Keep track of the expanded state of each expandable item (e.g. in the Adapter) and use them in getView() respectively onBindViewHolder().
Add another ListView like RecyclerView on clicking of any item.
Im creating an native android app which has 4 views and 4 textviews. Each view and textview are connected, beacuse each textview is actually within the view.
Here is a sketch of the layout:
I want to have a central model class to hold values and then the views and textviews should show the models values realtime.
Values should be able to change in the model when changing either a view or a textview or something else internal changes the model, it should also show in the views and textviews.
So how is the best pattern to do this? Is it somehing a pub sub, were values can be send from a view to the model, react on it and then from the model to the views and then react on it visually?
My first try is making the model static so it can remember values but I really feel the architecture is bad. Any ideas?
I'm not sure if I understood your problem... but maybe creating a custom view to warp your View and TextView and a ViewModel with the values that you want to keep.
Your ViewModel could expose LivteData to your custom view and your custom view can observe this changes and update the values.
Check out these links, maybe it can help you
https://developer.android.com/jetpack/docs/guide
https://developer.android.com/topic/libraries/architecture/viewmodel
I was prototyping an app with a recycler view where it boiled down to basically this concept:
There is one single list, which is entirely scrollable (this bit is important).
The items in question in the recycler view are however very heterogeneous. It is not like I want to have either an image or a text, but sometimes it is a simple "list item (clickable text)", sometimes it is a row with 3 buttons, sometimes it is an icon with text, another one is a button, etc.
While similar item types have similar behaviour, the groups itself are different. They need a different manager, a different ViewHolder to process their very different button events etc.
I find it not very convenient to put everything into the recycler view's adapter with some common base class and delegate everything those different items can do to some callbacks. It feels very clunky.
Is there some better way of handling that? The advantage of the recycler view is that it scrolls well. I personally do not need any lazy creation of those items (= recycling) so I am not winning much here. The other advantage is that I do not need to handle every items creation. Which is also the downside, I need to channel it through the adapter with its getItemViewType based on position etc.
Since RecyclerView uses ViewHolders, it means that you must have a predefined layout for each row. But what if each row needs to have a variable amount of views displayed?
For example, say I'm creating an instant messaging application where users can attach pictures to messages. They could attach anywhere from 0 to x pictures. When you create a RecyclerView to display these pictures (that are downloaded from a server), how would you make the rows include the correct number of ImageViews to display them?
There's a few ways I can think of doing this, but none really seem like good options.
Create ImageViews in onBindViewHolder, add them to a layout in the ViewHolder. (Isn't this what the ViewHolder tries to prevent? This would probably be laggy, especially with lots of pictures)
Restrict the amount of pictures the user can attach to a message to x, then add x ImageViews to the layout that are set to invisible/gone. In onBindViewHolder, set the ImageViews to display the picture and set these ImageViews visible. (What if I allow pictures & videos to be attached? Do I then need to add x ImageViews and x VideoViews as well?)
Put a GridView in each RecyclerView item and populate the GridView
inside onBindViewHolder. (I assume this would have no benefit over
option #1 because it's pretty much the same thing?)
That's all I can think of. Is there any other option that is designed for this sort of situation that I have not come across? Or what are the typical approaches taken towards this problem?
You need to create a heterogenous RecyclerView which will display multiple different ViewHolders. There are several ways to accomplish this.
The basic approach is that based on the number of photos/videos associated with each item in your RecyclerView.Adapter you would override getItemViewType(int position) (a method which is part of the RecyclerView.Adapter class) to return a different int. This int is the viewType parameter passed into createViewHolder(ViewGroup parent, int viewType). You would then use the correct ViewHolder/layout based on the viewType argument.
See here for a good tutorial.
If you don't mind using a library for an alternate approach I recommend AdapterDelegates.
I have an app on the iPhone that is completely table view driven. On android all I see is a static table, how can I create a table that I can populate with data that I requested from the network.
You could use either ListView or GridView. ListView has a method getView which you override to customize ListView item. This very much like (UITableViewCell *)tableView... in iphone, except that you needn't count the height of each cell. If you want to have something like tableView with sections you could use ExpandableListView. Here are links to Android ListView, Android Expandable ListView and Android GridView. There can also be found very useful examples in Android Dev web-site.
You can use GridView or ListView with custom View for row. In both cases you can supply a BaseAdaper (or a subclass of it) through which you can manipulate the data.
If you want the exact grid border like example here you go Android Grid Border... Obviously you can render data dynamically from whatever the source is...