FerDensetsu FerDensetsu - 18 days ago 6
Java Question

Including many external layouts in a single XML file affects performance?

I'm writing an application that uses a bunch of forms. Every form is designed in a separate XML file and then included into another "main" XML file. Then, what I do programmatically is to set the visibility of just one of them to VISIBLE, and the rest are set to GONE, and this changes according to a spinner that selects what form you want to see.

So far I've only added 4 forms and everything seems to work fine, but the app is meant to hold like 30 different forms.

Is this alright or should I inflate and replace the forms like Fragments? Every form has its own class that manages the widgets and logic, and these classes implements an interface so I can use polymorphism to clean or send the form.

Part of my main.xml where I embeed the forms

<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>


This is an example of a class I use to manage a form

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
}

}


Then, on my Main Activity I have something like:

//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...

}


So basically what happens here is that I have all my forms embeeded and hidden in a single layout, so I can manage all its widgets with a single View object. But again, is this OK?

Answer

When a view's visibility is set to gone it does not get rendered. This means that having hundreds of hidden views in a layout does not slow down performance when changes happen in the views that are visible.

Loading hundreds of views from an xml then you ll see a performance issue when your activity starts, because parsing such a big xml file is too much work.

If you load those views programmaticaly you wont have such a big performance issue at your activity's start...However all those views hold objects and that leads an increase of your app's memory usage. Depending on what other things you do this could lead to a serious memory problem.

You should choose one of the solutions provided by the Android SDK for handling cases like this. ViewPager, ViewStub, Fragments etc...These approaches will save you from memory problems as they destroy the unnecessary views when they should be destroyed (assuming that you will implement them correctly)

Comments