Marcos Placona Blog

Programming, technology and the taming of the web.

Category: Android

Android is an operating system for mobile devices such as cellular phones, tablet computers and netbooks. Android was developed by Google and based upon the Linux kernel and GNU software

Building a beautifully smart form in Android using RxJava

Reading time: 5 – 8 minutes

I don’t think I know a single Android developer who’s not stoked about Reactive Programming with RxAndroid right now. I totally dig the idea of subscribing to events emitted by my applications and be able to react accordingly.

With Rx you have Observables and Observers. Observables are expected to emit values. While Observers watch Observables by subscribing to them.

Observing a button for example would look like this:

But let’s look at a more real-life example.

Requirements

I would like to have a reactive login form that updates itself according to the values entered. Such that:

androidrx

  • It only shows a login button once the username and password have been validated
  • It lets me know that values I entered for each field are correct so I can start working on the next field.

Our tools

The form

You can download the entire project from my GitHub repo, or follow this tutorial.

Start by creating a new project with an Empty Activity, and once that’s completed open activity_main.xml.

I used the Design Support Library to create my form.

Once that form is created, we will add some references to it at the top of our MainActivity class.

We’re using ButterKnife here to bind the widgets to our layout. Inside the onCreate method we need to make sure to initialise ButterKnife.

rxandroid1-1Give that a spin and you should see our form, and really nothing else.

But now we know our form is working and all the fields are displaying and bound correctly. You will notice that if you try to do anything with this form though, no validation kicks in.

Also, the login button is displaying, and one of our initial requirements was that the login button only displays once we have validated that the data entered in the form is in the format we expect.

We will add this functionality now by adding three new Observables to our class and subscribing to them to check for when values change and become valid.

Validation

I want to validate that the username is in fact an email address. The easiest way we can do this is by using a regular expression. The EmailRegex website has a good one we can use here. So we will just copy that and create a new method called isValidLogin that returns a boolean to indicate whether the email is valid or not.

You could change that to fit anything you need. In my first go at this I was only checking whether the value had 5 characters or more.

Next we will create similar method to check whether the password is valid according to our requirements. I kept this simple and only checked that the password is anything between 4 and 8 characters and that it has at least one number.

Again, feel free to modify this to do whatever you want it to do. There are regular expression recipes all over the internet so just search for something that works for you.

Putting it all together

We need to start using these validation methods with our code, so go ahead and create three new Observables in the onCreate method.

The first and the second one are really simple and use the RxBinding library to check for text changes on the form field. The third one is the most interesting in my option, as it combines the latest vales emitted by each one of the previous Observables and then checks to see whether their values are considered to be valid according to our validation rules.

But we’re just emitting values here, and don’t really have anything watching for these value changes and reacting to it.

We will change our code to add subscribers (Observers) to each one of our Observables.

The first and second Observers are similar and will change the drawable in the field to a green dot when the values entered are valid.

The third Observer  will change the button to visible once the values are correct, and hide it if the values become incorrect again.

React to all the things

Reactive programming is a lot of fun, and once you get started with it you will want to find an excuse to subscribe to every one of your data streams. Bet you think our little form works way better now than before.

Donn Felker wrote a really good Rx tutorial here that goes through a lot of the basics when getting started with RxAndroid. The Operators page in the Reactive.io website is also a great resource to help you understanding what all the operators do.

Have fun!

Picasso – Same URL but different content

Reading time: 3 – 5 minutes

I love using Square’s Picasso library whenever I need to load images into my Android applications. It lets me load images from the internet into ImageViews with a single line of code.

Doing the same thing without the library is a whole different story, and Picasso even takes care of caching and transformations for me.

Until I hit a snag

Today I was working on a demo with a RecyclerView that loads random images from the internet to display as icons for each one of the items. The naive implementation on my View Adapter looked like this:

I’ve highlighted the code above to get you to think about what is going to happen with the result on the RecyclerView. Make sure you open the ICON_URL on a new tab and refresh a few times to help you out.

thinking...

If your guess was that all the images would be loaded the same for every single item on the RecyclerView, then you’ve either come across this problem or are pretty good at guessing.

Enabling logs show distinct requests being created from Picasso to the URL, which should in theory result in different images right?

As it turns out, it seems like the default behaviour for when you try to load the same URL with Picasso is that it only ever queues your request once. A deeper look into the log showed me only one of the requests was enqueued and executed. And this was not the easiest thing to realise in all honesty.

