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
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>
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.
Astuce curieuse, mais cela fonctionne en effet. – Jonik
pouvez-vous développer cela? Peut-être avec du code? – SoloPilot
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
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);
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
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
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());
}
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);
essayer ce http://stackoverflow.com/questions/20241614/android-fixed-header-horizontal-and-vertical-scrolling-table/26211896#26211896 ans –
Il ne supporte pas le défilement horizontal –