I am trying to determine the best way to have a single ListView that contains different layouts for each row. I know how to create a custom row + custom array adapter to support a custom row for the entire list view, but how can I implement many different row styles in the ListView?
相关问题
- How can I create this custom Bottom Navigation on
- Bottom Navigation View gets Shrink Down
- How to make that the snackbar action button be sho
- Listening to outgoing sms not working android
- How to create Circular view on android wear?
相关文章
- android开发 怎么把图片放入drawable的文件夹下
- android上如何获取/storage/emulated/下的文件列表
- androidStudio有个箭头不认识
- SQLite不能创建表
- Windows - Android SDK manager not listing any plat
- Animate Recycler View grid when number of columns
- Why is the app closing suddenly without showing an
- Android OverlayItem.setMarker(): Change the marker
Take a look in the code below.
First, we create custom layouts. In this case, four types.
even.xml
odd.xml
white.xml
black.xml
Then, we create the listview item. In our case, with a string and a type.
After that, we create a view holder. It's strongly recommended because Android OS keeps the layout reference to reuse your item when it disappears and appears back on the screen. If you don't use this approach, every single time that your item appears on the screen Android OS will create a new one and causing your app to leak memory.
Finally, we create our custom adapter overriding getViewTypeCount() and getItemViewType(int position).
And our activity is something like this:
now create a listview inside mainactivity.xml like this
In your custom array adapter, you override the getView() method, as you presumably familiar with. Then all you have to do is use a switch statement or an if statement to return a certain custom View depending on the position argument passed to the getView method. Android is clever in that it will only give you a convertView of the appropriate type for your position/row; you do not need to check it is of the correct type. You can help Android with this by overriding the getItemViewType() and getViewTypeCount() methods appropriately.
If we need to show different type of view in list-view then its good to use getViewTypeCount() and getItemViewType() in adapter instead of toggling a view VIEW.GONE and VIEW.VISIBLE can be very expensive task inside getView() which will affect the list scroll.
Please check this one for use of getViewTypeCount() and getItemViewType() in Adapter.
Link : the-use-of-getviewtypecount
Since you know how many types of layout you would have - it's possible to use those methods.
getViewTypeCount()
- this methods returns information how many types of rows do you have in your listgetItemViewType(int position)
- returns information which layout type you should use based on positionThen you inflate layout only if it's null and determine type using
getItemViewType
.Look at this tutorial for further information.
To achieve some optimizations in structure that you've described in comment I would suggest:
ViewHolder
. It would increase speed because you won't have to callfindViewById()
every time ingetView
method. See List14 in API demos.I hope that will help you. If you could provide some XML stub with your data structure and information how exactly you want to map it into row, I would be able to give you more precise advise. By pixel.
ListView was intended for simple use cases like the same static view for all row items.
Since you have to create ViewHolders and make significant use of
getItemViewType()
, and dynamically show different row item layout xml's, you should try doing that using the RecyclerView, which is available in Android API 22. It offers better support and structure for multiple view types.Check out this tutorial on how to use the RecyclerView to do what you are looking for.
You already know the basics. You just need to get your custom adapter to return a different layout/view based on the row/cursor information being provided.
A
ListView
can support multiple row styles because it derives from AdapterView:If you look at the Adapter, you'll see methods that account for using row-specific views:
The latter two methods provide the position so you can use that to determine the type of view you should use for that row.
Of course, you generally don't use AdapterView and Adapter directly, but rather use or derive from one of their subclasses. The subclasses of Adapter may add additional functionality that change how to get custom layouts for different rows. Since the view used for a given row is driven by the adapter, the trick is to get the adapter to return the desired view for a given row. How to do this differs depending on the specific adapter.
For example, to use ArrayAdapter,
getView()
to inflate, populate, and return the desired view for the given position. ThegetView()
method includes an opportunity reuse views via theconvertView
parameter.But to use derivatives of CursorAdapter,
newView()
to inflate, populate, and return the desired view for the current cursor state (i.e. the current "row") [you also need to overridebindView
so that widget can reuse views]However, to use SimpleCursorAdapter,
SimpleCursorAdapter.ViewBinder
with asetViewValue()
method to inflate, populate, and return the desired view for a given row (current cursor state) and data "column". The method can define just the "special" views and defer to SimpleCursorAdapter's standard behavior for the "normal" bindings.Look up the specific examples/tutorials for the kind of adapter you end up using.