滚动到TableLayout的滚动型中的最后一行TableLayout

2023-09-06 02:02:22 作者:只想独占沵的①切

我想有一个动态表,添加了随着时间的推移用户交互的结果行,使用TableLayout内的滚动型。这工作得很好,但是当我想用滚动到表的末尾fullScroll(),它总是让出最后一行;也就是说,它滚动,使得前的最后一个是可见的。手动滚动时的最后一行是可见的,并且滚动条是正确的了。

I want to have a dynamic table, with rows added over time as a result of user interaction, using a TableLayout inside a ScrollView. This works fine, but when I want to scroll to the end of the table using fullScroll(), it always leaves out the last line; that is, it scrolls so that the one before the last one is visible. The last line is visible when scrolling manually, and the scrollbar is correct too.

我当然愿意听取建议的,如何做一个更好的布局出了这一点;但我理解为什么 fullScroll()的行为这种方式特别感兴趣。我应该给它一个不同的参数,或者用别的东西完全?或者它这样做,因为新添加的行尚未出现不知何故? (如果是这样,我怎么能解决呢?)还是我错过了一些其他的显而易见的事?

I'm of course open to suggestions as to how to make a better layout out of this; but I'm specifically interested in understanding why fullScroll() behaves that way. Should I give it a different parameter, or use something else altogether? Or does it do that because the newly added line isn't yet visible somehow? (if so, how can I solve that?) Or did I miss some other obvious thing?

下面code复制问题:

The following code replicates the problem:

TestActivity.java:

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中:

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>

编辑:仅供参考,我实现了罗曼盖伊的解决方案如下:

for reference, I implemented Romain Guy's solution as follows:

在TestActivity.java,替换:

In TestActivity.java, replace:

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

            });

,工作正常。

Which works fine.

推荐答案

目前你正在做你fullScroll()布局还没有发生,所以滚动型使用老大小表的时间。而不是调用fullScroll()马上的,使用View.post(Runnable接口)。

At the time you are doing your fullScroll() the layout has not happened yet, so the ScrollView uses the "old" size for the table. Instead of calling fullScroll() right away, use View.post(Runnable).