web-dev-qa-db-fra.com

Comment créer une table avec des bordures dans Android?

J'utilise une disposition de tableau pour afficher les données sous forme de tableau, mais je veux un tableau avec des colonnes définies par l'utilisateur et des lignes avec des bordures. Suggestions?

172
Pinki

Ma solution à ce problème consiste à placer une ressource xml exploitable sur le champ d’arrière-plan de chaque cellule. De cette manière, vous pouvez définir une forme avec la bordure souhaitée pour toutes les cellules. Le seul inconvénient est que les bordures des cellules extrêmes ont la moitié de la largeur des autres, mais ce n'est pas un problème si votre table remplit tout l'écran.

Un exemple:

drawable/cell_shape.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
  xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape= "rectangle"  >
        <solid Android:color="#000"/>
        <stroke Android:width="1dp"  Android:color="#ff9"/>
</shape>

layout/my_table.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical">

    <TableRow
        Android:id="@+id/tabla_cabecera"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"></TableRow>

    <TableLayout
        Android:id="@+id/tabla_cuerpo"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">

        <TableRow
            Android:id="@+id/tableRow1"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content">

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

        </TableRow>

        <TableRow
            Android:id="@+id/tableRow2"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content">

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>
        </TableRow>

        <TableRow
            Android:id="@+id/tableRow3"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content">

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

        </TableRow>

        <TableRow
            Android:id="@+id/tableRow4"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content">

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

            <TextView
                Android:id="@+id/textView1"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:background="@drawable/cell_shape"
                Android:padding="5dp"
                Android:text="TextView"
                Android:textAppearance="?android:attr/textAppearanceMedium"></TextView>

        </TableRow>
    </TableLayout>


</LinearLayout>

Edit: un exemple

enter image description here

