开发者

Android scrollable TableLayout with a dynamic fixed header

I have a TableLayout inside a ScrollView, that is I have a scrollable TableLayo开发者_运维百科ut! It is populated dynamically when I create Dialog's in different places of an Activity.

Actually everything works fine, but the fact that for every case there's a different header (with a title for each column) on that table and it scrolls along with the rows. As the content of that table is dynamic, the amount (as well as the width) of columns is unknown.

So, basically, that's my problem. I don't see point in posting code, as I need mostly a suggestion/workaround, but if that would help overcome the issue, let me know. Would appreciate some samples very much.


Here is a way : http://sdroid.blogspot.com/2011/01/fixed-header-in-tablelayout.html

Note that there is a way to have this work every time : what you have to do is create a similar dummy row in the header, and set the texts in both dummies to the longest string you can find in the row (in number of chars, or, even better, do the comparison with Paint.getTextWidths)


    package com.test.test;

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

    public class TestProjectTestActivity extends Activity {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            TableLayout tl_head1 = (TableLayout)findViewById(R.id.tl_head);
            TableLayout tl_child1 = (TableLayout)findViewById(R.id.tl_child);

            String headcol1="";
            TableRow tr[]= new TableRow[40];
            TextView tv[] = new TextView[1000];
            for(int i=0; i <=30; i++)
            {

                tr[i]=new TableRow(this);


                for(int j=1; j<=5; j++)
                {
                    tv[j]=new TextView(this);
                    tv[j].setId(j);
                    tv[j].setText("testingmultiple data hello"+""+j);
                    tv[j].setTextColor(Color.WHITE);


                    if(headcol1.length() < tv[j].getText().length())
                    {
                        headcol1=null;
                        headcol1=tv[j].getText().toString();
                    }
                    tr[i].addView(tv[j]);
                }

                tl_child1.addView(tr[i]);
            }

            TableRow trhead= new TableRow(this);
            TextView tvhead[] = new TextView[5];

            for(int i=0;i<=4;i++)
            {
                tvhead[i] = new TextView(this);
                tvhead[i].setTextColor(Color.WHITE);
                tvhead[i].setHeight(0);
                tvhead[i].setText(headcol1);
                trhead.addView(tvhead[i]);

            }
            tl_head1.addView(trhead);


        }
    }



<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/hsv_main"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <LinearLayout
        android:id="@+id/ll_main"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TableLayout
            android:id="@+id/tl_head"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >

            <TableRow
                android:id="@+id/tr_head"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" >
                <TextView
                android:id="@+id/tv_hidden1"
                android:layout_gravity="center_horizontal"
                android:text="12"
                android:textColor="#FFFFFF"
                 />
                <TextView
                android:id="@+id/tv_hidden2"

                android:layout_gravity="center_horizontal"
                android:text="123"
                android:textColor="#FFFFFF"

                />
                <TextView
                android:id="@+id/tv_hidden3"

                android:layout_gravity="center_horizontal"
                android:text="1234"
                android:textColor="#FFFFFF"

                />
                <TextView
                android:id="@+id/tv_hidden4"

                android:layout_gravity="center_horizontal"
                android:text="12345"
                android:textColor="#FFFFFF"

                />
                <TextView
                android:id="@+id/tv_hidden5"

                android:layout_gravity="center_horizontal"
                android:text="123456"
                android:textColor="#FFFFFF"
                              />

            </TableRow>
        </TableLayout>

        <ScrollView
            android:id="@+id/sv_child"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >

            <TableLayout
                android:id="@+id/tl_child"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" >
            </TableLayout>
        </ScrollView>
    </LinearLayout>
</HorizontalScrollView>


Android scrollable TableLayout with a dynamic fixed header is very simple. Follow this steps

Step 1:

Create a TableLayout and use android:layout_alignParentTop="true" this will keep this layout always in top.

Step 2:

With in ScrollView create another TableLayout for contents with out Rows (For Dynamic content).

Step 3:

Add Rows and columns dynamically. While adding each column (TextView) assign the width to an temporary variable.

Ex

tvContentText.measure(0, 0); tempmaxwidth=tvContentText.getMeasuredWidth();

Step 4: Check for max width and assign max width to main variable.

Ex:

if (tempmaxwidth > maxwidth) maxwidth=tempmaxwidth;

Step 5: After assigning content details. Assign the max width of each column to its header column.

Ex:

TextView tvh1 = (TextView) findViewById(R.id.h1); tvh1.setWidth(maxwidth);

The xml and code is below

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TableLayout
        android:id="@+id/headertbl"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:background="@color/colorPrimary"
        android:layout_height="wrap_content"
        android:stretchColumns="*">
        <TableRow>
            <TextView
                android:id="@+id/h1"
                android:layout_height="wrap_content"
                android:text="H1"
                android:textStyle="bold"
                android:textAlignment="center"
                android:textSize="20sp" />
            <TextView
                android:id="@+id/h2"
                android:layout_height="wrap_content"
                android:text="H2"
                android:textStyle="bold"
                android:textAlignment="center"
                android:textSize="20sp" />
            <TextView
                android:id="@+id/h3"
                android:layout_height="wrap_content"
                android:text="H3"
                android:textStyle="bold"
                android:textAlignment="center"
                android:textSize="20sp" />
            <TextView
                android:id="@+id/h4"
                android:layout_height="wrap_content"
                android:text="H4"
                android:textStyle="bold"
                android:textAlignment="center"
                android:textSize="20sp" />
        </TableRow>
    </TableLayout>

    <ScrollView
        android:layout_below="@id/headertbl"
        android:id="@+id/container"
        android:layout_marginTop="10dp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical">
     <TableLayout
         android:id="@+id/contenttbl"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:stretchColumns="*">
        </TableLayout>
    </ScrollView>
