How to get started with Android development – Layout Managers

At the end of my last article, I left you hanging after describing activities, without telling you how to build a UI, so here we go. In the Android SDK, layouts are separate from the Java code that defines how an activity behaves. Using this separation of concern, it’s easier to modify the layout without having to worry about the code.

Android layouts are in XML, and are located in the res\layout folder. You can have multiple versions of a layout for various orientations, screen size or culture and the Android SDK will choose the right one according to the device. We won’t worry about this right now; for simple layouts one version is enough.

In this article, I’m going to show you how to use a layout manager to position a widget, called a View in the Android SDK, using XML and Java. Next time, I’ll complete this explanation with more details about views themselves, and how they can be controlled in the layout or programmatically.

There is also a designer tool in Android Studio to help build your layouts. I’ll stick to the code for now since I believe it’s best to understand how things are built manually first, and then you’ll know enough to be able to explore it on your own.

Your First Layout

Here is a simple layout with two TextView views, each showing a text string, inside a LinearLayout layout manager in the res\layout\activity_main.xml file:

<?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="horizontal">

    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:text="My first textview"/>
    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:text="My second textview"/>
</LinearLayout>

Each layout has a least one view as a root, but it’s usually a layout manager such as the LinearLayout, RelativeLayout or ConstraintLayout since those views are built to position other views. I used the linear layout in this example since it’s simple to understand: if the property android:orientation is set to vertical, all the views will be aligned one over the other, and if set to horizontal they will be side by side.

To use your layout with your activity, you must set the layout in the onCreate() event of the activity using the setContentView() method :

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
} 

Views and Layout Managers Properties

All views, including layout managers, have proprieties that can be added to their XML declaration to control their size and padding. For example, you can specify an android:layout_height and android:layout_width in dp (density-independent pixels) like the layout above, or use the wrap_content and match_parent values:

  • wrap_content: The size (width or height) of the view will be the size required to display its content. For example, if you have a very long view showing text, you’ll use wrap_content as the height so it doesn’t get truncated at the bottom.
  • match_parent: The size (width or height) of the view will be the same as the size of its parent layout element. This used to be called fill_parent in API level 7 and less, so you’ll still see that name from time to time.
<?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">
    <TextView android:layout_width="match_parent" 
              android:layout_height="wrap_content" 
              android:text="My first textview"/>
    <TextView android:layout_width="match_parent" 
              android:layout_height="wrap_content" 
              android:text="My second textview"/>
</LinearLayout>

Each layout manager also has properties to control the positioning of the views they contain, such as the android:orientation for the LinearLayout described previously.

Layout managers can be nested to create complex layouts: for example, you can add a vertical linear layout inside a horizontal linear layout or a grid layout. Still, to make rendering more efficient, you should be careful to avoid nesting too many layouts.

So next time, we’ll take a look at how to use complex views that requires an interaction from the user, and how control those views from your Java code.

See the other articles in the series here

Are You Hard to Convince?

When discussing a new technology, I’m rarely the first one to jump on the bandwagon. In fact, I’m usually the killjoy that ends up arguing against using a new library or a new language feature when the enthusiasm is high and everybody is eager to get started.

It’s not that I want to stay comfortable and never move forward. Rather, I need to be convinced that something is worth it instead of moving for the sake of it. New features and libraries can add complexity to something that’s already complex. That makes it harder for new people to join in (including you if you didn’t touch it for the last 6 months).

I’m all for new ideas that makes software easier to understand and that allows me to do my job better. Still, the argument about new technology is too focused on the shiny new technology itself, and not the problem it solves. A great idea is not enough; it has to work well in the real world.

To illustrate this, I choose a few templating engines at random on npm (not judging their quality; maybe they’re all great). Here is the kind of descriptions that will greet you:

Why should I choose one over the other, or use it to replace an existing tool?  A description like fast and powerful is not very helpful. It’s good to have, but who would pick a underpowered, slow engine?

Of course, if I’m looking specifically for an HTML template engines I can narrow it down a bit, but if I don’t have a strong preference one way or the other, what should I choose? There were surely a few problems or use cases that led to writing those engines instead of using an existing one, but I don’t have any way of knowing from looking at this.

At this point, I’m asking myself if the library will still exist in 5 years (without forcing me to rewrite everything every year) and if it’s well documented so I can get up to speed quickly, not if it implements a cool pattern in particular.

If I had to choose something for a project from that list, I would probably pick the ones that have the most promising documentation and a large following, and try them out for myself. Granted, it could still blow up later in production or when trying to implement a feature in particular since I’m only coding a prototype, but it’s better than nothing.

But after doing all this work, why would I switch to something new a few years down the line if the one I choose first still works well? I have to be really convinced that it can solve my problem better, and that is worth the cost of switching in improved productivity and ease of use. With the speed that the technology is moving I must be sure it’s worth it. I can’t afford to waste my time migrating to something that will make things worse.

Connecting the ESP8266 chip to your network

