как внедрить пользовательский адаптер массива во фрагмент с помощью roboguice 2.0

У меня есть фрагмент, содержащий listView. Фрагмент расширяет roboFragment. ListView имеет собственный адаптер, который устанавливает различные элементы пользовательского интерфейса в методе getView. Я хочу использовать @InjectView для получения элементов пользовательского интерфейса. Я понимаю, что для этого мне нужно также создать адаптер, используя guice, а не новый оператор. Вот что делает мой фрагмент:

@Inject
TweetsActivityAdapter tweetsAdapter;

Адаптер выглядит так:

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);
    }

Я читал, что мне нужно настроить guice и сказать ему, где взять ITweet. ITweet — это просто интерфейс для класса модели Tweet.

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();
}

Как создать привязку к списку? В настоящее время я получаю сообщение об ошибке:

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.

Мой модуль выглядит следующим образом: открытый класс MyCustomModule реализует модуль {

    @Override
    public void configure(Binder binder) {
        binder.bind(ITweet.class).to(Tweet.class);
    }
}

person U-L    schedule 12.10.2013    source источник


Ответы (1)


В вашем образце кода есть две основные проблемы:

1) Вы сказали инжектору, как создать экземпляр ITweet, а не List<ITweet>.
Кроме того, как вы ожидаете, что RoboGuice узнает, какие твиты вы хотите добавить в этот список?

Вы могли бы реализовать Provider, чтобы сделать что-то подобное, но это кажется слишком IMO. Более простым способом было бы добавить сеттер к вашему адаптеру и установить данные в ваш адаптер после того, как RoboGuice создал экземпляр.


2) Вы не можете использовать @InjectView в ArrayAdapter

Если вы посмотрите на код RoboActivity вы увидите этот код в обработчике onContentChanged():

@Override
public void onContentChanged() {
    super.onContentChanged();
    RoboGuice.getInjector(this).injectViewMembers(this);
    eventManager.fire(new OnContentChangedEvent());
}

Метод injectViewMembers() творит магию за @InjectView.
К сожалению, этот метод принимает только Activity или Fragment.

Вы можете взглянуть на Butterknife (автор Jake Wharton), который проще, чем RoboGuice, для внедрения представлений.

person nicopico    schedule 14.10.2013