2009-11-09 35 views
11

さて、このTableLayoutとそのデータが満載です。すべての行がプログラムによって追加されています。 Horizo​​ntalScrollViewの内部にTableLayoutがあります。これはScrollViewの内部にあります。これにより、水平方向と垂直方向の両方にスクロールできます。私が今しようとしているのは、スクロールしないヘッダー行を追加することです。私はスクロールビューの両方が実際にはTableLayoutの内側にあり、Horizo​​ntalScrollViewにTableRowsを追加するように物事を移動しようとしました。私の望みは、スクロールビューの外にヘッダー行を追加することでした。Android TableLayoutヘッダー行

私が考えることができる唯一のものは、ヘッダー行だけのために2番目の表レイアウトを持つことですが、列を整列させることは難しいようです。何か案は?

答えて

11

1つのアプローチは、別のTableLayoutの行にTableLayoutを埋め込み、下に示すように前の行にヘッダーを置くことです。データとヘッダーを整列するには、ヘッダViewオブジェクトのlayout_widthプロパティとデータのViewオブジェクトを同じディップ値に設定する必要があります。また、内部TableLayoutのViewオブジェクトのlayout_weightプロパティは、対応するヘッダーと一致する必要があります。 以下のXMLでは、3つのTextViewを内側のTableLayoutに1列で配置して、列見出しと一致させました。これは、どのようにアラインメントを行うことができるかを示すためのものです。レイアウトを拡張し、実行時に追加することによって、プログラムでデータを読み込むことができます。

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


    <TableRow> 
    <TextView android:text="Name" 
     android:layout_width="100dp"   
     android:layout_column="0" 
     android:layout_weight="1"/> 
    <TextView android:text="Score" 
     android:layout_width="30dp" 
     android:layout_column="1" 
     android:layout_weight="1"> 
    </TextView> 
    <TextView android:text="Level" 
     android:layout_width="30dp" 
     android:layout_column="2" 
     android:layout_weight="1"> 
    </TextView> 
    </TableRow> 

    <ScrollView android:layout_height="120dp">  
    <TableLayout android:id="@+id/score_table" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent">   
    <TableRow> 
     <TextView android:text="Al" 
     android:layout_width="100dp"   
     android:layout_column="0" 
     android:layout_weight="1"> 
     </TextView> 
     <TextView android:text="1000" 
     android:layout_width="30dp" 
     android:layout_column="1" 
     android:layout_weight="1"> 
     </TextView> 
     <TextView android:text="2" 
     android:layout_width="30dp" 
     android:layout_column="2" 
     android:layout_weight="1"> 
     </TextView> 
    </TableRow> 
    </TableLayout> 
    </ScrollView>  
</TableLayout> 
+0

が、これはhttp://stackoverflow.com/questions/20241614/android-fixed-header-horizo​​ntal-and-vertical-scrolling-table/26211896#26211896 ANSしてみてください –

+0

水平スクロールをサポートしていません –

13

私は実際これを行うための別のまともな方法を思いついた。

通常、ヘッダー行を最初の行として、垂直方向のLinearLayoutの内部に作成するだけです。次に、最初の行をプログラムで削除し、それを最初の子としてLinearLayoutに追加します。これは魅力的に機能しました。

編集:静的な列幅を指定しなくても機能します。

+0

奇妙なトリックですが、これは実際に動作します。 – Jonik

+0

これを拡張できますか?おそらくいくつかのコードですか? – SoloPilot

+0

私は((ViewGroup)tableRow.getParent())しました。removeChild(tableRow);次にlinearLayout.addView(tableRow);ヘッダー行を削除している間は表示されず、列幅も保持されませんでした。私はこれをonCreate()でした。たぶんそれは別の場所にいる必要があります。 – James

3

私は質問が古いことを知っていますが、私が同じ問題を抱えていたのでGoogleが私に与えたのは最初のものでした。私はより良い解決策を見つけたと思うので、私はそれを共有したいと思います。

アイデア:ScrollView内のTableLayoutをRelativeLayoutに配置し、最初の(ヘッダー)行を描画するオーバーレイを作成します。ここで

がlayout.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:id="@+id/table_wrapper" 

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

     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 

     tools:ignore="UselessParent" 
    > 
     <TableLayout 

      android:id="@+id/table" 

      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
     /> 
    </ScrollView> 
</RelativeLayout> 

そして、ここのコードです:あなたのサイズを事前に定義する必要に満足していない人のために

TableLayout table = (TableLayout)view.findViewById(R.id.table); 

final TableRow headerRow = new TableRow(context); 
table.addView(headerRow); 

table.addView(new TableRow(context)); 
table.addView(new TableRow(context)); 
table.addView(new TableRow(context)); 


RelativeLayout tableWrapper = (RelativeLayout)view.findViewById(R.id.table_wrapper); 

View fakeHeaderView = new View(context) { 
    @Override 
    public void draw(Canvas canvas) { 
     headerRow.draw(canvas); 
    } 
    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

     int width = headerRow.getMeasuredWidth(); 
     int height = headerRow.getMeasuredHeight(); 

     widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); 
     heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); 

     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 
}; 

tableWrapper.addView(fakeHeaderView); 
+0

Thumbs up!私はこれがどういう仕組みか分かりませんが、それはあります!非常にエレガントな、確かに:-) – mmo

+0