</RelativeLayout>

MainActivity.xml

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TableLayout tl = (TableLayout) findViewById(R.id.contenttbl);

    int tempmaxwidth=0,maxwidth=0;
    int tempmaxwidth1=0,maxwidth1=0;
    int tempmaxwidth2=0,maxwidth2=0;
    int tempmaxwidth3=0,maxwidth3=0;

    for(int i=0;i<50;i++)
    {
        TableRow newRow = new TableRow(getApplicationContext());
        newRow.setId(i);
        TextView tvContentText = new TextView(getApplicationContext());
        if(i!=6)
            tvContentText.setText("Content 1");
        else
            tvContentText.setText("---- Content with Max width");
            tvContentText.setTextColor(Color.BLACK);
            tvContentText.setTextSize(16f);
            tvContentText.measure(0, 0);
            tempmaxwidth=tvContentText.getMeasuredWidth();

        if (tempmaxwidth>maxwidth)
            maxwidth=tempmaxwidth;

        TextView tvContentText1 = new TextView(getApplicationContext());
        //tvContentText1.setText(Integer.toString(maxwidth));
        tvContentText1.setText("Content 2");
        tvContentText1.setTextColor(Color.BLACK);
        tvContentText1.setTextSize(16f);
        tvContentText1.measure(0, 0);
        tempmaxwidth1=tvContentText1.getMeasuredWidth();

        if (tempmaxwidth1>maxwidth1)
            maxwidth1=tempmaxwidth1;

        TextView tvContentText2 = new TextView(getApplicationContext());
        tvContentText2.setText("Content 3");
        tvContentText2.setTextColor(Color.BLACK);
        tvContentText2.setTextSize(16f);
        tvContentText2.measure(0, 0);
        tempmaxwidth2=tvContentText2.getMeasuredWidth();

        if (tempmaxwidth2>maxwidth2)
            maxwidth2=tempmaxwidth2;

        TextView tvContentText3 = new TextView(getApplicationContext());
        tvContentText3.setText("Content 4");
        tvContentText3.setTextColor(Color.BLACK);
        tvContentText3.setTextSize(16f);
        tvContentText3.measure(0, 0);
        tempmaxwidth3=tvContentText3.getMeasuredWidth();

        if (tempmaxwidth3>maxwidth3)
            maxwidth3=tempmaxwidth3;

        newRow.addView(tvContentText);
        newRow.addView(tvContentText1);
        newRow.addView(tvContentText2);
        newRow.addView(tvContentText3);
        tl.addView(newRow);
    }
    // Assigning Max width to header column
    TextView tvh1 = (TextView) findViewById(R.id.h1);
    tvh1.setWidth(maxwidth);

    TextView tvh2 = (TextView) findViewById(R.id.h2);
    tvh2.setWidth(maxwidth1);

    TextView tvh3= (TextView) findViewById(R.id.h3);
    tvh3.setWidth(maxwidth2);

    TextView tvh4= (TextView) findViewById(R.id.h4);
    tvh4.setWidth(maxwidth3);
}


Well for me I didn't want to go through the trouble of worrying about alignment of columns so I created this first of all:

public static Boolean SET_TABLE_HEADER;

Then I created this function to set my TableHeader:

public void setTableHeader(TableLayout tbl) {
    TableRow tr = new TableRow(context);

    TextView tcView = new TextView(context);
    tcView.setText("Class");
    tcView.setTextColor(Color.BLACK);
    tcView.setAllCaps(true);
    tcView.setTypeface(null, Typeface.BOLD);
    tcView.setGravity(Gravity.CENTER_HORIZONTAL);
    tr.addView(tcView);

    TextView tfView = new TextView(context);
    tfView.setText("Fee");
    tfView.setTextColor(Color.BLACK);
    tfView.setAllCaps(true);
    tfView.setTypeface(null, Typeface.BOLD);
    tfView.setGravity(Gravity.CENTER_HORIZONTAL);
    tr.addView(tfView);

    TextView tqView = new TextView(context);
    tqView.setText("Available");
    tqView.setTextColor(Color.BLACK);
    tqView.setAllCaps(true);
    tqView.setTypeface(null, Typeface.BOLD);
    tqView.setGravity(Gravity.CENTER_HORIZONTAL);
    tr.addView(tqView);

    // Adding row to Table
    tbl.addView(tr);

    // Table Header Has Been Set
    SET_TABLE_HEADER = false;
}

Then inside my loop:

if (SET_TABLE_HEADER) {
    setTableHeader(tbl);
}

Where tbl is the instance of my TableLayout in my view. This works for me.

Of course you will have to initialize SET_TABLE_HEADER to true at the point where you start creating your table.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