gpt4 book ai didi

Android onLayout() 和 AsyncTask() 不能一起工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:07:21 24 4
gpt4 key购买 nike

我需要一个带有固定标题的可滚动表格,所以我遵循了 this great blog一切都很好。

想法是使用一个表作为标题,一个表用于在 ScrollView 中添加的内容,它们都在一个自定义的 LinearLayout 中。在自定义的 LinearLayout 中,我们将覆盖 onLayout() 以获取每行的最大宽度,并为表头和内容表的每行设置宽度。

这是 Activity 及其布局:

package com.stylingandroid.ScrollingTable;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;

public class ScrollingTable extends LinearLayout
{
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 );

TableLayout header = (TableLayout) findViewById( R.id.HeaderTable );
TableLayout body = (TableLayout) findViewById( R.id.BodyTable );

if (body.getChildCount() > 0 ) {
TableRow bodyRow = (TableRow) body.getChildAt(0);
TableRow headerRow = (TableRow) header.getChildAt(0);

for ( int cellnum = 0; cellnum < bodyRow.getChildCount(); cellnum++ ){
View bodyCell = bodyRow.getChildAt(cellnum);
View headerCell = headerRow.getChildAt(cellnum);
int bodyWidth = bodyCell.getWidth();
int headerWidth = headerCell.getWidth();
int max = Math.max(bodyWidth, headerWidth);
TableRow.LayoutParams bodyParams = (TableRow.LayoutParams)bodyCell.getLayoutParams();
bodyParams.width = max;
TableRow.LayoutParams headerParams = (TableRow.LayoutParams)headerCell.getLayoutParams();
headerParams.width = max;
}
}
}
}

主.xml

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<com.stylingandroid.ScrollingTable.ScrollingTable
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">

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

<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">

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

</ScrollView>

</com.stylingandroid.ScrollingTable.ScrollingTable>

</LinearLayout>

主要 Activity

 package com.stylingandroid.ScrollingTable;

import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TableLayout;
import android.widget.TableRow;

import android.widget.TextView;

public class ScrollingTableActivity extends Activity
{
private String[][] tableData = {
{"header11111111111", "header2","header3","header4"},
{"column1", "column1","column1","column1"},
{"column1", "column1","column1","column1"},
{"column1", "column1","column1","column1"},


{"column1", "column1",

"column1","column1"},
{"column1", "column1","column1","column1"},
{"column1", "column1","column1","column1"},
{"column1", "column1","column1","column1"},
{"column1", "column1","column1","column1"},
{"column1", "column1","column1","column1"},
{"column1", "column1","column1","column1"},
{"column1", "column1","column1","column1"},
{"column1", "column1","column1","column1"}
};
/** Called when the activity is first created. */
@Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
setContentView( R.layout.main );
TableLayout tableHeader = (TableLayout)findViewById(R.id.HeaderTable);
TableLayout tableBody = (TableLayout)findViewById(R.id.BodyTable);

appendRows(tableHeader, tableBody, tableData);
}

private void appendRows(TableLayout tableHeader ,TableLayout tableContent, String[][] amortization) {
int rowSize=amortization.length;
int colSize=(amortization.length > 0)?amortization[0].length:0;
for(int i=0; i<rowSize; i++) {
TableRow row1 = new TableRow(this);

for(int j=0; j<colSize; j++) {
TextView c = new TextView(this);
c.setText(amortization[i][j]);
c.setPadding(3, 3, 3, 3);
if (i == 0) {
c.setTextColor(Color.BLACK);
}
row1.addView(c);
}

if (i == 0) {
row1.setBackgroundColor(Color.LTGRAY);
tableHeader.addView(row1, new TableLayout.LayoutParams());
} else {
tableContent.addView(row1, new TableLayout.LayoutParams());
}
}
}

上面的代码工作得很好(expected),但是,当我使用 AnysnTask 从服务器获取数据并稍后将数据添加到表中时,自定义 View 中的 onLayout() 不再起作用。我通过注销一些数字来模拟获取数据:

public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
setContentView( R.layout.main );

new MyTask().execute();
}

private class MyTask extends AsyncTask<Void, Void, Void> {

private ProgressDialog progressDialog;
protected void onPreExecute() {
progressDialog = ProgressDialog.show(ScrollingTableActivity.this,
"", "Loading. Please wait...", true);
}
@Override
protected Void doInBackground(Void... reportTypes) {
for (int i = 0; i < 500; i++) {
System.out.println(i);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
TableLayout tableHeader = (TableLayout)findViewById(R.id.HeaderTable);
TableLayout tableBody = (TableLayout)findViewById(R.id.BodyTable);

appendRows(tableHeader, tableBody, tableData);
}

}

因此 onLayout() 仅在我通过将其置于 onCreate() 方法中从主 UI 线程调用 appendRows() 时才起作用。如果我从另一个 UI 线程调用(在 AsyncTask 的 onPostExecute() 中),则会调用 onLayout()(我通过创建一些日志来检查它)但它不会影响 GUI。我尝试使用 invalidate()、forceLayout()、requestLayout() 但没有改变任何东西。 wrong

我认为我们需要调用一个方法来使 GUI 刷新,但不知道它是什么。

最佳答案

你可能想看看这个答案: Android Set textview layout width dynamically

但是,基本上,尝试将每个 TextView 的宽度设置为与标题相同。

这可能需要你做每件事两次,因为你可能需要让系统进行布局,所以使用 View.INVISIBLE,然后你需要退出 AsyncTask,调用另一个, 因此可以进行布局工作。

然后在第二个中,您可以获取不可见的表格,循环查找该列中的最大宽度,然后将该列中的所有 TextView 设置为最大。

这不是最佳解决方案,但应该可行。

我认为您在 AsyncTask 中的主要问题是布局需要完成,然后您可以进行修复。

关于Android onLayout() 和 AsyncTask() 不能一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8613465/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com