Edit2: Un autre exemple (avec plus d'éléments: coins de cercle, dégradés ...) enter image description here

J'ai expliqué ce problème avec plus de détails dans http://blog.intelligenia.com/2012/02/programacion-movil-en-Android.html#more . C'est en espagnol mais il y a des codes et des images de tables plus complexes.

189
David Jesse

Je suis d'accord avec Brad. C'était une réponse affreuse. La documentation de Android indique que les conteneurs TableLayout n'affichent pas de lignes de bordure; leur envoi sur le site Android ne les aidera donc pas un peu. J'ai trouvé une solution "sale" sur droidnova, qui consiste à définir une couleur d'arrière-plan pour TableLayout, puis une couleur d'arrière-plan différente pour TableRow et à ajouter layout_margin à la ligne. Je n'aime pas cette solution, mais elle fonctionne pour les bordures de lignes. Je suppose que vous pourriez faire la même chose avec les éléments composant chaque élément "cellule" mais je n'ai pas vérifié.

Un exemple similaire à celui sur DroidNova:

<TableLayout Android:background="#000000"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content">
  <TableRow Android:background="#FFFFFF"
  Android:layout_width="fill_parent"
  Android:layout_height="wrap_content"
  Android:layout_margin="1dp">
     ...
  </TableRow>
</TableLayout>
53
Shawn

SI vous essayez simplement d'avoir une ligne entre les lignes (par exemple, juste au-dessus de une ligne "Total"), il existe alors une solution simple: il suffit d'ajouter un TableRow avec une couleur d'arrière-plan et un layout_height spécifique tel que celui-ci:

_<TableRow Android:layout_height="1px" Android:background="#BDBDBD">
   <TextView Android:layout_span="2" Android:layout_height="1px" 
             Android:layout_width="fill_parent" Android:text="">
   </TextView>
</TableRow>
_

Définissez _Android:layout_height="1px"_ ou quelle que soit l'épaisseur souhaitée de la bordure. Remplissez autant de colonnes TextView vides que nécessaire pour correspondre au reste de votre tableau, ou utilisez-en une seule avec Android:layout_span comme je l’ai déjà montré.

La sortie ressemblera à ceci:

Table Border demonstrated

Si vous essayez d’ajouter des bordures plus complexes, les autres réponses déjà postées sont plus appropriées.

39
Michael Bray

Ce que je voulais c'est une table comme ça

table image with vertical dividers

J'ai ajouté ceci dans mon styles.xml:

      <style name="Divider">
        <item name="Android:layout_width">1dip</item>
        <item name="Android:layout_height">match_parent</item>
        <item name="Android:background">@color/divider_color</item>
    </style>

    <style name="Divider_invisible">
        <item name="Android:layout_width">1dip</item>
        <item name="Android:layout_height">match_parent</item>
    </style>

Puis dans mon disposition de la table:

 <TableLayout
            Android:id="@+id/table"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:orientation="horizontal"
            Android:stretchColumns="*" >

            <TableRow
                Android:id="@+id/tableRow1"
                Android:layout_width="fill_parent"
                Android:layout_height="match_parent"
                Android:background="#92C94A" >

                <TextView
                    Android:id="@+id/textView11"
                    Android:paddingBottom="10dp"
                    Android:paddingLeft="5dp"
                    Android:paddingRight="5dp"
                    Android:paddingTop="10dp" />

                <LinearLayout
                    Android:layout_width="1dp"
                    Android:layout_height="match_parent" >

                    <View style="@style/Divider_invisible" />
                </LinearLayout>

                <TextView
                    Android:id="@+id/textView12"
                    Android:paddingBottom="10dp"
                    Android:paddingLeft="5dp"
                    Android:paddingRight="5dp"
                    Android:paddingTop="10dp"
                    Android:text="@string/main_wo_colon"
                    Android:textColor="@color/white"
                    Android:textSize="16sp" />

                <LinearLayout
                    Android:layout_width="1dp"
                    Android:layout_height="match_parent" >

                    <View style="@style/Divider" />
                </LinearLayout>

                <TextView
                    Android:id="@+id/textView13"
                    Android:paddingBottom="10dp"
                    Android:paddingLeft="5dp"
                    Android:paddingRight="5dp"
                    Android:paddingTop="10dp"
                    Android:text="@string/side_wo_colon"
                    Android:textColor="@color/white"
                    Android:textSize="16sp" />

                <LinearLayout
                    Android:layout_width="1dp"
                    Android:layout_height="match_parent" >

                    <View style="@style/Divider" />
                </LinearLayout>

                <TextView
                    Android:id="@+id/textView14"
                    Android:paddingBottom="10dp"
                    Android:paddingLeft="5dp"
                    Android:paddingRight="5dp"
                    Android:paddingTop="10dp"
                    Android:text="@string/total"
                    Android:textColor="@color/white"
                    Android:textSize="16sp" />
            </TableRow>

            <!-- display this button in 3rd column via layout_column(zero based) -->

            <TableRow
                Android:id="@+id/tableRow2"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:background="#6F9C33" >

                <TextView
                    Android:id="@+id/textView21"
                    Android:padding="5dp"
                    Android:text="@string/servings"
                    Android:textColor="@color/white"
                    Android:textSize="16sp" />

                <LinearLayout
                    Android:layout_width="1dp"
                    Android:layout_height="match_parent" >

                    <View style="@style/Divider" />
                </LinearLayout>

..........
.......
......
24
YasirAzgar

Vous pouvez également le faire par programme, plutôt que par le biais de XML, mais c'est un peu plus "hackish". Mais ne laissez aucune option à un homme et vous ne lui laisserez aucun choix: p .. Voici le code:

TableLayout table = new TableLayout(this);
TableRow tr = new TableRow(this);
tr.setBackgroundColor(Color.BLACK);
tr.setPadding(0, 0, 0, 2); //Border between rows

TableRow.LayoutParams llp = new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
llp.setMargins(0, 0, 2, 0);//2px right-margin

//New Cell
LinearLayout cell = new LinearLayout(this);
cell.setBackgroundColor(Color.WHITE);
cell.setLayoutParams(llp);//2px border on the right for the cell


TextView tv = new TextView(this);
tv.setText("Some Text");
tv.setPadding(0, 0, 4, 3);

cell.addView(tv);
tr.addView(cell);
//add as many cells you want to a row, using the same approach

table.addView(tr);
21
Mnightmare

enter image description here

Ici, j'ai conçu la liste à l'aide de l'image de conception suivante. Mon nom de fichier listitem est Propertylistitem.xml et cellborder.xml est utilisé comme forme dessinable pour la sortie cellborder, sont affichés dans cette image. code nécessaire j'ai ajouté ici.

FileName: propertylistitem.xml

<TableLayout... >
            <TableRow... >
                 <TextView ...
                    Android:background="@drawable/cellborder"
                    Android:text="Amount"/>
            </TableRow>

            <TableRow... >
                <TextView...
                    Android:background="@drawable/cellborder"
                    Android:text="5000"/>
            </TableRow>
        </TableLayout>

nom du fichier: cellborder.xml Ici, je ne veux que la bordure dans ma conception, alors je mets commenter la balise de couleur unie.

<?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="rectangle" >
    <!--     <solid Android:color="#dc6888"/>     -->
        <stroke Android:width="0.1dp" Android:color="#ffffff"
            />
        <padding Android:left="0dp" Android:top="0dp"
                Android:right="0dp" Android:bottom="0dp" />
    </shape>
13
MohanRaj S

Pour créer 1dp collapse-border autour de chaque cellule sans écrire un code Java et sans créer une autre présentation XML avec la balise <shape...>, vous pouvez essayer cette solution:

Dans <TableLayout...> ajouter Android:background="#CCC" et Android:paddingTop="1dp" et Android:stretchColumns="0"

Dans <TableRow...> ajouter Android:background="#CCC" et Android:paddingBottom="1dp" et Android:paddingRight="1dp"

Dans chaque cellule/enfant de TableRow, c.-à-d. <TextView...> ajoute Android:background="#FFF" et Android:layout_marginLeft="1dp"

Il est très important de suivre les marges et les rembourrages tels que décrits. Cette solution va dessiner une bordure de 1dp, nommée border-collapse, en (X) HTML/CSS.

La couleur d'arrière-plan dans <TableLayout...> et <TableRow...> représente une couleur de bordure et un arrière-plan dans <TextView...> remplit une cellule de tableau. Vous pouvez mettre un peu de remplissage dans les cellules si nécessaire.

Un exemple est ici:

<TableLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:background="#CCC"
    Android:paddingTop="1dp"
    Android:stretchColumns="0"
    Android:id="@+id/tlTable01">

    <TableRow
        Android:background="#CCC"
        Android:paddingBottom="1dp"
        Android:paddingRight="1dp">
        <TextView 
            Android:layout_marginLeft="1dp"
            Android:padding="5dp"
            Android:background="#FFF"
            Android:text="Item1"/>
        <TextView 
            Android:layout_marginLeft="1dp"
            Android:padding="5dp"
            Android:background="#FFF"
            Android:gravity="right"
            Android:text="123456"/>
    </TableRow>
    <TableRow
        Android:background="#CCC"
        Android:paddingBottom="1dp"
        Android:paddingRight="1dp">
        <TextView 
            Android:layout_marginLeft="1dp"
            Android:padding="5dp"
            Android:background="#FFF"
            Android:text="Item2"/>
        <TextView 
            Android:layout_marginLeft="1dp"
            Android:padding="5dp"
            Android:background="#FFF"
            Android:gravity="right"
            Android:text="456789"/>
    </TableRow>
</TableLayout>
11
davidmrnustik

Après de longues recherches et des heures d’essai, c’est le code le plus simple que je puisse créer:

ShapeDrawable border = new ShapeDrawable(new RectShape());
border.getPaint().setStyle(Style.STROKE);
border.getPaint().setColor(Color.BLACK);
tv.setBackground(border);
content.addView(tv);

tv est un TextView avec un texte simple et le contenu est mon conteneur (LinearLayout dans ce cas). C'est un peu plus facile.

8
Marios

Cela peut vous inspirer. Ces étapes montrent comment créer une table encadrée de manière dynamique

voici la vue de la table

<Android.support.v4.widget.NestedScrollView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/nested_scroll_view"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:scrollbars="none"
    Android:scrollingCache="true">
    <TableLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:id="@+id/simpleTableLayout"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_marginLeft="45dp"
        Android:layout_marginRight="45dp"
        Android:stretchColumns="*"
        >
    </TableLayout>
</Android.support.v4.widget.NestedScrollView>

et ici la ligne à utiliser "attrib_row.xml"

<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:background="@drawable/border"
    >
    <TextView
        Android:id="@+id/attrib_name"
        Android:textStyle="bold"
        Android:height="30dp"
        Android:background="@drawable/border"
        Android:gravity="center"
        />
    <TextView
        Android:id="@+id/attrib_value"
        Android:gravity="center"
        Android:height="30dp"
        Android:textStyle="bold"
        Android:background="@drawable/border"
        />
</TableRow>

et nous pouvons ajouter ce fichier XML à drawable pour ajouter une bordure à notre tableau "border.xml"

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:shape= "rectangle">
    <solid Android:color="@color/colorAccent"/>
    <stroke Android:width="1dp" Android:color="#000000"/>
</shape>

et enfin voici le code compact écrit en Kotlin mais il est facile de le convertir en Java si vous en avez besoin.

well temps est une liste contenant des données: ArrayList<Double>()

fun CreateTable()
{
    val temps=controller?.getTemps()
    val rowHead = LayoutInflater.from(context).inflate(R.layout.attrib_row, null) as TableRow
    (rowHead.findViewById<View>(R.id.attrib_name) as TextView).text=("time")
    (rowHead.findViewById<View>(R.id.attrib_value) as TextView).text=("Value")
    table!!.addView(rowHead)
    for (i in 0 until temps!!.size) {

        val row = LayoutInflater.from(context).inflate(R.layout.attrib_row, null) as TableRow
        (row.findViewById<View>(R.id.attrib_name) as TextView).text=((i+1).toString())
        (row.findViewById<View>(R.id.attrib_value) as TextView).text=(temps[i].toString())
        table!!.addView(row)
    }
    table!!.requestLayout()
}

et vous pouvez l'utiliser dans votre fragment par exemple comme ceci

   override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        table = view?.findViewById<View>(R.id.simpleTableLayout) as TableLayout
        CreateTable()
    }

