2009-11-09 22 views
11

Okay, also ich habe dieses TableLayout, und es ist voll von Daten - mit allen Zeilen programmgesteuert hinzugefügt. Ich habe das TableLayout innerhalb einer HorizontalScrollView, die wiederum in einer ScrollView ist - das gibt mir Scrollen sowohl horizontal als auch vertikal. Ich versuche jetzt, eine Kopfzeile hinzuzufügen, die nicht scrollt. Ich habe versucht, Dinge zu verschieben, so dass meine beiden Scroll-Ansichten tatsächlich innerhalb des TableLayout waren und die TableRows zu HorizontalScrollView hinzugefügt wurden. Meine Hoffnung war, dass ich dann die Kopfzeile außerhalb der Bildlaufansichten hinzufügen konnte.Android TableLayout Header Zeile

Die einzige andere Sache, die ich für die Kopfzeile ein zweites Tabellenlayout denken kann nur von mir zu haben, aber die Spalten immer scheint zu aufreihen wie es schwierig sein würde. Irgendwelche Ideen?

Antwort

11

Ein Ansatz besteht darin, ein innerhalb eines anderen Tablelayouts Tablelayouts der Zeile Einbetten und den Header in der vorhergehenden Zeile setzen, wie unten gesehen. Das Ausrichten der Daten und des Headers erfordert, dass die Eigenschaft layout_width des Headers View-Objekte und die View-Objekte des Datenelements auf die gleichen Dip-Werte gesetzt werden. Außerdem muss die Eigenschaft layout_weight der View-Objekte der inneren TableLayout-Datei mit der entsprechenden Kopfzeile übereinstimmen. Jetzt, in der XML unten, habe ich 3 TextViews in der inneren TableLayout in einer einzigen Zeile platziert, um mit den Spaltenüberschriften übereinzustimmen. Dies ist nur um zu zeigen, wie die Ausrichtung durchgeführt werden kann. Sie können diese Daten programmatisch auffüllen, indem Sie ein Layout aufblähen und zur Laufzeit hinzufügen.

<?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

versuchen, diese ans http://stackoverflow.com/questions/20241614/android-fixed-header-horizontal-and-vertical-scrolling-table/26211896#26211896 –

+0

Es unterstützt nicht für horizontale Scroll –

13

Ich kam tatsächlich mit einer anderen anständigen Art und Weise, dies zu tun.

bauen einfach die Tabelle normalerweise mit der Kopfzeile als erste Zeile, innerhalb einer vertikalen Ausrichtung Linearlayout. Als Nächstes entfernen Sie programmgesteuert die erste Zeile und fügen Sie sie als erstes untergeordnetes Element zu LinearLayout hinzu. Das hat wie ein Zauber funktioniert.

Edit: Dies funktioniert auch ohne statische Spaltenbreiten angeben zu müssen.

+0

Neugieriger Trick, aber das funktioniert tatsächlich. – Jonik

+0

können Sie das erweitern? Vielleicht mit etwas Code? – SoloPilot

+0

Ich habe eine ((ViewGroup) tableRow.getParent()). RemoveChild (tableRow); dann linearLayout.addView (tableRow); und während es die Kopfzeile entfernte, wurde es nicht angezeigt, noch hielt es die Spaltenbreite. Ich habe dies onCreate() getan. Vielleicht muss es an einem anderen Ort sein. – James

3

Ich weiß, dass die Frage ist alt, aber es war das erste, dass Google mir gab, als ich das gleiche Problem gehabt haben. Und da ich denke, dass ich eine bessere Lösung gefunden habe, möchte ich es teilen.

Idee: setzen Sie das Tablelayout (im Scroll) in RelativeLayout und ein Overlay erstellen, dass die erste (Header) die Reihe über alles anderes ziehen würde.

Hier layout.xml ist:

<?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> 

Und hier ist der Code:

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

Daumen hoch! Ich verstehe nicht ganz, wie das funktioniert, aber es funktioniert! Sehr elegant, in der Tat :-) – mmo

+0

Das Problem mit diesem Ansatz ist, dass es ein Speicherleck verursacht! Man erstellt und fügt bei jedem Neuzeichnen einen neuen fakeHeaderView zum tableWrapper hinzu (die untergeordnete Liste wächst und wächst, wie mit dem Debugger überprüft werden kann). Und - wie ich herausfand, experimentiere - aus irgendeinem seltsamen Grund kann man alte Instanzen nicht entfernen, sonst wird der zuletzt hinzugefügte nicht richtig gezeichnet und der ganze Effekt funktioniert nicht! Irgendwelche Hinweise darauf? – mmo

0

Für diejenigen, die nicht zufrieden mit mit Ihren Größen vordefinieren, fand ich ein bisschen wie ein Hack das funktioniert für mich.

Im Grunde, erstellen Sie eine separate Tabelle für den Titel und legen Sie sie über Ihre Haupttabelle, aber mit der gleichen Top Ausrichtung, dann erstellen Sie zwei Kopien der Titelzeile und nach dem Hinzufügen eines der Haupttabelle, fügen Sie die anderen zu Titeltabelle und legen Sie die layoutParams der untergeordneten Ansicht für die Zeile der Haupttabelle fest.

Hier ist mein grundlegendes Beispiel.

in Ihrem Layout:

<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> 

Dann, wenn Sie Ihre Zeilen hinzufügen:

//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

Verwenden von zwei Tablelayout One in Scroll gerne geben 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> 

dann eine gemeinsame Ansicht erstellen für REIHEN und wichtigste Erwähnung 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> 

Jetzt in Aktivität

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);