Chcę mieć tabelę dynamiczną, z dodanymi wierszami w wyniku interakcji użytkownika, używając TableLayout wewnątrz ScrollView. Działa to dobrze, ale kiedy chcę przewinąć do końca tabeli przy użyciu fullScroll()
, zawsze opuszcza ostatnią linię; oznacza to, że przewija się tak, że widoczny jest jeden przed ostatnim. Ostatnia linia jest widoczna podczas przewijania ręcznego, a pasek przewijania również jest prawidłowy.Przewiń do ostatniego wiersza TableLayout w ScrollView
Jestem oczywiście otwarty na sugestie, jak zrobić lepszy układ z tego; ale jestem szczególnie zainteresowany zrozumieniem, dlaczego zachowuje się w ten sposób fullScroll()
. Czy powinienem podać inny parametr, czy też użyć czegoś zupełnie innego? Czy może to zrobić, ponieważ nowo dodana linia nie jest jeszcze jakoś widoczna? (jeśli tak, jak mogę to rozwiązać?) Czy też przegapiłem inną oczywistą rzecz?
Następujący kod replikuje problem:
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>
Edycja: odsyłające zaimplementowałem Romain Guy „s rozwiązanie następujące:
W TestActivity.java wymienić:
// Scrolls to line before last - why?
((ScrollView) findViewById(R.id.TableScroller)).fullScroll(View.FOCUS_DOWN);
z:
// 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);
}
});
który działa dobrze.
Dzięki - to była jedna z rzeczy, o których podejrzewałem, ale nie miałem pojęcia, jak łatwo to naprawić. Dziękuję za pomoc w leczeniu lęku przed wszystkim związanym z wątkami :-) – Joubarc