le résultat final ressemble à ceci enter image description here

6
DINA TAKLIT

Pourquoi ne pas surcharger la méthode onDraw et ensuite peindre des lignes sur le canevas?

for(int i = 0; i < rows; i++)
    {
        canvas.drawLine(0, i * m_cellHeight, m_totalWidth, i * m_cellHeight, Paint);
    }
    for(int i = 0; i < m_columns; i++){
        canvas.drawLine(i* m_cellWidth, 0, i * m_cellWidth, m_cellHeight * rows, Paint);
    }
5
Andrew

Voici un excellent moyen de résoudre ce problème:

Créez un rectangle pouvant être dessiné avec des angles arrondis comme ceci:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="rectangle"> 
    <stroke Android:width="2dp"
            Android:color="#888888"/> 

    <corners Android:bottomRightRadius="6dp" 
             Android:bottomLeftRadius="6dp" 
             Android:topLeftRadius="6dp" 
             Android:topRightRadius="6dp"/> 
</shape>

enregistrez-le dans le dossier pouvant être tracé avec le nom rounded_border.xml

Créez ensuite une mise en page relative qui utilise rounded_border comme arrière-plan, comme suit:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" 
    Android:background="@drawable/rounded_border">
   <ListView 
       Android:id="@+id/list_view"
       Android:layout_width="match_parent"
       Android:layout_height="wrap_content"/>

