Quiero tener una tabla dinámica, con filas añadieron con el tiempo como resultado de la interacción del usuario, utilizando un TableLayout dentro de un ScrollView. Esto funciona bien, pero cuando quiero para desplazarse hasta el extremo de la mesa usando fullScroll()
, siempre deja fuera la última línea; es decir, se desplaza para que el anterior al último sea visible. La última línea es visible cuando se desplaza manualmente, y la barra de desplazamiento también es correcta.Desplazarse a la última línea de TableLayout dentro de un ScrollView
estoy, por supuesto, abierto a sugerencias en cuanto a cómo hacer un mejor diseño fuera de este; pero estoy específicamente interesado en entender por qué fullScroll()
se comporta de esa manera. ¿Debo darle un parámetro diferente, o usar algo completamente distinto? ¿O lo hace porque la línea recién agregada aún no está visible de alguna manera? (De ser así, ¿cómo puedo resolver eso?) ¿O me perdí alguna otra cosa obvia?
El siguiente código se replica el problema:
TestActivity.java:
package com.example.android.tests;
import java.util.Random;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button) findViewById(R.id.AddRow)).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Random rnd = new Random();
TableRow nr = new TableRow(v.getContext());
for (int c=0; c<3; c++) {
TextView nv = new TextView(v.getContext());
nv.setText(Integer.toString(rnd.nextInt(20)-10));
nr.addView(nv);
}
((TableLayout) findViewById(R.id.Table)).addView(nr);
// Scrolls to line before last - why?
((ScrollView) findViewById(R.id.TableScroller)).fullScroll(View.FOCUS_DOWN);
}
});
}
}
Main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:text="Add Row"
android:id="@+id/AddRow"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
<ScrollView
android:id="@+id/TableScroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@id/AddRow"
android:layout_alignParentTop="true" >
<TableLayout
android:id="@+id/Table"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="0,1,2" />
</ScrollView>
</RelativeLayout>
Editar: para referencia, he implementado Romain Guy 's solución como sigue:
En TestActivity.java, reemplace:
// Scrolls to line before last - why?
((ScrollView) findViewById(R.id.TableScroller)).fullScroll(View.FOCUS_DOWN);
con:
// Enqueue the scrolling to happen after the new row has been layout
((ScrollView) findViewById(R.id.TableScroller)).post(new Runnable() {
public void run() {
((ScrollView) findViewById(R.id.TableScroller)).fullScroll(View.FOCUS_DOWN);
}
});
que funciona muy bien.
Gracias - era una de las cosas que sospechaba, pero no tenía idea de que sería tan fácil de arreglar. Gracias por ayudarme a curar mi miedo a todo lo relacionado con los hilos :-) – Joubarc