Software Development

Pro tip: Add a dashed line in an Android layout

Save yourself hours of consternation by using this workaround to add a dashed line to your Android layout.

 

android-logo-generic-092413.jpg
 

Sometimes being a software engineer can be very frustrating. It has been one of those days, despite the fact that things started out in the right direction.

I got a request from a creative director on my current project to add a dashed line to a layout. According the official Google documentation, this is out of the box functionality. After a brief scan of the SDK guide, I was ready to rock and roll.

I'd define a simple XML drawable, like so:

 

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
	android:shape="line">
    <stroke
       android:color="#FF0000FF"
       android:dashWidth="4dp"
       android:dashGap="8dp" />
</shape>
 

Then apply it to a view in a simple layout:

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <View 
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="8dp"
        android:layout_margin="20dp"
        android:background="@drawable/dotted_line"/>
    
</RelativeLayout>
 

In minutes, I'd spun up an Android Virtual Device and validated my assumptions (Figure A).

Figure A

 

android_framed_dotted_line_011514.png
 

However, after applying the same technique to my production code, I discovered something troublesome: The line showed up completely solid on an actual device (Figure B).

Figure B

 

android_framed_solid_line_011514.png
   

I racked my brain and the brains of my colleagues and eventually ended up asking the all-knowing Google. After over an hour of reading Android-related blogs and forums posts, I came across this little gem on the official Android issue tracker: Issue 29944: DashPathEffect/drawLine not working properly when hardwareAccelerated="true". I wasn't explicitly setting hardware acceleration to true in my manifest, but a quick glance back to the Google documentation confirms that as of API 14 hardware acceleration is true by default on all views.

Like I said, it was one of those days. Fortunately, the workaround is rather simple: You add the following line to the affected view in your layout:

android:layerType="software"
 

The result was exactly what I wanted (Figure C).

Figure C

 

android_framed_dotted_line2_011514.png
  

I remember my grandfather coming home from work some days looking like he'd been through the mill.  I'd ask him how his day went, and his response would be: "Some days you get the bear, and other days the bear gets you." I'd like to think today I got the bear -- even if the bear did get in a few good licks.

 

 

About

William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intellige...

0 comments