</RelativeLayout>

enregistrez cela dans votre dossier de présentation et nommez-le table_with_border.xml

puis, chaque fois que vous avez besoin d'un tel tableau, tirez-le dans une vue en utilisant la syntaxe include suivante:

<include
        Android:id="@+id/rounded_table"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        layout="@layout/table_with_border" />

Vous voudrez probablement ajouter un espacement autour des bords - enveloppez donc l'inclusion dans un LinearLayout et ajoutez un peu de rembourrage autour des bords.

Un moyen simple et facile d’obtenir une jolie bordure autour d’une table.

3
Aaron

J'ai utilisé cette solution: dans TableRow, j'ai créé pour chaque cellule LinearLayout une ligne verticale et la cellule réelle qu'il contient, et après chaque TableRow, j'ai ajouté une ligne horizontale.

Regardez le code ci-dessous:

<TableLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:shrinkColumns="1">

    <TableRow            
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content" >

            <LinearLayout 
                Android:orientation="horizontal"
                Android:layout_height="match_parent"
                Android:layout_weight="1">

                <TextView 
                    Android:layout_width="0dp"
                    Android:layout_height="wrap_content"
                    Android:gravity="center"/>

            </LinearLayout>

            <LinearLayout 
                Android:orientation="horizontal"
                Android:layout_height="match_parent"
                Android:layout_weight="1">

                <View
                    Android:layout_height="match_parent"
                    Android:layout_width="1dp"
                    Android:background="#BDCAD2"/>

                <TextView 
                    Android:layout_width="0dp"
                    Android:layout_height="wrap_content"
                    Android:gravity="center"/>

            </LinearLayout>
      </TableRow>

      <View
        Android:layout_height="1dip"
        Android:background="#BDCAD2" />

      <!-- More TableRows -->
