2010-06-21 8 views
12

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.

Odpowiedz

15

W czasie wykonywania funkcji fullScroll() układ jeszcze się nie pojawił, więc ScrollView używa "starego" rozmiaru dla tabeli. Zamiast od razu wywoływać funkcję fullScroll(), użyj polecenia View.post (Runnable).

+0

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

2

Znalezienie wskazówkę powyżej użyteczny, tutaj jest prosta implementacja, która przewija się Scrollview aby dana dziecko widoczne ...

a: Przygotować następujące klasy pomocnika

public class ScrollToTrick implements Runnable { 

ScrollView scroller; 
View  child; 

ScrollToTrick(ScrollView scroller, View child) { 
    this.scroller=scroller; 
    this.child=child; 

} 
public void run() { 
    scroller.scrollTo(0, child.getTop()); 
} 
} 

b) nazwać podoba mi się to:

my_scroller.post(new ScrollToTrick(my_scroller,child_to_scroll_to));