2010-06-21 64 views
12

我想要一個動態表,隨着時間的推移,由於用戶交互,在ScrollView中使用TableLayout添加行。這工作正常,但是當我想滾動到表的末尾使用fullScroll()時,它總是捨棄最後一行;也就是說,它滾動以便最後一個之前的那個可見。手動滾動時最後一行是可見的,滾動條也是正確的。滾動到ScrollView中的TableLayout的最後一行

我當然樂於接受有關如何更好地設計佈局的建議;但我特別有興趣瞭解爲什麼fullScroll()表現如此。我應該給它一個不同的參數,還是完全使用其他的東西?或者是否這樣做是因爲新添加的行在某種程度上還不可見? (如果是這樣,我該如何解決這個問題?)或者我錯過了其他一些明顯的東西?

下面的代碼複製問題:

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> 

編輯:供參考,我實現Romain Guy的解決方案如下:

在TestActivity.java,替換:

  // Scrolls to line before last - why? 
      ((ScrollView) findViewById(R.id.TableScroller)).fullScroll(View.FOCUS_DOWN); 

有:

  // 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); 
       } 

      }); 

工作正常。

回答

15

當你正在做你的fullScroll()佈局還沒有發生,所以ScrollView使用表的「舊」大小。不要立即調用fullScroll(),而應使用View.post(Runnable)。

+0

謝謝 - 這是我懷疑的事情之一,但沒有真正的想法,這將是如此簡單的修復。感謝您幫助我治癒我對所有線程相關的恐懼:-) – Joubarc 2010-06-22 05:46:49

2

上面找到有用的提示,這裏是一個簡單的實現,滾動滾動型,使給定的孩子可見......

一:準備下面的輔助類

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)稱它爲像這樣

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