I have a fragment that contains a listView. The fragment extends roboFragment. The listView has a custom adapter that sets up different UI elements in the getView method. I want to use @InjectView to get the ui elements. I understand that in order to do this, I need to also create the adapter using guice and not the new operator. So this is what my fragment does:
@Inject
TweetsActivityAdapter tweetsAdapter;
The adapter looks like this:
public class TweetsActivityAdapter extends ArrayAdapter<ITweet> {
@InjectView(R.id.ivProfilePic)
ImageView ivProfilePic;
@InjectView(R.id.tvUserName)
TextView tvUserName;
@InjectView(R.id.tvTweet)
TextView tvTweet;
private final static String tag =
"Debug - com.codepath.upkar.twitterapp.TweetsActivityAdapter";
@Inject
public TweetsActivityAdapter(Context context, List<ITweet> tweets) {
super(context, 0, tweets);
}
I read that I need to configure guice and tell it where to get ITweet from. ITweet is just the interface for Tweet model class.
public interface ITweet {
public User getUser();
public void setUser(User user);
public String getBody();
public long getId();
public long getStrId();
public boolean isFavorited();
public boolean isRetweeted();
}
How do I create a binding for the List? I am currently getting an error:
FATAL EXCEPTION: main
E/AndroidRuntime(18753): java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.bindaas.twitterapp/com.bindaas.twitterapp.activities
.TwitterAppActivity}: com.google.inject.ConfigurationException:
Guice configuration errors:
E/AndroidRuntime(18753): 1) No implementation for
java.util.List<com.bindaas.twitterapp.models.ITweet> was bound.
My module is as follows: public class MyCustomModule implements Module {
@Override
public void configure(Binder binder) {
binder.bind(ITweet.class).to(Tweet.class);
}
}
There is 2 main problems with your code sample:
1) You told the injector how to create an ITweet
instance, not a List<ITweet>
.
Also, how do you expect RoboGuice to know what tweets you want in that list ?
You could implement a Provider
to do something like that, but that seems a bit too much IMO. A simpler way would be to add a setter to your adapter, and set the data to your adapter after it has been instantiated by RoboGuice.
2) You cannot use @InjectView
in a ArrayAdapter
If you look at the code of RoboActivity
, you'll see this code in the onContentChanged()
handler:
@Override
public void onContentChanged() {
super.onContentChanged();
RoboGuice.getInjector(this).injectViewMembers(this);
eventManager.fire(new OnContentChangedEvent());
}
The injectViewMembers()
method is the one doing the magic behind @InjectView
.
Sadly this method only accept an Activity
or a Fragment
.
You might have a look at Butterknife (by Jake Wharton), which is leaner than RoboGuice for views injection.