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
- Give the TableLayout a background colour. (purple – #ff00f0 – in my example)
- 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:
<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>
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:
- Give the TableLayout a background colour (red)
- Give a layout_margin to TableRow so that it will display the outer border (similar to previous example) for each row.
- 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:
<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.
<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.
/** * 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(); }
Hope this was helpful and don’t hesitate to ask any questions that you might have!
Helpful. Thanks.
Thank you
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:
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,ListView
. This will allow you to “draw” tables where each list item corresponds to a table rowLet 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.
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
you are welcome!
In the above example, CustomItemView is a java class that extends the View class and is in the package
com.thira.examples.customAdapters
. You can use either pure Java code (as in the example above) or a mix of code+xml to define the layout. I am hoping to write a small tutorial on creating custom views, but meanwhile you might find http://developer.android.com/guide/topics/ui/custom-components.html quite useful. Hope that helps!cheers,
Thiranjith.
Hey my vertical border line coming is to thick.Can you help me to get it in proper size.
Thanks,
Aditya
Hi Aditya,
The last parameter you pass into Canvas#drawLine method determines the style of your vertical/horizontal line (see line #12 in the code segment above). You can set the width of the Paint object to something smaller if you want thinner vertical lines (I recommend using different Paint objects for different styles).
see http://developer.android.com/reference/android/graphics/Paint.html for more details. Hope that helps!
Cheers,
Thira..
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.
Hi,
You need some familiarity with developing Android applications before trying to do some of these tasks. A good starting point would be http://developer.android.com/guide/developing/index.html … let me know if you have any questions regarding to specific aspects of Android development.
Cheers,
Thira.
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?)
P.S. code tag does not seem to work on comments when you have XML. I use the
sourcecode
tag instead.very nice! that is a good idea. thx, it’s very helpfull
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.
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).