Theoretically loading up the same page over and over again should always result on the same content and if you remember well, in the beginning of this post I mentioned Picasso takes care of caching for me, and I presume in this case the URL will be the key.

Let’s make a small change to the code and check whether we can force Picasso to think that it needs to enqueue and execute every single one of our URLs regardless.

Doing pretty much the same thing as before, but notice I now have a number that gets appended to each URL. This should make my URLs look like this: https://unsplash.it/50/50?random&{number}.

I'm ugly and I'm proud

Now let’s look at the logs:

Each one of my URLs now started a request that was created, enqueued and executed. And sure enough, now each one of the items on my RecyclerView has a different image for its icon.

But there is a better way. Right?

I found a few threads like this one indicating that a combination of the invalidate() method,  MemoryPolicy and NetworkPolicy should get this to work. So something like this should do the trick right?

Nope! Doing so presented the same behaviour as before, where only one item is ever enqueued.

So for the time being, I will stick to the solution where I add a query parameter to each one of the images to make sure I always get random results on the same URL.

Know the solution?

I would love to hear from you what the correct/less hacky solution you found to this problem. Drop a comment bellow if you know how to make this work without having to fiddle with the URL.

Android: Where is my menu button?

Reading time: 2 – 2 minutes

So you’ve created your super polished android application and added a navigation menu to it, so your users can go from a place to another in your application without having top jump to the main application screen. It’s great, they can now simply press the menu button, and and a little menu pops up showing them all options available in your application. You’ve obviously made sure to select the correct images, and use icons that adhere to the Android style. Great! It’s time to start testing you application in as many devices as you can, and definitely make sure it works on any of the latest devices. Until you you see yourself facing a device that looks like this:

WhereIsTheMenu

Where is my flipping menu?

It turns out most devices now don’t even come with a menu button (iPhone’s never had them for example), and more and more, developers are being discouraged to build applications that actually rely on a physical menu button.

“So, does that mean you can’t use menu’s on your application?”

Continue reading

E4X and XML with namespaces

Reading time: 2 – 3 minutes

Here’s is something that got me scratching my head for a little while today while working on my new mobile application.

In my new application, I’ll be reading XML off various different providers, so I have an interface that gets implemented in various classes to make sure they all obey a certain contract, and I don’t need worry about what type they are (more on that later…)

With that in mind, I ended up implementing different logic on different classes since the XML returned will vary from provider to provider. I am using E4X to get the various information I need from the XML returned, and one of them would not work at all when selected.

I will put two XML examples here, and let you spot the difference:

var basket:XML =
	<foods>
	  <fruit>
		<name>Apples</name>
		<name>Bananas</name>
	  </fruit>
	</foods>;
trace(basket..fruit.name[0])

And that should return “Apples”.

Nothing new here, now for the second example:

var basket:XML =
	<foods xmlns="http://www.w3.org/TR/html4/">
	  <fruit>
		<name>Apples</name>
		<name>Bananas</name>
	  </fruit>
	</foods>;
trace(basket..fruit.name[0])

At a first glance, I have to admit I was expecting apples as well, but to my surprise, I got… nothing…

It took me a while to to go look on the XML again, and then it hit me. This provider would give me XML with a namespace, and in order to read that with E4X, I would need to declare that namespace. There is absolutely nothing wrong with the code above, but it simply won’t find anything since you’re not declaring what the namespace is, and the compiler gets completely lost.

What you need to do is declare the namespace on the top of my code like so:

namespace items = "http://ns.imageshack.us/imginfo/7/";
use namespace items;
trace(basket..fruit)

How you name it doesn’t matter, but it’s important that it’s unique, so in case you’re reading from multiple XML files on the same class, you should be using different names, otherwise you will get compiling errors.

Android and what I’ve been up to

Reading time: 1 – 2 minutes

Androids eat applesPhoto by: laihiu

I jumped into the Android bandwagon about two months ago, and so far I can’t cease to be impressed.

One of my favorite features is how easy it is to install new apps, as well as how open (source) the whole thing is. You can install and do whatever you like, without having to rely on closed platforms, or having to “sync as soon as I get home“. Do it anywhere, and whenever you please. It’s your phone, and you should be allowed freedom.

Continue reading