By day, I mostly use Microsoft development tools, and have used them for YEARS. I’ve
been experimenting with some Android development recently, and was annoyed by
several missing handy tricks that Microsoft tools have done for years. So, I just
coded one replacement.
Commonly, in Microsoft platforms, when you create a user interface element (from VB3
to WPF and Silverlight) and give it an ID/Name, that named element is readily
available in code-behind, without any extra effort. Nice.
Android development, apparently, is lacking that feature. So, I created a simple
pattern to make it convenient for me. Imagine the following UI element defined in an
Android Layout:
<Button android:id="@+id/btnSend" android:layout_width="fill_parent"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content" android:text="@string/send_message" />
As you can see, the id of the Button is btnSend.
Normally, in the backing Java class if you wanted to access that UI element, you’d
add code like this:
Button btn = (Button) findViewById(R.id.btnSend);
Simple, but annoying for commonly accessed UI elements (or Views).
I’m not the best Java coder by any means as I’ve not done it full time for more than
10 years and my knowledge of any recent Java innovations is zero. So, take this code
with a pinch of skepticism.
private void autoWire() {
Field[] privateFields = this.getClass().getDeclaredFields();
for(Field f : privateFields){
f.setAccessible(true);
ViewId viewId = f.getAnnotation(ViewId.class);
if (viewId != null ){
try {
f.set(this, (Object)this.findViewById(viewId.Id()));
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Now, in the onCreate method that is typical of an Android Activity, I call the
method above, autoWire.
This Java code looks at the current class for declarations like this:
@ViewId(Id=R.id.btnSend)
private Button btnSend;
It’s just an annotation (ViewId), followed by the Id of the control.
The annotation definition is:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author WiredPrairie
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ViewId {
int Id();
}
Using autoWire, btnSend is automatically set and ready to rock and roll.