Implementing view injection, SlothFramework

So… I tried to make a Framework, I call it SlothFramework. But I consider it more of an experiment.

While I was developing my last app I decided that I wanted to get rid of as much boilerplate code as I could. So I started a package where I was putting all that code. With time that package become a library and now I’m sharing it with you.

It’s in a clearly alpha (pre-alpha?) state so don’t be too hard on me, but I will be pleased to hear suggestions and (constructive) critics.

For now I present you two of it’s main features, but I will only analyse the view injection:

  • Inject views
  • Save the state of a field to keep its value when you rotate your device.

Implementing view injection

The view injection it’s done through a custom annotation @InjectView, that has for parameter the id of the view. It’s done in a similar way to roboguice.

View injection example:

    @InjectView(   ListView breadCrumList;
    @InjectView( ImageButton changeToList;
    @InjectView( RelativeLayout contextBar;
    @InjectView(        ImageButton edit;
    @InjectView(  EditText searchText;

It’s quite few code the necessary to implement view injection. Basically there are 3 parts:

  • Annotation: To mark the fields to process and pass the view id as parameter.
  • Base classes: To process the annotations in the activities and the fragments.
  • View injector: the one who injects the view. Implementing an injector helps to avoid code replication on base classes.


First we need to define the annotation:

package es.slothdevelopers.slothframework.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public @interface InjectView {
    int value() default Integer.MIN_VALUE;

Base classes

In order to process this annotations and inject the views our classes must extend an Sloth Class (depending if it’s an activity or a fragment).

Here you can check the available classes: available classes.

The view injection is made in different points depending of the base class. This is because the views are consolidated in different forms depending if it’s an activity or a fragment.


Here we have the code related to view injection for an Activity (SlothActivity)class:

public class SlothActivity extends Activity {
    ViewInjector viewInjector = new ViewInjector(this);

    public SlothActivity(){

    private void parseFields() {
        for (Field field : this.getClass().getDeclaredFields()) {
    public void setContentView(int layoutResID) {

In the constructor we parse fields to check the annotations, saving the fields we would inject later.

Then we override the setContentView method (in the Sloth class) to inject the views at this point. It’s made this way because is in this method where we have our view for the first time in the activity.


For the fragments (bases on SlothFragment) we inject the views in the onViewCreated method:

public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

In resume: depending the class you are extending you would have access to the injected views on different points.

  • If you are extending an Activity class you could use the injected views after calling the setContentView method.
  • If you are extending a Fragment class you could use the injected views after calling the super method on onViewCreated.

View Injector

And here we have the code for the injector:

public class ViewInjector {
    List<Field> viewsToInject = new LinkedList<Field>();
    SlothLog log;
    Object caller;

    public ViewInjector(Object caller){
        this.log = new SlothLog(caller);
        this.caller = caller;

    public void checkIfViewToInject(Field field) {
        if (field.isAnnotationPresent(InjectView.class)){

    public void injectViewList(Activity activity) {
        for (Field field: viewsToInject){
            injectView(activity, field);

    private void injectView(Activity activity, Field field) {
        int id = field.getAnnotation(InjectView.class).value();
        if (id == Integer.MIN_VALUE){
        try {
            field.set(caller, activity.findViewById(id));
        } catch (IllegalAccessException e) {
            log.error(errorInjectingView(field, activity.getResources()));
        } catch (IllegalArgumentException ex){
            log.error(errorInjectingView(field, activity.getResources()));

As we can see it basically save the fields to be injected in a List and inject the views on demand. The view injection is done in this line:

field.set(caller, activity.findViewById(id));

Notifying errors

I tried to advise some typical errors injecting view. One of them is try to inject a different type that the one you declared.

In this example I’m trying to inject a ListView in a FrameLayout.

Error injecting view in: MainActivity.
It's possible that the type you are trying to inject differs from the one declared in the layout.
Check code.
FrameLayout listView;

Saving the state of a field, @SaveState annotation

This annotation can be used in simple fields (primitive data types, POJOs, and list) to save the state of the field when we pause our activity and restore it when we resume it.

To use the annotation you must simply add the @SaveState annotation, no parameters needed.


    @SaveState    boolean waitingForRestartGame = false;
    @SaveState    int punctuation = 0;

This annotation can be used in Fragments and Activities.

I will post about this annotation with more time in future posts, but you can check the repository if you want to see how it’s done.

The process it’s similar to the inject view, it involves an annotation, the base classes and the save state injector.

The type support its not complete(I’ll try to make a list), there is still some work to do, and how you can see, it involves Reflection.

Example project

To show the framework in action I made a very simple project.

It consist of a button and a counter. Each time you press the button the counter grows.

Example application

The views are injected automatically. In this example we are injecting the Button and the TextView of the counter with the @InjectView annotation.

We are also saving the state of the counter with the @SaveState annotation. Without the annotation your counter will go down to 0 each time you rotate your device. You could write the code to restore the state, but the main point of the framework is not to do so.

Here is the resulting code of the main activity:

public class MainActivity extends SlothActionBarActivity implements View.OnClickListener {
    int counter = 0;

    @InjectView(       TextView counterCount;
    @InjectView( Button increaseCount;

    protected void onCreate(Bundle savedInstanceState) {

    public void onClick(View view) {

    protected void onResume() {

    private void updateCounterCount(){

You can check the rest of the code in the repository:

That’s all by now. I’ll present more features in future posts.

Thanks for reading.

Sloth logo 3


6 thoughts on “Implementing view injection, SlothFramework

    • Thanks for the comment!
      Your are the second one that talks me about butterknife, I have to check it.
      For view injection I was using roboguice, but I started to program the SaveState annotation and then one thing led to another.
      Now when I think I can simplify (at least for me) something, I try to add it to my little framework.

  1. Pingback: Custom header with parallax effect in ListView | Sloth Developers

  2. I started to get real tired of calling findViewById the whole time. I write too much code myself all the time :P. I should build my own framework too. Can I ask how long you develop for android devices?

    • I made a project with some friends in 2012, it took about 3 months (our first project :D). After that I didn’t continue programming until this January, when I started again. So, in total about 8/9 months.

      • Looks very promising 🙂 Bubble me, nice work. I’ve been developing for android almost 3 years now.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s