onPostExecute() is called on the UI thread. On Mon, Dec 26, 2011 at 1:20 AM, Binh Nguyen <[email protected]> wrote: > Hi experts, > > I need a scrollable table with fixed header, so I followed this great > blog (http://blog.stylingandroid.com/archives/432) and everything is > fine. > > The idea is using one table for header, one table for content added in > scrollview, both of them are in a customized LinearLayout. In > customized LinearLayout, we will overwrite the onLayout() to get the > max width of each row and set width for each row of both header and > content table. > > Here is the activity and its layout: > > 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; > } > } > } > } > > main.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> > > Main 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()); > } > } > } > > > The above code work perfectly, however, when I use AnysnTask to get > data from server and add data to table later, the onLayout() in my > custom view doesn't work anymore. I simulate getting data by log out > some number: > > 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); > } > > } > > So the onLayout() only work when I call appendRows() from main UI > thread by putting it in onCreate() method. If I call from another > thread (in onPostExecute() of AsyncTask), the onLayout() is called (I > checked it by create some logs) but it doesn't effect to the GUI. I > tried with invalidate(), forceLayout(), requestLayout() but doesn't > change anything. > > I think we need to call a method to make the GUI refresh but don't > know what it is, I have searched and tried a lot of ways in 2 days but > got nothing, so it will be very appreciated if you can give any idea > about this. > > Many thanks, > Binh Nguyen > > -- > You received this message because you are subscribed to the Google > Groups "Android Developers" group. > To post to this group, send email to [email protected] > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/android-developers?hl=en
-- Romain Guy Android framework engineer [email protected] -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

