Part 3: Building a custom image keyboard on Android
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 getAllResource
and 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.