调用 requestLayout 时明显变慢

Visible slowness when calling requestLayout

我有一个包含 TableLayout 的 Dialogfragment。我用自定义 class(如下所示)包装了 TableLayout,因为我想要一个固定的 header 和一个滚动的 body。我希望 header 与 body 正确对齐。自定义 class 通过覆盖 onLayout 来实现。

            <com.ui.components.ScrollingTable
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:gravity="center"
                android:layout_weight="1"
                android:background="@color/transaction_table_bg">

                <TableLayout
                    android:id="@+id/tlScrollingTableHeader"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

                <ScrollView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:scrollbarStyle="outsideOverlay"
                    android:fillViewport="true">

                    <TableLayout
                        android:id="@+id/tlScrollingTableBody"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"/>

                </ScrollView>

            </com.ui.components.ScrollingTable>

我使用以下 class 来包装 TableLayout。

public class ScrollingTable extends LinearLayout {

    private static final String TAG = ScrollingTable.class.getSimpleName();

    public ScrollingTable (Context context) {
        super(context);
    }

    public ScrollingTable (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        super.onLayout(changed, l, t, r, b);

        List<Integer> colWidths = new LinkedList<Integer>();

        TableLayout header = (TableLayout) findViewById(R.id.tlScrollingTableHeader);
        TableLayout body = (TableLayout) findViewById(R.id.tlScrollingTableBody);

        // Measure content width first
        for (int rownum = 0; rownum < body.getChildCount(); rownum++) {
            TableRow row = (TableRow) body.getChildAt(rownum);
            int countCells = 0;
            for (int cellnum = 0; cellnum < row.getChildCount(); cellnum++) {
                View cell = row.getChildAt(cellnum);
                if (cell.getVisibility() == VISIBLE) {
                    Integer cellWidth = cell.getWidth();
                    if (colWidths.size() <= countCells) {
                        colWidths.add(cellWidth);
                    } else {
                        Integer current = colWidths.get(countCells);
                        if (cellWidth > current) {
                            colWidths.remove(countCells);
                            colWidths.add(countCells, cellWidth);
                        }
                    }
                    countCells++;
                }
            }
        }

        // Figure out if header needs resizing first based on widths
        TableRow headerRow = (TableRow) header.getChildAt(0);
        for (int count = 0; count < colWidths.size(); count++) {
            if (headerRow.getChildAt(count).getWidth() >= colWidths.get(count)) {
                colWidths.remove(count);
                colWidths.add(count, headerRow.getChildAt(count).getWidth());
            }
        }

        // Then apply to header
        for (int rownum = 0; rownum < header.getChildCount(); rownum++) {
            TableRow row = (TableRow) header.getChildAt(rownum);
            for (int cellnum = 0; cellnum < row.getChildCount(); cellnum++) {
                View cell = row.getChildAt(cellnum);
                TableRow.LayoutParams params = (TableRow.LayoutParams) cell.getLayoutParams();
                params.width = colWidths.get(cellnum);
                cell.requestLayout();
            }
        }
    }
}

除一个问题外,此方法运行良好。当对话框打开时,我可以清楚地看到由于 requestLayout 而调整列的大小。有办法解决这个问题吗?

按照 Nguyen 的建议,我转到了另一个线程。但是我删除了 requestLayout。相反,在新线程中,我使用了以下似乎可以解决问题的方法。

    @Override
    protected void onPostExecute(Void result) {
        tableHeader.setColumnCollapsed(0, false);
        tableContent.setColumnCollapsed(0, false);
    }