I’m working on a project to automate our chicken coop (see my article Getting over myself and doing things the easy way for more details on the project). Right now, the lights open and close by themselves: it needed to be done now since the chickens had trouble laying eggs with our short Fall days. The current system uses an Arduino Uno, a real-time clock module with the DS1307 chip and an analog dimmer. You can see the code for this version on GitHub :
https://github.com/CindyPotvin/Chickmatic/tree/master/Phase1-ScheduleTime

I’m working on the second phase: being able to change the schedule directly from our phones and gather weather data from inside and outside the coop. My plan is to use the Arduino I already have to gather data and control the dimmer, and add a ESP8266 chip to connect this system to our home network.

Another server inside the house, probably a Raspberry Pi, will be used to host a small web application in NodeJS that will save the schedule and weather data. This is also in progress on GitHub at :
https://github.com/CindyPotvin/Chickmatic/tree/master/WebServer

To get started, I had to figure out how to connect to the network using the ESP8266. I purchased a cheap, poorly-documented board (the ESP13 by doit.am) that mounts the chip as an Arduino shield so they can be stacked:

esp8266

Here are where the problems started. Because of the form factor, I thought I could make HTTP requests from the Arduino, and the ESP8266 would be a dumb chip that transmitted the request.

That’s far from the truth: the ESP8266 is also a microcontroller and it has to also be programmed. It comes preloaded with some strange chinese firmware that I could use to see if the board works, but not much else. Fortunately, it can also be programmed using the Arduino IDE and there are some nice examples, so I could start from there.

Unfortunately, it’s not that easy to program the chip directly since it doesn’t have its own USB port. There are all kinds of suggestions online on how to bypass the Arduino and use its USB port to program the chip, but it never worked and I would always get the following errors:

warning: espcomm_sync failed
error: espcomm_open failed

TL;DR The only way I found to program the ESP8266 easily was to use a 3.3V FTDI cable I bought on eBay for a few dollars, pull the digital pin 0 to ground (as stated in the documentation for the ESP8266), reboot and then I was good to go. Don’t waste time like it did.

Good to go for a few minutes, that is. After connecting just fine to the network for the first time and congratulating myself on my success, I never could connect a second time using the same code. After much experimentation, I found that the best way to make sure it always worked was to disconnect from the network and then reconnect while the chip is booting. Here is what my setup looks like for the ESP8266:

void setup() {
  Serial.begin(115200);

  // WiFi.disconnect();  // Made things work because memory was corrupted but is not needed, see EDIT below
  WiFi.persistent(false);

  Serial.print("Connecting");
  WiFi.begin(/*username*/,/*password*/); // Username/password not required after the first time, saved to flash
  while (WiFi.status() != WL_CONNECTED) {
    delay(5500);
    Serial.print("status");
    Serial.println(WiFi.status());
    }
  Serial.println(" connected");
  Serial.println(WiFi.localIP());
}

So, I’m finally ready to get started coding now that I’ve proved that I can connect to my network. To be more precise, I want to use the I2C bus to connect the Arduino and the ESP8266 together using the Wire library. The ESP8266 will send all the HTTP requests and parse the responses. This will leave the standard serial ports free so I can debug and program both chips without unplugging everything each time.

Seems logical to me, but the shield doesn’t wire the I2C bus for the Arduino and the ESP8266 together, only the serial port. I can’t just wire them myself since the ESP8266 works with 3.3V logic levels while the Arduino works with 5V. I need to have a logic level shifter, like what they did on the shield with the serial ports (the blue dip switches are used to toggle between programming the chip and linking the chips together). It can work for a little while if I cheat and connect them anyway, but it will eventually fry the ESP8266.

Since I really want to keep the serial ports for debugging and because the shield doesn’t really add much to the project after all, I ordered a new ESP8266 off eBay that’s only the chip mounted on a board with the I2C port exposed, along with an order for a few level shifters. It took a while to find a good board: many of the cheap models only expose the serial ports while I wanted a bit more. I’m still wanting for the new chips to show up in the mail, so stay tuned!


EDIT: following Ken’s comment, I tried to clear the ESP8266 memory using his sketch at https://github.com/kentaylor/EraseEsp8266Flash, and indeed it now works property.

It makes a lot of sense: I tried the disconnect() because I read somewhere that the connection was persistent, so I figured it couldn’t hurt to try disconnecting, but I did not realize I could clear the flash instead. I can’t tell when the memory got corrupted: I tried many examples I found lying around on the Internet before reaching this point.

He also made me realize I won’t need the Arduino anymore. I was stuck with the idea that it would be a hassle to plug the dimmer (controlled by a digital signal) and the real-time clock to the ESP8266, but it shouldn’t be too hard. I’ll need to use the I2C for the clock, but the library handles everything.

Don’t hesitate to tell me if I do something else that’s wrong: I’m an amateur at best when it comes to electronics. I occasionally write about my experiments, but the results are far from production-ready.