Part 3: Building a custom image keyboard on Android

James Best
Gravitywell UK
Published in
5 min readNov 15, 2018

--

In part 2 we set the scene, getting the base code in place for the keyboard. We have a working keyboard with a single button. This is great but can we really call it a keyboard when it only has one button?

With the work done in the first part, we can make some headway into making this actually look like a real keyboard.

The areas we are going to concentrate on in this post is the programmatically generated layout for our keyboard.

Hopefully, we will end up with something that looks like this.

Let’s start with the layout files. We are gonna build a number of reusable layout files that we can use to generate the layout based on the number of icons we want to have on our keyboard.

  • Light Blue: keyboard_layout.xml this is the main container layout that forms the base of our keyboard
  • Dark Blue: image_container_column.xml this is the reusable vertical column layout that will hold 2 image buttons.
  • Pink: image_button.xml this is the reusable button layout.

Updated keyboard_layout.xml

The first changes we are going to make is to our keyboard_layout.xml file. Our keyboard displays the icons in a 2-up grid layout and allows the user to scroll sideways. To allow this we add a HorizontalScrollView to our RelativeLayout. The scroll view haswraps_content for both the width and height. Within our scroll view, we place a LinearLayout with a horizontal property set on the orientation. This is the wrapper for our programmatically generated keyboard buttons. We have added an android:id. This gives us a hook into the layout that will come in handy later.

image_container_column.xml

Next, we are going to create the vertical wrapper for the icons. This will hold 2 icons and will be repeated for all the icons.

This is another LinearLayout but with the orientation set to vertical. This will stack the icons on top of each other. Again we add an android:id.

image_button.xml

The last layout file we are creating is the actual button. This layout is pretty simple. We will be adding important properties when we are generating the layout.

That is the layout cover now lets look to update our imageKeyboard class to generate our layout based on the images we have in our res/raw folder. Lets add some more images to display. I am using some icons I downloaded, just make sure you have the rights to use them.

Let move back to the ImageKeyboard class and make the necessary changes to use our new layout files.

We want to be able to display all the icons in the res/raw folder we are gathering all the files in the onCreate method and adding them to a variable ready for use later.

As you can see we are calling a new method getAllResourceand as you can probably grasp from the name it is gathering all the resources from the raw directory. The file names are returned in an array ready for use by the onCreateInputView.

There is a lot going on in the onCreateInputView method so I will include the code first and then run through each part.

As before we are creating a handle to the images path ready to add the image to the editor.

In the next 2 lines we are inflating the keyboard_layout.xml layout file using the getLayoutInflator method and assign that to a local variable giving us a hook into that layout. We then use that hook to get a specific part of the layout using the android:id we set earlier.

Again we use the getLayoutInflator method to get access to the imageContainerColumn.xml layout file. Here we are passing in the imageContainer variable into the inflator giving the layout that context. This step is important as it allows us to add the required click handlers and passes the ImageKeyboard context.

Now to generate the buttons. We loop through all the filenames in the rawFiles array creating ImageContainerColumn every 2 loop interations. Basically creating a new vertical column every 2 icons as per the design.

Every iteration of the loop we are getting a hook into the ImageButton layout file. Once again we are passing in the correct context.

Once we have the hook we add an image resource to the ImageButton using the setImageResource. We also add the filename as a tag and the click handler.

The click handler is pretty similar to the addImage method we wrote in the first part, we assign a new method to the setOnClickHandler property. The method uses the getFileForResource and doCommitContent methods we wrote in the first part. It is also using the tag we just assigned to create a description for the doCommitContent method.

We then add the newly created ImageButton to the ImageContainerColumn layout.

Finally, we add the new ImageContainerColumn to the ImageContainer layout every other iteration.

Phew, that was a lot to get through. I hope it all makes sense!

And that is it. We now have a fully working image keyboard that looks the part and functions perfectly. Our version of the app only delivers png images but could easily be extended to deliver different or multiple types of rich content.

The source code for this tutorial can be found here.

See what we have done for others and get in touch to discuss what we can achieve together

--

--

James Best
Gravitywell UK

Tech and photography loving developer @candideTech. A host on the @salted-bytes