Question

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);
    }
}
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top