I have a LinearLayout
view that already contains several elements. I want to add a lot more Views to it, programmatically. And because this is inside a ScrollView
, everything will be scrolled.
So what I do is go through my list, and add new instances of my custom View to it. That custom view inflates a XML layout and adds a few methods.
This approach works well. The problem is that it's super slow, even without any crazy code... a list with 10 items takes around 500ms to instantiate. As an user experience standpoint, this is hard to swallow.
My question is, is this the correct/best approach? Android seems to take a lot of time inflating the layout, even though "R.layout.my_list_item" is super simple. I wonder if there's a way to maybe to reuse "inflated" layouts for additional views, kinda caching the more complex parsing?
I've tried doing this with a ListView
(and adapter and a wrapper) and it seems to be much faster. The problem is that I can't use a simple ListView
; my layout is more complex than a simple list (the LinearLayout
itself contains additional custom icons, and it has another parent with even more Views before it's wrapped by the ScrollView
).
But is there a way to use an adapter for a LinearLayout? Would that be faster than trying to add the views myself?
Any help is appreciated. I'd love to make this faster.
Code follows.
Main Activity:
// The LinearLayout that will contain everything
lineList = (LinearLayout) findViewById(R.id.lineList);
// Add a lot of items for testing
for (int i = 0; i < 10; i++) {
addListItem("Item number " + i);
}
protected void addListItem(String __title) {
MyListItem li;
li = new MyListItem(this);
li.setTitle(__title);
lineList.addView(li);
}
MyListItem:
public class MyListItem extends RelativeLayout {
protected TextView textTitle;
public MyListItem(Context __context) {
super(__context);
init();
}
public MyListItem(Context __context, AttributeSet __attrs) {
super(__context, __attrs);
init();
}
public MyListItem(Context __context, AttributeSet __attrs, int __attrsdefStyle) {
super(__context, __attrs, __attrsdefStyle);
init();
}
protected void init() {
// Inflate the XML layout
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_list_item, this);
// Create references
textTitle = (TextView)findViewById(R.id.textTitle);
}
public void setTitle(String __text) {
textTitle.setText(__text);
}
}
What I'm trying to accomplish is this. Consider this layout:
This layout is a FrameLayout
(outer box) containing a ImageView
(in gray), a TextView
(inner rectangle, on top) and a LinearLayout
(inner rectangle, on bottom). This LinearLayout
rectangle is the one I'm dynamically populating with a few items.
After I populate it, I want the final result to be this (where every new rectangle is a new MyListItem
instance):
That is, everything is scrollable (the background image, for example, is aligned on top). The LinearLayout
isn't scrollable by itself (everything else follows) hence why a ListView
, from what I know, wouldn't work very well
in my case.
LayoutInflater
each time ininit()
may be adding a fair amount of time to each call. I'd get the inflater once in the main activity and then pass a reference to it intoinit()
. That way, you only callgetSystemService(Context.LAYOUT_INFLATER_SERVICE)
once and you don't need thegetContext()
call either as the main activity can do it directly. Just an idea - it might speed things up slightly. – Rancidandroid:background
to an image from your drawable folder (in main.xml). Also the list items are simple default items. This can easily be changed by using a custom adapter. – BelaborListView
is by hooking up an event to theListView
's scroll and then scrolling aLinearLayout
in parallel on the background, with all elements I need. Kinda hacky but it might work. I just wish there was a way to optimize a linearlayout.addView() a little bit though, it'd be enough for my case (it's not a huge list). – CouncilMyListItem
as shown by you, on an HTC Desire I can generate 10 in under 20ms and 500 in just under 500ms. I know you say the list items you want to display contain icons etc but generating 10 takes 500ms??? That's a 25x increase on what it takes my Desire to generate the simple TextView based items - a big difference. – Rancid