【发布时间】:2012-01-22 08:42:54
【问题描述】:
我有一个LinearLayout 视图,其中已经包含多个元素。我想以编程方式向它添加更多视图。因为这是在ScrollView 内,所以所有内容都会滚动。
所以我要做的是浏览我的列表,并将我的自定义视图的新实例添加到其中。该自定义视图扩展了 XML 布局并添加了一些方法。
这种方法效果很好。问题是它非常慢,即使没有任何疯狂的代码……一个包含 10 个项目的列表需要大约 500 毫秒来实例化。从用户体验的角度来看,这很难接受。
我的问题是,这是正确/最好的方法吗?尽管“R.layout.my_list_item”非常简单,但 Android 似乎需要花费大量时间来扩充布局。我想知道是否有一种方法可以将“膨胀”布局重用于其他视图,有点缓存更复杂的解析?
我已经尝试使用ListView(以及适配器和包装器)来执行此操作,它似乎要快得多。问题是我不能使用简单的ListView;我的布局比一个简单的列表更复杂(LinearLayout 本身包含额外的自定义图标,并且在被ScrollView 包裹之前,它还有另一个父级具有更多视图)。
但是有没有办法为 LinearLayout 使用适配器?这会比尝试自己添加视图更快吗?
感谢任何帮助。我很想加快速度。
代码如下。
主要活动:
// 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);
}
我的列表项:
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);
}
}
我想要完成的是这个。考虑这种布局:
此布局是一个FrameLayout(外框),其中包含一个ImageView(灰色)、一个TextView(内部矩形,在顶部)和一个LinearLayout(内部矩形,在底部)。这个LinearLayout 矩形是我动态填充的几个项目。
填充后,我希望最终结果是这样的(每个新矩形都是一个新的MyListItem 实例):
也就是说,一切都是可滚动的(例如,背景图像在顶部对齐)。 LinearLayout 本身不能滚动(其他所有内容都在后面),因此据我所知,为什么 ListView 不能很好地工作
就我而言。
【问题讨论】:
-
该活动中有多少个元素,是否有任何自定义类继承 UI 元素?
-
ListViews 如此之快,因为它们回收了项目布局。他们夸大了填满屏幕所需的项目布局数量。向下滚动时,顶部的一个视图被隐藏,底部的一个视图被显示。列表视图从顶部获取旧的、不可见的视图,并将新数据放在底部。避免昂贵的通货膨胀。总的来说:这里看起来非常效率低下,我很确定你想做的任何事情都可以通过列表视图来完成。如果您展示您尝试过的内容并发布您的预期布局草图,我们可以帮助您解决这个问题。
-
保罗:元素不多。也许是 4 或 5 个。是的,其中一些是从基本框架继承的自定义类。 alexsc:感谢您的解释。我添加了一个图表,可以更好地解释我的情况,因此很清楚我是否以及如何使用 ListView 代替(或不)。
-
@zeh:这可能没有多大帮助,但您每次在
init()中“获得”LayoutInflater的事实可能会为每次通话增加相当多的时间。我会在主要活动中获得一次充气机,然后将对它的引用传递给init()。这样,您只需调用一次getSystemService(Context.LAYOUT_INFLATER_SERVICE),并且您也不需要调用getContext(),因为主要活动可以直接执行此操作。只是一个想法 - 它可能会稍微加快速度。 -
@zeh 好吧,我发现这比我最初的要复杂一些。在我写一个长答案之前如何做到这一点:I wrote a short throwaway layout-prototype project with a ListView。看看这是否是大约。你想要的结果。它有点简化:背景不是图像,而是简单的灰色。您可以通过将列表视图
android:background设置为可绘制文件夹(在main.xml 中) 中的图像来更改它。列表项也是简单的默认项。这可以通过使用自定义适配器轻松更改。
标签: android layout view android-linearlayout inflate