Introducing the $ - the Heart of the Vapor Android Framework

The $, much like in jQuery, should be your first port-of-call for any core functionality you need.

It contains a wealth of extremely useful static factory and helper methods that efficiently make the most of the Vapor framework, concealing the repetitive and ugly boilerplate code associated with common tasks in an Android app developer's life.

Using the $ in the Vapor framework will save you precious development time, and make your Android app code a lot more compact as a result. Win win!

As a convention $ methods usually start with a lower case letter, as is standard practice in Java. However, factory methods are an exception to this rule. This is because the factory methods in the $ class are analogous to class constructors, and are named with a starting capital letter to reflect this:
    // Analogous to : new ImageView<ImageView,?>(R.id.myImageView) ...
    $.ImageView(R.id.myImageView) ...

Factory methods will also accept a View object, providing it can be safely cast to the intended underlying Android type. Here's an example in the onClick callback, registered to a VaporButton in this case:

    $.Button(R.id.myButton).click(new $$click(){

		public void onClick(View v){
            
            // we know 'v' is actually our R.id.myButton button!
			$.Button(v).text("I was clicked!"); 
		}

	});

Because we know the actual type of v is Button we can safely pass it to the $.Button(...) factory method to get back a fluent VaporButton. Also note that this would also work if v was some derived class from Button, for example a custom button class you have written!

You might also be wondering about the use of $$click in the .click(...) method. This is an example of a 'One Size Fits All' double-dollar ($$) listener, discussed in detail in the Callbacks section. Head there now for a look at the meaning of single-dollar ($) and double-dollar ($$) type prefixes in the Vapor Android framework.

Example Code

Let's look at some examples. Say, you want to change a TextView's text in your app depending on the current device type:

 $.TextView(R.id.deviceCheck).text( $.tablet()? "USING A TABLET" : "USING A PHONE");

This line of code retrieves a TextView with the id "deviceCheck", and sets it's text dynamically depending on what type of device the Vapor Android framework deduces the application to be running on.

This is neat enough, but we could also utilise the powerful Vapor Hook Framework through the $ facade to achieve the same thing:

// jQuery style list of selectors
$.hooks(VaporActivity.DEVICE_TABLET,VaporActivity.DEVICE_PHONE)

	.hookIn(new $$hookee<TextView>($.TextView(R.id.deviceCheck)){

		public void call(String hookName, VaporBundle args){
		
			String device = hookName.equals(DEVICE_TABLET)? "TABLET" : "PHONE";
			
            // $subject is a handle to our TextView here!
			$subject.text("USING A " + device); 
		}
	}
);

There are several things going on here, so let's step through them one by one:

  • On Line 1 we use VaporX in conjunction with the Vapor Hook Engine to subscribe to both VaporActivity.DEVICE_TABLET and VaporActivity.DEVICE_PHONE hooks - passed as jQuery like selectors
  • On Line 2 we create an anonymous inline instance of $$hookee, an alias for a VaporHookee - the wrapper around subscribers to a hook. We pass the TextView object to the $$hookee constructor so that we can use $subject inside the object as an alias for our TextView
  • Inside the .call(...) method we provide our logic for setting the TextView as before, but this time we use the $subject handle to do so
We could easily retrieve our TextView handle inside the $$hookee using $.Text(R.id.deviceCheck), but this demonstrates how to assign to $subject as this is useful in situations where the variable goes out of scope and cannot be statically retrieved It is good practice to hook out of a hook you no longer need it. In the above example R.id.deviceCheck might not be part of the layout for the next Activity firing this hook

Granted, using the Vapor Hook Framework is unnecessary with this example and requires more code. However, this shows how we can quickly and easily create async callbacks using the $ methods. Don't forget, you can even create your own bespoke hooks and callbacks in the apps you develop with the Vapor Android framework!

VaporViews

When using the $ factory methods to retrieve an instance of a Vapor or VaporX View, the subsequent changes you make to the state of the Vapor object are also reflected in the underlying Android View. Hence you needn't maintain a reference to a VaporView or View as it can be easily retrieved again from where you left off using $ methods.

Multi-selectors

Moreover, the Vapor Android framework is smart enough to know when you wish to create a VaporView or VaporXView. VaporX types are a great feature in Vapor as they let you invoke methods on a group of related components at once.

The $ factory methods will return you the required VaporXView type whenever you supply a varargs list of more than one selector to a $ View factory method. However unlike jQuery, if you supply just one selector you are given the required singular VaporView type instead.

The VaporView and VaporXView section discusses the differences in more detail, so here we are just going to run through a brief example. Say you want to add the same click listener to two of your buttons. Normally you would do this sequentially, but thanks to VaporX you can do the following:

$.Button(R.id.button1,R.id.button2).click(new $$click(){

    public void onClick(View v){
        $.Button(v).text("Clicked!").pulse();
    }

});

The new $$click listener will be set for both R.id.button1 and R.id.button2 in one statement. This is a trivial example, but in many cases it is helpful to be able to manage a set of View components at once, say if you wanted to disable a set of TextViews when a submit button is pressed:

$.Button(R.id.submit).click(new $$click(){

    public void onClick(View v){
        $.TextView(R.id.name,R.id.address,R.id.phone,R.id.email)
            .enabled(false); // disable the text fields
    }

});

Because of the intelligent $ factory methods you need not be concerned about what goes on under-the-hood. All you need to bear in mind is that a VaporXView invokes methods on all constituent views, and returns an aggregate ArrayList of results from methods (if they have a return type other than self), instead of just one value.

Callbacks

The $ symbol is also used as a prefix for type names in Vapor that pertain to events. They are discussed in the Callbacks section.

Further Reading

The $ facade contains a wealth of useful methods, so reading the documentation is highly recommended.

Also, if you are using an IDE why not experiment with the $ class interactively to learn more.