我正在编写一个使用大量表单的应用程序。每个表单都是在一个单独的XML文件中设计的,然后包含在另一个" main" XML文件。然后,我以编程方式执行的操作是将其中一个的可见性设置为VISIBLE,其余的设置为GONE,并根据选择要查看的表单的微调器进行更改。
到目前为止,我只添加了4个表单,一切似乎都运行良好,但该应用程序意味着可以容纳30种不同的表单。
这没关系,还是应该像片段一样膨胀和替换表格?每个表单都有自己的类来管理小部件和逻辑,这些类实现了一个接口,因此我可以使用多态来清理或发送表单。
我的main.xml的一部分,我在其中嵌入了表单
<RelativeLayout
android:id="@+id/fr_form_layouts"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<include
android:id="@+id/fr_layout_1"
android:visibility="gone"
layout="@layout/my_layout_1"/>
<include
android:id="@+id/fr_layout_2"
android:visibility="gone"
layout="@layout/my_layout_2"/>
<include
android:id="@+id/fr_layout_3"
android:visibility="gone"
layout="@layout/my_layout_3"/>
<include
android:id="@+id/fr_layout_4"
android:visibility="gone"
layout="@layout/my_layout_4"/>
</RelativeLayout>
这是我用来管理表单
的类的示例public class MR01FormWidgets implements MyFormInterface {
private EditText someEditText;
private View view;
public MR01FormWidgets(View view) {
this.view = view;
//Initialize widgets with findViewById
}
@Override
public boolean isFormValid() {
return true;
}
@Override
public void cleanForm() {
//Cleans form
}
@Override
public void sendForm() {
//Sends form
}
}
然后,在我的主要活动中,我有类似的东西:
//The spinner defines the layoutId and calls this method
private void replaceFormView(View view, int layoutId) {
view.findViewById(visibleForm).setVisibility(View.GONE);//Hides the previous form
visibleForm = layoutId;//sets the new visible form
view.findViewById(visibleForm).setVisibility(View.VISIBLE);//makes it visible
MyFormInterface currentForm;
if(visibleForm == R.id.fr_layout_1)
currentForm = new MR01FormWidgets(view);
else if(visibleForm == R.id.fr_layout_2)
currentForm = new MR02FormWidgets(view);
//And so on...
}
所以基本上这里发生的是我将所有表单嵌入并隐藏在单个布局中,因此我可以使用单个View对象管理其所有窗口小部件。但是,这又好吗?
答案 0 :(得分:0)
首先,您应该使用FrameLayout
作为父级,而不是RelativeLayout
当您担心表现时。
如果视图为GONE
,则大部分时间都会跳过该视图,因为您可以看到,例如这里有FrameLayout.onMeasure
实现。因此,您可以看到一个视图且隐藏了29个视图的事实不应该太对性能不利。
即使性能影响在运行时可能不会太糟糕,所有这些观点都需要夸大。会有延迟,甚至有些冻结。
在添加第4个视图后我开始担心我的实现,在7日左右有点担心,当我达到30时我会确定我错过了什么。
如果你有一个对象列表,你应该使用某种适配器,并可能以更动态的方式管理这些视图。以ViewPager
为例:它只会膨胀可见的View
和每边的相邻视图。但这一切都取决于它应该如何表现。
答案 1 :(得分:0)
当视图的可见性设置为已消失时,它不会被渲染。这意味着,在可见的视图中发生更改时,布局中包含数百个隐藏视图不会降低性能。
从xml加载数百个视图,然后在活动开始时会看到性能问题,因为解析这么大的xml文件太多了。
如果您以程序方式加载这些视图,那么在您的活动开始时您将不会遇到如此大的性能问题...但是所有这些视图都会保留对象并导致应用程序的内存使用量增加。根据你做的其他事情,这可能会导致严重的记忆问题。
您应该选择Android SDK提供的解决方案之一来处理这样的情况。 ViewPager,ViewStub,Fragments等......这些方法可以避免内存问题,因为它们会在销毁它们时销毁不必要的视图(假设您将正确实现它们)