</TableLayout>

J'espère que ça va aider.

3
Matus

Une frontière entre cellules est doublée dans les réponses ci-dessus. Donc, vous pouvez essayer cette solution:

<item
    Android:left="-1dp"
    Android:top="-1dp">

    <shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
           Android:shape="rectangle">
        <solid Android:color="#fff"/>
        <stroke
            Android:width="1dp"
            Android:color="#ccc"/>
    </shape>
</item>
2
CoolMind

Je sais que c’est une vieille question ... en tout cas ... si vous voulez conserver votre code xml Simple et agréable, vous pouvez étendre TableLayout et remplacer dispatchDraw pour réaliser des dessins personnalisés.

Voici une implémentation rapide et incorrecte qui trace un rectangle autour de la vue du tableau, ainsi que des barres horizontales et verticales:

public class TableLayoutEx extends TableLayout {
    private Paint linePaint = null;
    private Rect tableLayoutRect;

    public TableLayoutEx(Context context) {
        super(context);
    }

    public TableLayoutEx(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        float strokeWidth = this.getContext().getResources().getDisplayMetrics().scaledDensity * 1;
        linePaint = new Paint(0);
        linePaint.setColor(0xff555555);
        linePaint.setStrokeWidth(strokeWidth);
        linePaint.setStyle(Paint.Style.STROKE);

        Rect rect = new Rect();           
        int paddingTop= getPaddingTop();

        this.getDrawingRect(rect);
        tableLayoutRect = new Rect(rect.left, rect.top + paddingTop, rect.right, rect.bottom);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);

        Rect rect = new Rect();

        if (linePaint != null) {
            canvas.drawRect(tableLayoutRect, linePaint);
            float y = tableLayoutRect.top;
            for (int i = 0; i < getChildCount() - 1; i++) {
                if (getChildAt(i) instanceof TableRow) {
                    TableRow tableRow = (TableRow) getChildAt(i);
                    tableRow.getDrawingRect(rect);
                    y += rect.height();
                    canvas.drawLine(tableLayoutRect.left, y, tableLayoutRect.right, y, linePaint);
                    float x = tableLayoutRect.left;
                    for (int j = 0; j < tableRow.getChildCount() - 1; j++) {
                        View view = tableRow.getChildAt(j);
                        if (view != null) {
                            view.getDrawingRect(rect);
                            x += rect.width();
                            canvas.drawLine(x, tableLayoutRect.top, x, tableLayoutRect.bottom, linePaint);
                        }
                    }
                }
            }
        }
    }
}

