Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Data Binding with RecyclerView

Data Binding with RecyclerView

shibuya.apk #16

Keisuke Kobayashi

June 22, 2017
Tweet

More Decks by Keisuke Kobayashi

Other Decks in Programming

Transcript

  1. user_list_item.xml • ֤Ϣʔβʔͱ֤ΞΠςϜͷόΠϯσΟϯά <layout> <data> <variable name="user" type="com.example.app.User"/> </data> <LinearLayout>

    <ImageView app:imageUrl="@{user.imageUrl}"/> <TextView android:text="@{user.name}"/> </LinearLayout> </layout>
  2. user_list_item.xml • ֤Ϣʔβʔͱ֤ΞΠςϜͷόΠϯσΟϯά <layout> <data> <variable name="user" type="com.example.app.User"/> </data> <LinearLayout>

    <ImageView app:imageUrl="@{user.imageUrl}"/> <TextView android:text="@{user.name}"/> </LinearLayout> </layout> UserʹόΠϯυ
  3. UserListViewModel • ͜͜Ͱ͸ϢʔβʔϦετ͸ݻఆ class UserListViewModel: BaseObservable() { val users =

    listOf( User(“taro”, “https://example.com/1.png”), User(“jiro”, “https://example.com/2.png”), User(“saburo”, “https://example.com/3.png”) ) }
  4. UserListActivity lateinit var viewModel: UserListViewModel override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) val binding = DataBindingUtil.setContentView<UserListActivityBinding>( this, R.layout.user_list_activity) // Set up viewModel here (ex. inject by Dagger) binding.recyclerView.setAdapter(UserAdapter(viewModel.users)) }
  5. UserListActivity lateinit var viewModel: UserListViewModel override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) val binding = DataBindingUtil.setContentView<UserListActivityBinding>( this, R.layout.user_list_activity) // Set up viewModel here (ex. inject by Dagger) binding.recyclerView.setAdapter(UserAdapter(viewModel.users)) } ը໘ͷϏϡʔϞσϧ ͜͜ͰॳظԽ
  6. UserListActivity lateinit var viewModel: UserListViewModel override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState) val binding = DataBindingUtil.setContentView<UserListActivityBinding>( this, R.layout.user_list_activity) // Set up viewModel here (ex. inject by Dagger) binding.recyclerView.setAdapter(UserAdapter(viewModel.users)) } ը໘ͷϏϡʔϞσϧͷusersΛΞμϓλʔʹηοτ
  7. UserAdapter class UserAdapter(val users: List<User>): RecyclerView.Adapter<ViewHolder>() { override fun onCreateViewHolder(parent:

    ViewGroup, viewType: Int): ViewHolder { val binding = UserListItemBinding.inflate(inflater, parent, false) return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = holder.binding binding.user.set(users[position]) } }
  8. UserAdapter class UserAdapter(val users: List<User>): RecyclerView.Adapter<ViewHolder>() { override fun onCreateViewHolder(parent:

    ViewGroup, viewType: Int): ViewHolder { val binding = UserListItemBinding.inflate(inflater, parent, false) return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = holder.binding binding.user.set(users[position]) } } UserListItemBinding༻
 ViewHolder
  9. UserAdapter class UserAdapter(val users: List<User>): RecyclerView.Adapter<ViewHolder>() { override fun onCreateViewHolder(parent:

    ViewGroup, viewType: Int): ViewHolder { val binding = UserListItemBinding.inflate(inflater, parent, false) return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = holder.binding binding.user.set(users[position]) } } onBindViewHolderͰ
 ϢʔβʔΛηοτ͢Δ
  10. UserListViewModel class UserListViewModel(...): BaseObservable() { val users = mutableListOf<User>() fun

    onStart() { // getUsers͸Single<List<User>> getUsers().subscribe({ users.addAll(it) adapter.notifyDataSetChanged() }) } }
  11. UserListViewModel class UserListViewModel(...): BaseObservable() { val users = mutableListOf<User>() fun

    onStart() { // getUsers͸Single<List<User>> getUsers().subscribe({ users.addAll(it) adapter.notifyDataSetChanged() }) } } ???
  12. UserListViewModel class UserListViewModel: BaseObservable() { val users = ObservableArrayList<User>() //

    Called from activity's onCreate fun initialize() { getUsers().subscribe({ users.addAll(it) }) } }
  13. UserListViewModel class UserListViewModel: BaseObservable() { val users = ObservableArrayList<User>() //

    Called from activity's onCreate fun initialize() { getUsers().subscribe({ users.addAll(it) }) } } ObservableList
  14. UserListViewModel class UserListViewModel: BaseObservable() { val users = ObservableArrayList<User>() //

    Called from activity's onCreate fun initialize() { getUsers().subscribe({ users.addAll(it) }) } } ͜Ε͚ͩͰOK
  15. UserAdapter class UserAdapter(val users: ObservableList<User>): RecyclerView.Adapter<ViewHolder>() { init { users.addOnListChangedCallback(object:

    ObservableList.OnListChangedCallback<ObservableList<User>>() { override fun onChanged(users: ObservableList<User>?) { notifyDataSetChanged() } ... }) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {...} override fun onBindViewHolder(holder: ViewHolder, position: Int) {...} }
  16. UserAdapter class UserAdapter(val users: ObservableList<User>): RecyclerView.Adapter<ViewHolder>() { init { users.addOnListChangedCallback(object:

    ObservableList.OnListChangedCallback<ObservableList<User>>() { override fun onChanged(users: ObservableList<User>?) { notifyDataSetChanged() } ... }) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {...} override fun onBindViewHolder(holder: ViewHolder, position: Int) {...} } ίϯετϥΫλͰObservableListΛड͚औΔ
  17. UserAdapter class UserAdapter(val users: ObservableList<User>): RecyclerView.Adapter<ViewHolder>() { init { users.addOnListChangedCallback(object:

    ObservableList.OnListChangedCallback<ObservableList<User>>() { override fun onChanged(users: ObservableList<User>?) { notifyDataSetChanged() } ... }) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {...} override fun onBindViewHolder(holder: ViewHolder, position: Int) {...} } ॳظԽ࣌ʹ ίʔϧόοΫొ࿥
  18. UserAdapter class UserAdapter(val users: ObservableList<User>): RecyclerView.Adapter<ViewHolder>() { init { users.addOnListChangedCallback(object:

    ObservableList.OnListChangedCallback<ObservableList<User>>() { override fun onChanged(users: ObservableList<User>?) { notifyDataSetChanged() } ... }) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {...} override fun onBindViewHolder(holder: ViewHolder, position: Int) {...} } ֤ίʔϧόοΫͰ
 notifyʙΛݺͿ
  19. ༨ஊ: ϕʔεΫϥεʹ͢Δ abstract class ObservableRecyclerAdapter<T>( val items: ObservableList<T> ): RecyclerView.Adapter<BindingViewHolder>()

    { init { items.addOnListChangedCallback(object: ObservableList.OnListChangedCallback<ObservableList<T>>() { override fun onChanged(items: ObservableList<T>?) { notifyDataSetChanged() } ... }) } }
  20. ༨ஊ: ϕʔεΫϥεʹ͢Δ abstract class ObservableRecyclerAdapter<T>( val items: ObservableList<T> ): RecyclerView.Adapter<BindingViewHolder>()

    { init { items.addOnListChangedCallback(object: ObservableList.OnListChangedCallback<ObservableList<T>>() { override fun onChanged(items: ObservableList<T>?) { notifyDataSetChanged() } ... }) } }
  21. UserAdapter class UserAdapter(val users: ObservableList<User>): RecyclerView.Adapter<ViewHolder>() { init {...} override

    fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder { ... } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = holder.binding binding.user.set(users[position]) binding.executePendingBindings() } }
  22. UserAdapter class UserAdapter(val users: ObservableList<User>): RecyclerView.Adapter<ViewHolder>() { init {...} override

    fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder { ... } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = holder.binding binding.user.set(users[position]) binding.executePendingBindings() } } ͜ΕͰଈ࣌ʹUIߋ৽͞ΕΔʂ
  23. Files • ը໘શମ • user_list_activity.xml • UserListActivity • UserAdapter •

    UserListViewModel • ֤ΞΠςϜ • user_list_item.xml • UserViewModel ʢ֤ΞΠςϜͷϏϡʔϞσϧʣ
  24. user_list_item.xml <layout> <data> <variable name="viewModel" type="com.example.app.UserViewModel"/> </data> <LinearLayout android:onClick="@{viewModel::onItemClick}"> <ImageView

    app:imageUrl="@{viewModel.user.imageUrl}" android:onClick="@{viewModel::onImageClick}"/> <TextView android:text="@{viewModel.user.name}"/> </LinearLayout> </layout>
  25. user_list_item.xml <layout> <data> <variable name="viewModel" type="com.example.app.UserViewModel"/> </data> <LinearLayout android:onClick="@{viewModel::onItemClick}"> <ImageView

    app:imageUrl="@{viewModel.user.imageUrl}" android:onClick="@{viewModel::onImageClick}"/> <TextView android:text="@{viewModel.user.name}"/> </LinearLayout> </layout> ΞΠςϜ͝ͱͷ
 ϏϡʔϞσϧ
  26. user_list_item.xml <layout> <data> <variable name="viewModel" type="com.example.app.UserViewModel"/> </data> <LinearLayout android:onClick="@{viewModel::onItemClick}"> <ImageView

    app:imageUrl="@{viewModel.user.imageUrl}" android:onClick="@{viewModel::onImageClick}"/> <TextView android:text="@{viewModel.user.name}"/> </LinearLayout> </layout> ΫϦοΫΠϕϯτΛ
 όΠϯυ
  27. UserViewModel class UserViewModel: BaseObservable() { val user = ObservableField<User>() fun

    onItemClick(view: View) { // go to profile } fun onImageClick(view: View) { // go to image viewer } }
  28. UserAdapter class UserAdapter(val users: ObservableList<User>): RecyclerView.Adapter<ViewHolder>() { init {...} override

    fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = UserListItemBinding.inflate(inflater, parent, false) binding.viewModel = UserViewModel() return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = holder.binding binding.viewModel.user.set(users[position]) binding.executePendingBindings() } }
  29. UserAdapter class UserAdapter(val users: ObservableList<User>): RecyclerView.Adapter<ViewHolder>() { init {...} override

    fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = UserListItemBinding.inflate(inflater, parent, false) binding.viewModel = UserViewModel() return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = holder.binding binding.viewModel.user.set(users[position]) binding.executePendingBindings() } } Ϗϡʔͷ࡞੒࣌ʹ
 ϏϡʔϞσϧΛηοτ
  30. UserAdapter class UserAdapter(val users: ObservableList<User>): RecyclerView.Adapter<ViewHolder>() { init {...} override

    fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = UserListItemBinding.inflate(inflater, parent, false) binding.viewModel = UserViewModel() return ViewHolder(binding) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = holder.binding binding.viewModel.user.set(users[position]) binding.executePendingBindings() } } ϏϡʔϞσϧͷ
 ϢʔβʔΛߋ৽