Skip to content
Jorge Martin Espinosa edited this page Jan 18, 2015 · 16 revisions

Introduction. What is SwissKnife?

SwissKnife is a multi-purpose library based -only in behavior, not in code- on other libraries such as ButterKnife or AndroidAnnotations.

A Swiss army Knife is like a Dagger, but although it may be less sharp, it can be more handy 😉.

This library is only compatible with Groovy language as it uses its Ast processing to generate the final code. If you don't use Groovy on your Android projects yet, you can find some info about how to use it here.

Don't be afraid of using Groovy, Android Studio supports it really well, its syntax is almost the same as Java's, it's compatible with Dalvik and ART and can be mixed with your existing Java code. Also, most times turning a Java class into a Groovy one is as easy as changing the file extension from .java to .groovy.

How to use the annotations

SwissKnife is heavily based on annotations. Most annotations will need only one parameter named value which can be a View id or a list of ids. When it's the only annotation parameter, the "value=" part can be ignored.

@InjectView(R.id.button)
Button myButton;

@InjectView(value=R.id.button)
Button myButton;

// To inject several views, the annotation is @InjectViews, in plural
@InjectViews([R.id.view_1, R.id.view_2])
List<View> myViews;

// This case here is special. If the name of the field is the same as the id, the @InjectView annotation doesn't need any parameters
@InjectView()
Button button_1;

Also, you can have several listener injection methods. When the listener is triggered on the provided view, they will execute the code specified in the method. On some annotations, a "method" parameter is also required to specify which method of the listener interface will be triggered.

@OnClick(R.id.button)
public void onClick() {
    Toast.makeText(this, "Button clicked", Toast.LENGTH_SHORT).show();
}

// You can provide a list of ids here, too
@OnClick([R.id.button_1, R.id.button_2])
public void onClick(View v) {
    Toast.makeText(this, "Button $v.text clicked", Toast.LENGTH_SHORT).show();
}

@OnItemSelected(value=R.id.list, method=OnItemSelected.Method.NOTHING_SELECTED)
public void onItemSelected(AdapterView adapterView) {
    Toast.makeText(this, "Nothing selected", Toast.LENGTH_SHORT).show();
}

Also, you can't just use any combination of parameters you want on the method. Each annotation has its compatible method declarations. You can see more in each annotation's wiki page.

Injecting Views and Listeners

To make those annotations work, both view injection and listener injection, you will need to tell your class to use SwissKnife. You can do it like this:

// Inject an Activity or a View in which "findViewById()" method is accesible
SwissKnife.inject(Object objectInjected);

// If you are using a Fragment or want to inject a View's children into any object, you use this
SwissKnife.inject(Object objectInjected, View viewToInject);

For example, in an Activity, you would do it like this:

SwissKnife.inject(this);

And in a Fragment, it would be:

SwissKnife.inject(this, getView());

This means that injection can be used on any class and is done on runtime, so you can choose when you want that injection to happen.

Method declaration and Intellij IDEA Plugin:

As stated before, annotated method declarations can't be anything you want, as this library uses reflection to call them and must have a specified argument structure. To see compatible declarations with each annotation, please visit their wiki pages.

Also, as I realized this was difficult to remember, I started working on an IntelliJ Plugin which creates the annotations, the declarations and imports the needed classes for you. You can find it here.

screen_methods