2009-11-09 7 views
11

Ok, donc j'ai ce TableLayout, et son plein de données - avec toutes les lignes ajoutées par programmation. J'ai le TableLayout à l'intérieur d'un HorizontalScrollView, qui à son tour est à l'intérieur d'un ScrollView - cela me donne le défilement à la fois horizontalement et verticalement. Ce que j'essaie de faire maintenant est d'ajouter une ligne d'en-tête qui ne défilera pas. J'ai essayé de déplacer des choses de sorte que mes deux affichages de défilement étaient réellement à l'intérieur du TableLayout et en ajoutant les TableRows à HorizontalScrollView; mon espoir était de pouvoir ensuite ajouter la ligne d'en-tête en dehors des vues de défilement. La seule autre chose que je peux penser est d'avoir une deuxième disposition de table juste pour la rangée d'en-tête, mais obtenir les colonnes pour aligner semble que ce serait difficile. Des idées?Ligne d'en-tête Android TableLayout

Répondre

11

Une approche consiste à incorporer une TableLayout dans une autre ligne de TableLayout et à placer l'en-tête dans la ligne précédente comme indiqué ci-dessous. L'alignement des données et de l'en-tête nécessite que la propriété layout_width des objets View de l'en-tête et des objets View des données soit définie sur les mêmes valeurs de trempette. En outre, la propriété layout_weight des objets View de TableLayout internes doit correspondre à son en-tête correspondant. Maintenant, dans le XML ci-dessous, j'ai placé 3 TextViews dans le TableLayout interne dans une seule ligne pour correspondre avec les en-têtes de colonne. C'est juste pour montrer comment l'alignement peut être fait. Vous pouvez remplir ces données par programmation en gonflant une mise en page et en l'ajoutant au moment de l'exécution.

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

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

+0

Il ne supporte pas le défilement horizontal –

13

En fait, j'ai trouvé une autre façon décente de le faire.

Construisez simplement la table normalement avec la rangée d'en-tête comme première rangée, à l'intérieur d'une LinearLayout à orientation verticale. Ensuite, supprimez par programme la première ligne, puis ajoutez-la en tant que premier enfant à LinearLayout. Cela a fonctionné comme un charme.

Éditer: Cela fonctionne aussi sans avoir à spécifier les largeurs de colonnes statiques.

+0

Astuce curieuse, mais cela fonctionne en effet. – Jonik

+0

pouvez-vous développer cela? Peut-être avec du code? – SoloPilot

+0

J'ai fait un ((ViewGroup) tableRow.getParent()). RemoveChild (tableRow); then linearLayout.addView (tableRow); et alors qu'il supprimait la ligne d'en-tête, il ne l'affichait pas et ne conservait pas la largeur de la colonne. J'ai fait ceci onCreate(). Peut-être qu'il doit être dans un autre endroit. – James

3

Je sais que la question est ancienne, mais c'était la première, que Google m'a donné car j'ai eu le même problème. Et puisque je pense avoir trouvé une meilleure solution, j'aimerais la partager. Idée: placez TableLayout (à l'intérieur de ScrollView) dans RelativeLayout et créez une superposition qui dessine la première ligne (d'en-tête) sur tout le reste.

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

Et voici le 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

Pouce en l'air! Je ne comprends pas très bien comment cela fonctionne, mais c'est le cas! Très élégant, en effet :-) – mmo

+0

Le problème avec cette approche est qu'elle provoque une fuite de mémoire! On crée et ajoute un nouveau fakeHeaderView au tableWrapper à chaque redessiner (la liste des enfants grandit et grandit comme on peut le vérifier avec le débogueur). Et - comme je l'ai découvert expérimenter avec cela - pour une raison étrange, on ne peut pas supprimer les anciennes instances ou bien le dernier ajouté n'est pas correctement dessiné et l'effet entier ne fonctionne pas! Des indices à ce sujet? – mmo

0

Pour ceux qui ne heureux d'avoir à prédéfinir vos tailles, j'ai trouvé un peu un hack ça marche pour moi. Fondamentalement, faites un tableau séparé pour le titre et placez-le sur votre table principale, mais avec le même alignement Top, puis créez deux copies de la rangée de titre et après en avoir ajouté une à la table principale, ajoutez l'autre à la table titre et définissez layoutParams de la vue enfant dans la ligne de la table principale.

Voici mon exemple de base.

dans votre mise en page:

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

Ensuite, lorsque vous ajoutez vos lignes:

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

Utilisez deux TableLayout un dans ScrollView like donner 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> 

puis créer une vision commune pour les emprises et la mention la plus importante: 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> 

maintenant en activité

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