exemple xml avec le texte d'habillage de la troisième colonne:

<com.YOURPACKAGE.TableLayoutEx
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:shrinkColumns="2"
    Android:paddingTop="6dp">

    <TableRow>
        <TextView
            Android:text="@string/my_text_0_0"
            Android:padding="@dimen/my_padding"/>
        <TextView
            Android:text="@string/my_text_0_1"
            Android:padding="@dimen/my_padding"/>
        <TextView                   
            Android:text="@string/my_text_0_2_to_wrap"
            Android:padding="@dimen/my_padding"/>
    </TableRow>

    <!--more table rows here-->

</com.YOURPACKAGE.TableLayoutEx>
2
A.J.Bauer

Je pense qu'il est préférable de créer une image de 9 pixels de 1px et d'utiliser l'attribut showDividers dans TableRow et TableLayout car ils sont tous deux LinearLayouts.

2
Bartek

Le trait se dédouble sur les sections intermédiaires, j'ai utilisé cette liste de calques dessinable:

<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >

 <item Android:top="0dp" Android:left="0dp" Android:bottom="0dp" Android:right="0dp">

     <shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="rectangle">
       <solid Android:color="@color/grey" />
    </shape>
</item>

<item Android:top="1dp" Android:left="1dp" Android:bottom="1dp" Android:right="1dp">

    <shape xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:shape="rectangle">
      <solid Android:color="@color/lightgrey" />
    </shape>
 </item>
</layer-list>
2
user3853262

Une autre solution consiste à utiliser des dispositions linéaires et à définir des séparateurs entre les lignes et les cellules comme suit:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical" Android:layout_width="match_parent"
Android:layout_height="match_parent">

<View
    Android:layout_width="match_parent"
    Android:layout_height="1px"
    Android:background="#8000"/>

<LinearLayout
    Android:orientation="horizontal"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:layout_weight="1">

    <View
        Android:layout_width="@dimen/border"
        Android:layout_height="match_parent"
        Android:background="#8000"
        Android:layout_marginTop="1px"
        Android:layout_marginBottom="1px"/>

    <LinearLayout
        Android:orientation="horizontal"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_weight="1"
        ></LinearLayout>

    <View
        Android:layout_width="@dimen/border"
        Android:layout_height="match_parent"
        Android:background="#8000"
        Android:layout_marginTop="1px"
        Android:layout_marginBottom="1px"/>

    <LinearLayout
        Android:orientation="horizontal"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_weight="1"></LinearLayout>

    <View
        Android:layout_width="@dimen/border"
        Android:layout_height="match_parent"
        Android:background="#8000"
        Android:layout_marginTop="1px"
        Android:layout_marginBottom="1px"/>

</LinearLayout>

<View
    Android:layout_width="match_parent"
    Android:layout_height="1px"
    Android:background="#8000"/>

<LinearLayout
    Android:orientation="horizontal"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:layout_weight="1">

    <View
        Android:layout_width="@dimen/border"
        Android:layout_height="match_parent"
        Android:background="#8000"
        Android:layout_marginTop="1px"
        Android:layout_marginBottom="1px"/>

    <LinearLayout
        Android:orientation="horizontal"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_weight="1"
        ></LinearLayout>

    <View
        Android:layout_width="@dimen/border"
        Android:layout_height="match_parent"
        Android:background="#8000"
        Android:layout_marginTop="1px"
        Android:layout_marginBottom="1px"/>

    <LinearLayout
        Android:orientation="horizontal"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_weight="1"></LinearLayout>
    <View
        Android:layout_width="@dimen/border"
        Android:layout_height="match_parent"
        Android:background="#8000"
        Android:layout_marginTop="1px"
        Android:layout_marginBottom="1px"/>
</LinearLayout>

<View
    Android:layout_width="match_parent"
    Android:layout_height="1px"
    Android:background="#8000"/>
</LinearLayout>

C'est une solution sale, mais simple et qui fonctionne également avec un fond et des bordures transparents.

1
Gregor Ažbe