Glideは、Androidアプリで画像を表示するときに、簡単にセットしてくれたり、丸く切り抜いてくれる便利なライブラリです。
今回、そのGlideをDatabindingと一緒に使う方法です。
最初、下記を見てやってましたが
https://androidwave.com/loading-images-using-data-binding/
うまくいかなかったので、自分でちょっとアレンジしています。
GlideとDataBinding自体の適用は、いろんなところで情報がありますので、割愛させていただきます。
①まず、Fragmentのレイアウトファイル。DataBinding時代になってから、レイアウトファイルをいかにうまく書くか、は結構難しくなりましたね。
fragment.user_list.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="imageUrl"
type="String" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/ivProfileImage"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:layout_margin="5dip"
android:contentDescription=""
app:profileImage="@{imageUrl}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
②UsrListViewModel.kt ビューモデルです。
class UserListViewModel constructor(private val repository: UserRepository) : ViewModel() {
val TAG: String = "UserListViewModel"
//監視対象のLiveData
var userListLiveData = MutableLiveData<List<User>>()
//引数が必要な時は、Factoryが必要
class Factory(private val repository: UserRepository) :
ViewModelProvider.NewInstanceFactory() {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return UserListViewModel(repository) as T
}
}
//これが大事 スタティックにしないとエラーが出ます。
companion object {
@JvmStatic
@BindingAdapter("profileImage")
fun loadImage(view: ImageView, imageUrl: String?) {
//imageUrlはnullチェックが必要です。
if(imageUrl != null) {
Glide.with(view.context)
.load(imageUrl).apply(RequestOptions().circleCrop())
.into(view)
}
}
}
}
なんで、これスタティックにしないといけないのかなーとか、思ってましたが、スタティックにしないと次のエラーが出ます。
java.lang.IllegalStateException: Required DataBindingComponent is null in class FragmentUserListBindingImpl. A BindingAdapter in jp.onlineconsultant.hogehoge.User is not static and requires an object to use, retrieved from the DataBindingComponent. If you don't use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.
imageUrlをnull許可にして、nullチェックしないと、次のエラーも出ます。
Process: jp.onlineconsultant.hogehoge.dev, PID: 19146
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter imageUrl
③Fragmentです。値をセットします。
UserListFragment.kt
class UserListFragment : Fragment() {
private lateinit var userListViewModel: UserListViewModel
private lateinit var binding: FragmentUserListBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val database = getDatabase(getActivity() as MainActivity)
val repository = UserRepository(database.userDao)
userListViewModel = ViewModelProviders.of(this, UserListViewModel.Factory(repository))
.get(UserListViewModel::class.java)
//dataBinding用のレイアウトリソース
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_user_list, container, false)
setRecycleView(binding)
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
binding.setImageUrl("https://pbs.twimg.com/profile_images/1162746270697443336/EMUCXT0E_400x400.jpg");
observeViewModel(userListViewModel)
}
}