Joe Who Joe Who - 8 days ago 9
Android Question

How to increase layouting performance

I have dynamic and quite large contents which needs to be populated on user interaction (click next / prev page).
The dynamic contents displayed programmatically on myTableLayout (see xml below). Each time user clicked next/prev
page then I call

myTableLayout.removeAllViews()
, do some stuff and repopulate with
myTableLayout.addView()
.
On small contents it draws quite fast, but I notice two to three seconds lag if populating large contents.

I already saw an application that do same functionality as mine (also with quite large contents) but it really paging so fast
even on low-end device.

Need some advice on how to increase the layout performance.

Thanks.

Note: Upper TableLayout used as title (header), LinearLayout below it is where the contents placed.




<TableLayout
android:layout_width="fill_parent"
android:layout_height="45dip"
android:stretchColumns="0,2"
android:shrinkColumns="0,2"
>
<TableRow>
<LinearLayout
android:id="@+id/llLeft"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/tvLeft1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>

<LinearLayout
android:id="@+id/llCenter"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/tvCenter1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
/>

<TextView
android:id="@+id/tvCenter2"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
/>
</LinearLayout>

<LinearLayout
android:id="@+id/llRight"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/tvRight1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
</TableRow>
</TableLayout>

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<com.MyScrollView
android:id="@+id/myScrollView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>

<TableLayout
android:id="@+id/**myTableLayout**"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:shrinkColumns="1"
android:stretchColumns="1"
/>

</com.MyScrollView>
</LinearLayout>




Here is the code that create the dynamic content. The content fetched from memory (ArrayList) so it should not be the problem.

private void gotoPage() {
myTableLayout.removeAllViews();
GlobalVar g = GlobalVar.getInstance();
ArrayList<String> arrScripts = g.getDatasMap().get(SCRIPT_INDEX);
ArrayList<String> arrTrans = g.getTranslationMap().get(SCRIPT_INDEX);
Log.i(APP_NAME, "finished preparing data");

try {

// Data Title
tvCenter1.setText(arrScripts.get(0));
tvCenter2.setText(" (" + SCRIPT_INDEX + ")");

int countScripts = arrScripts.size();
for(int i=1; i<countScripts; i++) {

// Row Script
TableRow trScript = new TableRow(this);
trScript.setPadding(0, 5, 0, 0);
TextView tvIndex = new TextView(this);
tvIndex.setGravity(Gravity.CENTER);
tvIndex.setWidth(40);
tvIndex.setText("" + i);

TextView tvScript = new TextView(this);
tvScript.setGravity(Gravity.RIGHT);
tvScript.setTypeface(g.getFontTypeFace());
tvScript.setTextSize(FONT_SIZE);
tvScript.setPadding(0, 0, 5, 0);
tvScript.setText(arrScripts.get(i));

trScript.addView(tvIndex);
trScript.addView(tvScript);

TableRow trTrans = null;

if(IS_USE_TRANSLATION) {
// Row Translation
trTrans = new TableRow(this);

TextView tvBlank = new TextView(this);
tvBlank.setPadding(0, 0, 0, 5);
TextView tvTrans = new TextView(this);
tvTrans.setPadding(0, 0, 0, 5);
tvTrans.setText(arrTrans.get(i));

trTrans.addView(tvBlank);
trTrans.addView(tvTrans);
}

// Place for line separator
View vSep = new View(this);
ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
p.height = 3;
vSep.setLayoutParams(p);

// Combine rows to table
if(IS_USE_SCRIPT) myTableLayout.addView(trScript);
if(IS_USE_TRANSLATION) myTableLayout.addView(trTrans);
myTableLayout.addView(vSep);
}
} catch (Exception e) {
Log.e(APP_NAME, e.getMessage());
}
}


Here is the traceview result.

Answer

I agree with @amplify91 that it might be from generating the content, but one of the other things you might want to look at is the number of layouts you are using. The basic thought is "the fewer the better". You can check out some of googles layout tricks

Example: I see your header is a table with linearlayouts with textviews. Couldn't that be fixed by a Relative layout with the textviews as children?

You'll save some Views, and also some 'depth' in the layout tree.

Comments