2010-06-21 7 views
12

Tôi muốn có một bảng động, với các hàng được thêm vào theo thời gian do sự tương tác của người dùng, sử dụng TableLayout bên trong một ScrollView. Điều này làm việc tốt, nhưng khi tôi muốn di chuyển đến cuối bảng bằng cách sử dụng fullScroll(), nó luôn luôn rời khỏi dòng cuối cùng; có nghĩa là, nó cuộn để cái trước khi cái cuối cùng hiển thị. Dòng cuối cùng hiển thị khi cuộn theo cách thủ công và thanh cuộn cũng chính xác.Di chuyển đến dòng cuối cùng của TableLayout trong ScrollView

Tôi tất nhiên mở để gợi ý về cách tạo bố cục tốt hơn trong số này; nhưng tôi đặc biệt quan tâm đến việc hiểu tại sao fullScroll() hoạt động theo cách đó. Tôi có nên cho nó một tham số khác, hoặc sử dụng cái gì khác hoàn toàn không? Hay nó làm điều đó bởi vì dòng mới được thêm vào chưa được nhìn thấy bằng cách nào đó? (Nếu vậy, làm thế nào tôi có thể giải quyết điều đó?) Hoặc tôi đã bỏ lỡ một số điều hiển nhiên khác?

Các mã sau tái tạo vấn đề:

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> 

Edit: để tham khảo, tôi thực hiện Romain Guy 's giải pháp như sau:

Ở TestActivity.java, thay thế:

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

với:

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

      }); 

nào hoạt động tốt.

Trả lời

15

Tại thời điểm bạn đang làm fullScroll() bố cục chưa xảy ra, vì vậy ScrollView sử dụng kích thước "cũ" cho bảng. Thay vì gọi fullScroll() ngay lập tức, hãy sử dụng View.post (Runnable).

+0

Cảm ơn - đó là một trong những điều tôi nghi ngờ nhưng không có ý tưởng thực sự sẽ dễ dàng sửa chữa. Cảm ơn đã giúp tôi chữa nỗi sợ của tôi về mọi thứ liên quan đến luồng :-) – Joubarc

2

Tìm gợi ý ở trên hữu ích, đây là một thực hiện đơn giản mà cuộn một scrollview để làm cho một đứa trẻ được nhìn thấy ...

một: Chuẩn bị lớp helper sau

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) gọi nó là như thế này

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