How to display borders in Table Layouts

According to the Android developer guide, border lines are not displayed for table layouts. However, often you will find the need to do things such as having vertical separators between table cells and borders around table rows. There are two different methods that I can think of to achieve this.

Method 1: Use of background colour and layout margins

  1. Give the TableLayout a background colour. (purple – #ff00f0 – in my example)
  2. Give the TableRow a different background colour (black in my example) and a layout_margin (2dp). The layout_margin is the width of the “border”.

This will essentially give a border around each row in the TableLayout, as shown in Figure 1 (first table). The code snippet for the XML-layout file looks like this:

XHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<TableLayout android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:stretchColumns="*"
    android:background="#ff00f0">
    <TableRow android:layout_margin="2dp" android:background="#000000">
        <TextView android:text="first column" />
        <TextView android:text="second column" />
        <Button android:text="third Column" />
    </TableRow>
    <TableRow android:layout_margin="2dp" android:background="#000000">
        <TextView android:text="first column" />
        <TextView android:text="second column" />
        <Button android:text="third Column" />
    </TableRow>
</TableLayout>

Figure 1 - Table borders using background/layout_margin

NOTE: In a proper application, you are more likely to use this in conjunction with a ListView. i.e. represent each list item as a table row.

However, if you want to have vertical borders between cells it gets trickier. This is because some views such as EditView and Buttons have their own “padding”/transparency that makes it tedious to specify everything in a XML file. You can see how this looks in Figure 1 (2nd table) Steps to achieve this is as follows:

  1. Give the TableLayout a background colour (red)
  2. Give a layout_margin to TableRow so that it will display the outer border (similar to previous example) for each row.
  3. Give each view within a TableRow its own background colour. Otherwise it will be inherited from the parent view (which is red). This is where the things can get tricky depending on your views. Have a play around and see what works for you the best.

Layout code example:

XHTML
1
2
3
4
5
6
7
8
9
10
11
<TableLayout android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:stretchColumns="*"
    android:background="#ff0000">
    <TableRow android:layout_margin="1dp">
        <TextView android:text="first column" android:background="#000000"
            android:layout_margin="1dp" />
        <TextView android:text="second column" android:background="#000000"
            android:layout_margin="1dp" />
    </TableRow>
    ...
</TableLayout>

Method 2: Create a custom view using code + XML

The second method involves writing a custom View and controlling exactly what/how things get drawn on screen. Personally, I think this is much better approach due to its flexibility and reusability, when compared to the first approach. For this guide, I created a custom TextView (called CustomItemView) to display vertical borders.

XML to create the CustomItemView is shown below. You can use it within a list or a table as shown in Figure 2.

XHTML
1
2
3
4
<com.thira.examples.customAdapters.CustomItemView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:padding="10dp" android:textColor="#AA0000FF" />

As I mentioned before, CustomItemView is a java class that extends TextView and overrides the onDraw method. The code fragment below shows how to draw the vertical and horizontal lines within the onDraw method. Since it extends a TextView, you can directly specify the visible text if you want to using the android:text property in the XML layout file.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  /**
  * Text | Text
  */
    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawColor(mItemBackgroundColour);    // set the background colour for the item
        // draw the horizontal line at the bottom of the item
        canvas.drawLine(0, getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight(), mLinePaint);
        // draw some text to the left of the margin
        canvas.drawText(" *)", 5, getMeasuredHeight() - 4, mMarginPaint);
        // Draw the vertical margins
        canvas.drawLine(2, 0, 2, getMeasuredHeight(), mMarginPaint);
        canvas.drawLine(mBorderMarginOffset, 0, mBorderMarginOffset, getMeasuredHeight(), mMarginPaint);
        // Move the text across from the margin and up 10 from the line
        canvas.save();
        canvas.translate(mBorderMarginOffset, 10);
        // Use the TextView to render the text.
        super.onDraw(canvas);
        canvas.restore();
    }

Figure 2 - Using custom views to display vertical lines

Hope this was helpful and don’t hesitate to ask any questions that you might have!