このアプローチの問題は、メモリリークを引き起こすことです! 1つは、各再描画時に新しいfakeHeaderViewを作成してtableWrapperに追加します(子リストは、デバッガで確認できるように拡大および拡大します)。そして、私がこれを試してみたように - 何らかの奇妙な理由で古いインスタンスを削除できない場合や、最後に追加されたインスタンスが正しく描画されず、全体の効果がうまくいかない場合それについてのヒント? – mmo

0

、私はハックのビットを発見しましたそれは私のために働いています。

基本的に、タイトルの別のテーブルを作成し、それをメインテーブルの上に配置しますが、同じTopアライメントを使用して、タイトル行を2つ作成し、メインテーブルに追加した後、タイトルテーブルを作成し、子テーブルのlayoutParamsをメインテーブルの行に設定します。

これは私の基本的な例です。あなたのレイアウトで

<HorizontalScrollView 
    android:id="@+id/table_horizontal_scroll_view" 
    android:layout_alignParentTop="true" 
    android:layout_width="wrap_content" 
    android:layout_height="match_parent" 
    android:clickable="false"> 

    <RelativeLayout 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     > 

     <ScrollView 
      android:layout_alignParentTop="true" 
      android:layout_marginTop="0dp" 
      android:id="@+id/table_vertical_scroll_view" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content"> 

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

     </ScrollView> 

     <TableLayout 
      android:layout_alignLeft="@+id/table_vertical_scroll_view" 
      android:layout_alignRight="@+id/table_vertical_scroll_view" 
      android:layout_alignStart="@+id/table_vertical_scroll_view" 
      android:layout_alignEnd="@+id/table_vertical_scroll_view" 
      android:layout_alignParentTop="true" 
      android:background="@color/grid_view_background" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/grid_floating_row_layout" 
      /> 

    </RelativeLayout> 


</HorizontalScrollView> 

次に、あなたがあなたの行を追加します。ScrollViewで

//clear out any views 
    tableLayout.removeAllViews(); 
    floatingRowLayout.removeAllViews(); 

    TableRow[] rows = getTableContentRows() // content of your table 
    TableRow[] titleRows = {getTitleRow(), getTitleRow()}; //two copies of your title row 
    tableLayout.addView(titleRows[0]); // first add the first title to the main table 
    addRows(rows) // add any other rows 

    floatingRowLayout.addView(titleRows[1]); // floatingRowLayout is connected to id/grid_floating_row_layout 

    titleRows[0].setVisibility(View.INVISIBLE); // make the title row added to the main table invisible 

    // Set the layoutParams of the two title rows equal to each other. 
    // Since this is done after the first is added to the main table, they should be the correct sizes. 
    for(int i = 0; i < titleRows[0].getChildCount(); i++) { 
     titleRows[1].getChildAt(i).setLayoutParams(titleRows[0].getChildAt(i).getLayoutParams()); 
    } 
0

使用する2つのtableLayoutワンなどがandroid:stretchColumns="*"

<RelativeLayout 
      android:layout_width="match_parent" 
      android:orientation="vertical" 
      android:paddingTop="5dp" 
      android:layout_height="match_parent" 
      android:layout_below="@+id/llSpinner"> 
      <TableLayout 
       android:layout_width="match_parent" 
       android:id="@+id/tableHead" 
android:stretchColumns="*" 
       android:layout_height="wrap_content"> 
      </TableLayout> 

     <ScrollView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_above="@+id/tableTotal" 
      android:layout_below="@+id/tableHead" 
      android:id="@+id/scrolltable"> 


     </ScrollView> 
    <TableLayout 
       android:layout_width="match_parent" 
       android:id="@+id/tableTotal" 
android:stretchColumns="*" 
       android:layout_alignParentBottom="true" 
       android:layout_height="wrap_content"> 
      </TableLayout> 
     </RelativeLayout> 

を与え、その後、共通のビューを作成ROWと最も重要な言及のためにandroid:layout_width="0dp"

<TableRow 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="?android:attr/listPreferredItemHeight" 
    android:focusable="true" 
    android:focusableInTouchMode="false" 
    android:clickable="true" 
    android:background="@android:drawable/list_selector_background"> 

    <TextView 
     android:text="S.No" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:id="@+id/tbsNo" 
     android:layout_weight="1" 
     android:gravity="center" 
     android:layout_column="1" /> 

    <TextView 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:text="Date" 
     android:layout_weight="1" 
     android:gravity="center" 
     android:id="@+id/tbDate" 
     android:layout_column="2" /> 


    <TextView 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:text="Count" 
     android:layout_weight="1" 
     android:gravity="center" 
     android:id="@+id/tbMrCount" 
     android:layout_column="3" /> 
</TableRow> 

今の活動に

Tablelayout tableHeading =(TableLayout)findViewById(R.id.tableHead); 


       Tablelayout table =(TableLayout) findViewById(R.id.table_repots); 
        trHeading = (TableRow) getLayoutInflater().inflate(R.layout.table_row_item, null); 
       trHeading.setBackgroundColor(Color.parseColor("#6688AC")); 
       trHeading.setPadding(0,10,0,10); 

       TextView tv; 
       tv = (TextView) trHeading.findViewById(R.id.tbsNo); 
       tv.setText("S.No"); 
      tv = (TextView) trHeading.findViewById(R.id.tbDate); 
      tv.setText("Date"); 
      table.addView(tv);