Как настроить @BindingAdapter с помощью Picasso?

Я хотел бы создать сетку изображений фильмов с помощью привязок.

Моя viewmodel выглядит так:

public class PopularMoviesViewModel extends BaseObservable { Movie movie; Context context; MovieServiceComponent movieServiceComponent = DaggerMovieServiceComponent.builder() .contextModule(new ContextModule(context)) .build(); Picasso getPicasso = movieServiceComponent.getPicasso(); public PopularMoviesViewModel(Movie movie, Context context) { this.movie = movie; this.context = context; } @Bindable public String getImageUrl(){ return movie.posterPath(); } @Bindable public String getTitle(){ return movie.originalTitle(); } @BindingAdapter({"imageUrl"}) public void setImageUrl(ImageView view, String poserPath){ getPicasso.with(view.getContext()).load("http://image.tmdb.org/t/p/w185"+ poserPath).into(view); } } 

Планировка:

 <?xml version="1.0" encoding="utf-8"?> <layout xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <data class="PopularMoviesBinding"> <variable name="pmvm" type="com.hartyandi.oviesm.modelviews.PopularMoviesViewModel"></variable> </data> <LinearLayout android:id="@+id/row" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFF" android:paddingBottom="0dp" android:paddingTop="5dp" android:paddingRight="2.5dp" android:paddingLeft="5dp" android:orientation="vertical"> <ImageView app:imageUrl="@{pmvm.imageUrl}" android:id="@+id/popular_movies_grid_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="0dp" android:adjustViewBounds="true" android:elevation="20dp"> </ImageView> <TextView android:id="@+id/popular_movies_grid_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{pmvm.title}" android:textColor="#000000" android:textSize="12sp" android:background="#FFFFFF" > </TextView> </LinearLayout> </layout> 

адаптер:

 public class PopularMoviesAdapter extends RecyclerView.Adapter<PopularMoviesAdapter.BindingHolder> { private List<Movie> movies; private Context context; public PopularMoviesAdapter(List<Movie> movies, Context context) { this.movies = movies; this.context = context; } public void add(Movie movie){ movies.add(movie); } @Override public BindingHolder onCreateViewHolder(ViewGroup parent, int viewType) { PopularMoviesBinding popularMoviesBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.popular_movies_gridview_row, parent,false); return new BindingHolder(popularMoviesBinding); } @Override public void onBindViewHolder(PopularMoviesAdapter.BindingHolder holder, int position) { PopularMoviesBinding popularMoviesBinding = holder.popularMoviesBinding; popularMoviesBinding.setPmvm(new PopularMoviesViewModel(movies.get(position), context)); } @Override public int getItemCount() { return movies.size(); } public class BindingHolder extends RecyclerView.ViewHolder{ private PopularMoviesBinding popularMoviesBinding; public BindingHolder(PopularMoviesBinding popularMoviesBinding) { super(popularMoviesBinding.getRoot()); this.popularMoviesBinding = popularMoviesBinding; } } } 

Я получаю следующую ошибку:

 java.lang.IllegalStateException: Required DataBindingComponent is null in class PopularMoviesBinding.A BindingAdapter in modelviews.PopularMoviesViewModel is not static and requires an object to use, retrieved from the DataBindingComponent. 

Я попытался изменить свою реализацию так же, как это предложение postoverflow предложить, и я получил то же сообщение об ошибке.

Я также использовал следующий код в качестве примера.

Может ли кто-нибудь объяснить, в чем проблема с кодом и как его решить?

Вероятно, вы не собираетесь использовать метод экземпляра для BindingAdapter .

Если вы это сделаете, вы должны предоставить DataBindingComponent, чтобы сгенерированный класс Binding знал, какой экземпляр использовать.

У вас есть два варианта: предоставить DataBindingComponent или просто передать требуемый контекст в качестве атрибута для метода статического привязывающего адаптера. Второе немного легче понять, поэтому я начну с этого:

 <?xml version="1.0" encoding="utf-8"?> <layout xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android"> <data class="PopularMoviesBinding"> <variable name="pmvm" type="com.hartyandi.oviesm.modelviews.PopularMoviesViewModel"/> <variable name="picasso" type="com.whatever.Picasso"/> </data> <!-- ... --> <ImageView app:imageUrl="@{pmvm.imageUrl}" app:picasso="@{picasso}" ... /> </ImageView> </layout> 

Затем в вашем BindingAdapter:

 @BindingAdapter({"imageUrl", "picasso"}) public static void setImageUrl(ImageView view, String poserPath, Picasso picasso){ picasso.with(view.getContext()).load("http://image.tmdb.org/t/p/w185"+ poserPath).into(view); } 

Обратите внимание, что setImageUrl теперь static .

В качестве альтернативы, поскольку ваш экземпляр Picasso также находится в ViewModel, вы можете просто передать экземпляр, добавив геттер для пикассо:

 <ImageView app:imageUrl="@{pmvm.imageUrl}" app:picasso="@{pmvm.picasso}" ... /> 

И метод в вашей модели ViewModel:

 public Picasso getPicasso() { return this.getPicasso; } 

Другой способ означает, что вы реализуете DataBindingComponent . Когда вы создаете метод BindingAdapter экземпляра, сгенерированный интерфейс будет иметь getter для вашего класса. Вам необходимо создать класс для реализации этого интерфейса:

 public class MyDataBindingComponent implements DataBindingComponent { public PopularMoviesViewModel getPopularMoviesViewModel() { return whateverIDoToCreateOrGetThisBindingAdapterInstance(); } } 

Затем вы передаете экземпляр, когда вы надуваете или связываете:

 PopularMoviesBinding popularMoviesBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.popular_movies_gridview_row, parent,false, new MyDataBindingComponent()); 
Intereting Posts
Как я могу напрямую отправить электронное письмо с помощью почтового приложения по умолчанию на устройстве Настройте ActionBar на Android с помощью ActionbarSherlock и jeremyfeinstein slidemenu Есть ли способ поделиться одним и тем же LayoutManager между несколькими вложенными RecyclerViews OnMessageReceived не вызван в WearableListenerService Двойная SIM-карта Android Назначение камеры и очередь приоритетов в Android Запустить службу на Android Значение всегда возвращает 0, где он должен возвращать число вставленной строки Android Offline Speech Recognition показывает только один результат? Как настроить java.util.logging.logger в android для использования файла свойств ведения журнала, размещенного на SD-карте? Как определить изменение ориентации в макете в Android? Как сохранить изображение на SD-карту на кнопке Click android Android – вытащить Android-устройство SQlite Сохранить base64 строку как изображение с помощью phonegap? Масштабирование VideoView для заполнения ширины, сохраняя соотношение сторон