18 Responses to How to display borders in Table Layouts

  1. Helpful. Thanks.

  2. Thank you

  3. really Helpful, Thanks. Is these the only way we can ‘draw’ tables in Android? It seems that there is the same issue with Java Me as there isnt a standard class associate with tables and r0ws. Do you think this solutions can be incorporated with data storage and actually save table content persistently.
    Thanks

    • You are welcome and I am glad you found my article helpful!

      The two methods I described are probably good “starting points” to “draw” tables in Android. I personally prefer the 2nd method of having a customised view due to its extensibility and re-usability.

      Off the top of my head, I can think of two ways you can go about doing what you want:

      1. 1. Have a TableLayout that you dynamically populate (by code)
      2. 2. Use a ListView

      I personally prefer to go with a ListView, since you can leverage support for directly linking to data sources (using various Adapters provided by Android API) and optimizations for reusing Views (very useful to improve performance when dealing with displaying large number of items). You can use the customised view approach in conjunction with a ListView to accomplish what you want. Essentially,

      1. 1. Use the custom view (described in Approach #2) to represent a row within your ListView. This will allow you to “draw” tables where each list item corresponds to a table row
      2. 2. Write a custom ListAdapter (probably extend the BaseAdapter class in Android API) to map your data from the storage correctly to the custom view (so the columns will be displayed properly)

      Let me know if you are unclear about any of it, and I’ll write up some tutorials to describe some of the basic concepts.

      Cheers!

      • Thank you, this was very helpful!!!!!
        I am a bit new in android programming and will be happy to get your opinion for the best approach in the following app.
        I want to dynamically add items such as in this app:
        http://www.appbrain.com/app/stocks/org.dayup.stocks
        where each item include 2 lines of data on both sides and clicking it will give me new form.
        What do you think the best approach here? I am currently doing it with LayoutTable and having some difficultiesto put line separators.

  4. hey thanks for the info, this is just what i am looking to do!

    i am a little confused about the CustomItemView though, where does the code for that go? do i need to create a new XML file called CustomItemView? or just put this in my layout.xml file?
    thanks,
    ~clayton

  5. Hey my vertical border line coming is to thick.Can you help me to get it in proper size.

    Thanks,
    Aditya

  6. May be it’s good .but i don’t know how to uses it . I’m very new to android.
    please some one explain it.

  7. Hi,
    there is another way for single border in any side of element using the custom view tag like this

    • Hi Sam,
      looks like part of your reply was cut off (probably wordpress filtered it out). I am guessing you were suggesting something like this: (using a view instead of a custom widget?)

      [sourcecode language="xml"]
      <View
      android:layout_width="1dip"
      android:layout_height="fill_parent"
      android:background="#FF0000FF"
      />
      [/sourcecode]

      P.S. code tag does not seem to work on comments when you have XML. I use the sourcecode tag instead.

  8. very nice! that is a good idea. thx, it’s very helpfull

  9. How to do this same borders with programatically ? Please help me out !

    • There are quite a few ways of doing that . one way is to have a custom view (see CustomItemView in the above post) and draw your borders using the Canvas object as I’ve illustrated.

  10. Hi Thiru
    You ListView approach is quite impressive. I have few questions.

    1. Have you extended View or TextView?
    2. Let us say your XML file is list_view.xml. Have you used something like this – lv.setAdapter(new ArrayAdapter(this, R.layout.list_item, COUNTRIES)); where COUNTRIES is an array of countries from ListView example in Android Tutorials.

    • You can extend either View or any subclass of View (e.g. TextView) depending on how complex you want your ‘table row/cell’ to be displayed and behave.

      I’d say select the superclass based on what you want to draw on your table row. For example, TextView is good enough if its just text. ButtonView is more suitable if your table only going to contain buttons. A ViewGroup – e.g. RelativeLayout, LinearLayout etc. – is more appropriate if you want a more complex table row with nested Views.

      You will find that oftentimes, you can work with a subclass of View rather than directly extending View in order to reduce the amount of code you have to write (In my example I used View because its a dead-simple use case and didn’t want to confuse the reader in anyway).

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>