diff --git a/app/build.gradle b/app/build.gradle index 2e96a76..ccf02a5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,7 +11,7 @@ repositories { android { compileSdkVersion 23 - buildToolsVersion '23.0.2' + buildToolsVersion '25.0.0' defaultConfig { applicationId "net.droidlabs.mvvmdemo" diff --git a/app/src/main/java/net/droidlabs/mvvmdemo/binder/SuperUserBinder.java b/app/src/main/java/net/droidlabs/mvvmdemo/binder/SuperUserBinder.java index bc06985..70e7974 100644 --- a/app/src/main/java/net/droidlabs/mvvmdemo/binder/SuperUserBinder.java +++ b/app/src/main/java/net/droidlabs/mvvmdemo/binder/SuperUserBinder.java @@ -4,16 +4,14 @@ import net.droidlabs.mvvmdemo.viewmodel.SuperUserViewModel; import net.droidlabs.mvvmdemo.viewmodel.UserViewModel; -public class SuperUserBinder extends ConditionalDataBinder -{ - public SuperUserBinder(int bindingVariable, int layoutId) - { - super(bindingVariable, layoutId); +public class SuperUserBinder extends ConditionalDataBinder { + + public SuperUserBinder(int bindingVariable, int layoutId) { + super(bindingVariable, layoutId, null); } @Override - public boolean canHandle(UserViewModel model) - { + public boolean canHandle(UserViewModel model) { return model instanceof SuperUserViewModel; } } diff --git a/app/src/main/java/net/droidlabs/mvvmdemo/binder/UserBinder.java b/app/src/main/java/net/droidlabs/mvvmdemo/binder/UserBinder.java index 36ad3a3..bf5654e 100644 --- a/app/src/main/java/net/droidlabs/mvvmdemo/binder/UserBinder.java +++ b/app/src/main/java/net/droidlabs/mvvmdemo/binder/UserBinder.java @@ -3,16 +3,13 @@ import net.droidlabs.mvvm.recyclerview.adapter.binder.ConditionalDataBinder; import net.droidlabs.mvvmdemo.viewmodel.UserViewModel; -public class UserBinder extends ConditionalDataBinder -{ - public UserBinder(int bindingVariable, int layoutId) - { - super(bindingVariable, layoutId); +public class UserBinder extends ConditionalDataBinder { + public UserBinder(int bindingVariable, int layoutId) { + super(bindingVariable, layoutId, null); } @Override - public boolean canHandle(UserViewModel model) - { + public boolean canHandle(UserViewModel model) { return true; } } diff --git a/app/src/main/java/net/droidlabs/mvvmdemo/model/Group.java b/app/src/main/java/net/droidlabs/mvvmdemo/model/Group.java new file mode 100644 index 0000000..37298fa --- /dev/null +++ b/app/src/main/java/net/droidlabs/mvvmdemo/model/Group.java @@ -0,0 +1,12 @@ +package net.droidlabs.mvvmdemo.model; + +public class Group { + + public String name; + public String id; + + public Group(String name, String id) { + this.name = name; + this.id = id; + } +} diff --git a/app/src/main/java/net/droidlabs/mvvmdemo/view/UsersView.java b/app/src/main/java/net/droidlabs/mvvmdemo/view/UsersView.java index bea41fe..b86aa6c 100644 --- a/app/src/main/java/net/droidlabs/mvvmdemo/view/UsersView.java +++ b/app/src/main/java/net/droidlabs/mvvmdemo/view/UsersView.java @@ -1,5 +1,7 @@ package net.droidlabs.mvvmdemo.view; +import android.app.Activity; +import android.content.Context; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.annotation.Nullable; @@ -9,35 +11,38 @@ import android.view.View; import android.widget.EditText; import android.widget.Toast; + import net.droidlabs.mvvm.recyclerview.adapter.ClickHandler; import net.droidlabs.mvvm.recyclerview.adapter.LongClickHandler; import net.droidlabs.mvvm.recyclerview.adapter.binder.CompositeItemBinder; import net.droidlabs.mvvm.recyclerview.adapter.binder.ItemBinder; +import net.droidlabs.mvvm.recyclerview.adapter.binder.ItemBinderBase; import net.droidlabs.mvvmdemo.BR; import net.droidlabs.mvvmdemo.R; import net.droidlabs.mvvmdemo.binder.SuperUserBinder; import net.droidlabs.mvvmdemo.binder.UserBinder; import net.droidlabs.mvvmdemo.databinding.UsersViewBinding; +import net.droidlabs.mvvmdemo.model.Group; import net.droidlabs.mvvmdemo.model.User; import net.droidlabs.mvvmdemo.viewmodel.SuperUserViewModel; import net.droidlabs.mvvmdemo.viewmodel.UserViewModel; import net.droidlabs.mvvmdemo.viewmodel.UsersViewModel; -public class UsersView extends AppCompatActivity -{ +import java.util.HashMap; + +public class UsersView extends AppCompatActivity { private UsersViewModel usersViewModel; private UsersViewBinding binding; + private boolean useCompositeBinder = false; @Nullable - private static String getStringFromEditText(EditText editText) - { + private static String getStringFromEditText(EditText editText) { Editable editable = editText.getText(); return editable == null ? null : editable.toString(); } @Override - protected void onCreate(Bundle savedInstanceState) - { + protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); usersViewModel = new UsersViewModel(); usersViewModel.users.add(new SuperUserViewModel(new User("Android", "Dev"))); @@ -48,47 +53,47 @@ protected void onCreate(Bundle savedInstanceState) binding.activityUsersRecycler.setLayoutManager(new LinearLayoutManager(this)); } - public View.OnClickListener onButtonClick() - { - return new View.OnClickListener() - { + public View.OnClickListener onButtonClick() { + return new View.OnClickListener() { @Override - public void onClick(View v) - { + public void onClick(View v) { usersViewModel.addUser(getStringFromEditText(binding.usersViewFirstname), getStringFromEditText(binding.usersViewLastname)); } }; } - public ClickHandler clickHandler() - { - return new ClickHandler() - { + public ClickHandler clickHandler() { + return new ClickHandler() { @Override - public void onClick(UserViewModel user) - { + public void onClick(UserViewModel user) { Toast.makeText(UsersView.this, user.getFirstName() + " " + user.getLastName(), Toast.LENGTH_SHORT).show(); } }; } - public LongClickHandler longClickHandler() - { - return new LongClickHandler() - { + public LongClickHandler longClickHandler() { + return new LongClickHandler() { @Override - public void onLongClick(UserViewModel user) - { + public void onLongClick(UserViewModel user) { Toast.makeText(UsersView.this, "LONG CLICK: " + user.getFirstName() + " " + user.getLastName(), Toast.LENGTH_SHORT).show(); } }; } - public ItemBinder itemViewBinder() - { - return new CompositeItemBinder( - new SuperUserBinder(BR.user, R.layout.item_super_user), - new UserBinder(BR.user, R.layout.item_user) - ); + + public ItemBinder itemViewBinder() { + if (useCompositeBinder) { + return new CompositeItemBinder<>( + new SuperUserBinder(BR.user, R.layout.item_super_user), + new UserBinder(BR.user, R.layout.item_user) + ); + } else { + + return new ItemBinderBase<>(BR.user, R.layout.item_user, new HashMap() { + { + put(BR.group, new Group("TestGroup", "1")); + } + }); + } } } diff --git a/app/src/main/res/layout/item_super_user.xml b/app/src/main/res/layout/item_super_user.xml index adf6b77..3d75e42 100644 --- a/app/src/main/res/layout/item_super_user.xml +++ b/app/src/main/res/layout/item_super_user.xml @@ -1,37 +1,37 @@ - + + type="net.droidlabs.mvvmdemo.viewmodel.SuperUserViewModel" /> + - + android:orientation="horizontal"> + + + tools:text="Hello" /> + tools:text="World" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_user.xml b/app/src/main/res/layout/item_user.xml index b27d762..1be4858 100644 --- a/app/src/main/res/layout/item_user.xml +++ b/app/src/main/res/layout/item_user.xml @@ -7,6 +7,11 @@ + + + + + extends RecyclerView.Adapter implements View.OnClickListener, View.OnLongClickListener -{ +public class BindingRecyclerViewAdapter extends RecyclerView.Adapter implements View.OnClickListener, View.OnLongClickListener { private static final int ITEM_MODEL = -124; private final WeakReferenceOnListChangedCallback onListChangedCallback; private final ItemBinder itemBinder; @@ -24,63 +25,49 @@ public class BindingRecyclerViewAdapter extends RecyclerView.Adapter clickHandler; private LongClickHandler longClickHandler; - public BindingRecyclerViewAdapter(ItemBinder itemBinder, @Nullable Collection items) - { + public BindingRecyclerViewAdapter(ItemBinder itemBinder, @Nullable Collection items) { this.itemBinder = itemBinder; this.onListChangedCallback = new WeakReferenceOnListChangedCallback<>(this); setItems(items); } - public ObservableList getItems() - { + public ObservableList getItems() { return items; } - public void setItems(@Nullable Collection items) - { - if (this.items == items) - { + public void setItems(@Nullable Collection items) { + if (this.items == items) { return; } - if (this.items != null) - { + if (this.items != null) { this.items.removeOnListChangedCallback(onListChangedCallback); notifyItemRangeRemoved(0, this.items.size()); } - if (items instanceof ObservableList) - { + if (items instanceof ObservableList) { this.items = (ObservableList) items; notifyItemRangeInserted(0, this.items.size()); this.items.addOnListChangedCallback(onListChangedCallback); - } - else if (items != null) - { + } else if (items != null) { this.items = new ObservableArrayList<>(); this.items.addOnListChangedCallback(onListChangedCallback); this.items.addAll(items); - } - else - { + } else { this.items = null; } } @Override - public void onDetachedFromRecyclerView(RecyclerView recyclerView) - { - if (items != null) - { + public void onDetachedFromRecyclerView(RecyclerView recyclerView) { + if (items != null) { items.removeOnListChangedCallback(onListChangedCallback); } } @Override - public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int layoutId) - { - if (inflater == null) - { + public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int layoutId) { + if (inflater == null) { inflater = LayoutInflater.from(viewGroup.getContext()); } @@ -89,43 +76,42 @@ public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int layoutId) } @Override - public void onBindViewHolder(ViewHolder viewHolder, int position) - { + public void onBindViewHolder(ViewHolder viewHolder, int position) { final T item = items.get(position); viewHolder.binding.setVariable(itemBinder.getBindingVariable(item), item); viewHolder.binding.getRoot().setTag(ITEM_MODEL, item); viewHolder.binding.getRoot().setOnClickListener(this); viewHolder.binding.getRoot().setOnLongClickListener(this); + if (itemBinder.getBindings() != null) { + for (Map.Entry entry : itemBinder.getBindings().entrySet()) { + viewHolder.binding.setVariable(entry.getKey(), entry.getValue()); + } + } + viewHolder.binding.executePendingBindings(); } @Override - public int getItemViewType(int position) - { + public int getItemViewType(int position) { return itemBinder.getLayoutRes(items.get(position)); } @Override - public int getItemCount() - { + public int getItemCount() { return items == null ? 0 : items.size(); } @Override - public void onClick(View v) - { - if (clickHandler != null) - { + public void onClick(View v) { + if (clickHandler != null) { T item = (T) v.getTag(ITEM_MODEL); clickHandler.onClick(item); } } @Override - public boolean onLongClick(View v) - { - if (longClickHandler != null) - { + public boolean onLongClick(View v) { + if (longClickHandler != null) { T item = (T) v.getTag(ITEM_MODEL); longClickHandler.onLongClick(item); return true; @@ -133,85 +119,69 @@ public boolean onLongClick(View v) return false; } - public static class ViewHolder extends RecyclerView.ViewHolder - { + public static class ViewHolder extends RecyclerView.ViewHolder { final ViewDataBinding binding; - ViewHolder(ViewDataBinding binding) - { + ViewHolder(ViewDataBinding binding) { super(binding.getRoot()); this.binding = binding; } } - private static class WeakReferenceOnListChangedCallback extends ObservableList.OnListChangedCallback - { + private static class WeakReferenceOnListChangedCallback extends ObservableList.OnListChangedCallback { private final WeakReference> adapterReference; - public WeakReferenceOnListChangedCallback(BindingRecyclerViewAdapter bindingRecyclerViewAdapter) - { + public WeakReferenceOnListChangedCallback(BindingRecyclerViewAdapter bindingRecyclerViewAdapter) { this.adapterReference = new WeakReference<>(bindingRecyclerViewAdapter); } @Override - public void onChanged(ObservableList sender) - { + public void onChanged(ObservableList sender) { RecyclerView.Adapter adapter = adapterReference.get(); - if (adapter != null) - { + if (adapter != null) { adapter.notifyDataSetChanged(); } } @Override - public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) - { + public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) { RecyclerView.Adapter adapter = adapterReference.get(); - if (adapter != null) - { + if (adapter != null) { adapter.notifyItemRangeChanged(positionStart, itemCount); } } @Override - public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) - { + public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) { RecyclerView.Adapter adapter = adapterReference.get(); - if (adapter != null) - { + if (adapter != null) { adapter.notifyItemRangeInserted(positionStart, itemCount); } } @Override - public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) - { + public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) { RecyclerView.Adapter adapter = adapterReference.get(); - if (adapter != null) - { + if (adapter != null) { adapter.notifyItemMoved(fromPosition, toPosition); } } @Override - public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) - { + public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) { RecyclerView.Adapter adapter = adapterReference.get(); - if (adapter != null) - { + if (adapter != null) { adapter.notifyItemRangeRemoved(positionStart, itemCount); } } } - public void setClickHandler(ClickHandler clickHandler) - { + public void setClickHandler(ClickHandler clickHandler) { this.clickHandler = clickHandler; } - public void setLongClickHandler(LongClickHandler clickHandler) - { + public void setLongClickHandler(LongClickHandler clickHandler) { this.longClickHandler = clickHandler; } } \ No newline at end of file diff --git a/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/CompositeItemBinder.java b/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/CompositeItemBinder.java index 7324e54..6c4afaa 100644 --- a/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/CompositeItemBinder.java +++ b/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/CompositeItemBinder.java @@ -1,22 +1,19 @@ package net.droidlabs.mvvm.recyclerview.adapter.binder; -public class CompositeItemBinder implements ItemBinder -{ +import java.util.Map; + +public class CompositeItemBinder implements ItemBinder { private final ConditionalDataBinder[] conditionalDataBinders; - public CompositeItemBinder(ConditionalDataBinder... conditionalDataBinders) - { + public CompositeItemBinder(ConditionalDataBinder... conditionalDataBinders) { this.conditionalDataBinders = conditionalDataBinders; } @Override - public int getLayoutRes(T model) - { - for (int i = 0; i < conditionalDataBinders.length; i++) - { + public int getLayoutRes(T model) { + for (int i = 0; i < conditionalDataBinders.length; i++) { ConditionalDataBinder dataBinder = conditionalDataBinders[i]; - if (dataBinder.canHandle(model)) - { + if (dataBinder.canHandle(model)) { return dataBinder.getLayoutRes(model); } } @@ -25,17 +22,21 @@ public int getLayoutRes(T model) } @Override - public int getBindingVariable(T model) - { - for (int i = 0; i < conditionalDataBinders.length; i++) - { + public int getBindingVariable(T model) { + for (int i = 0; i < conditionalDataBinders.length; i++) { ConditionalDataBinder dataBinder = conditionalDataBinders[i]; - if (dataBinder.canHandle(model)) - { + if (dataBinder.canHandle(model)) { return dataBinder.getBindingVariable(model); } } throw new IllegalStateException(); } + + @Override public Map getBindings() { + ConditionalDataBinder dataBinder = conditionalDataBinders[0]; + return dataBinder.getBindings(); + } + + } diff --git a/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ConditionalDataBinder.java b/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ConditionalDataBinder.java index c46cdfc..0d0f204 100644 --- a/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ConditionalDataBinder.java +++ b/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ConditionalDataBinder.java @@ -1,16 +1,15 @@ package net.droidlabs.mvvm.recyclerview.adapter.binder; -public abstract class ConditionalDataBinder extends ItemBinderBase -{ - public ConditionalDataBinder(int bindingVariable, int layoutId) - { - super(bindingVariable, layoutId); +import java.util.Map; + +public abstract class ConditionalDataBinder extends ItemBinderBase { + public ConditionalDataBinder(int bindingVariable, int layoutId, Map bindings) { + super(bindingVariable, layoutId, bindings); } public abstract boolean canHandle(T model); - public boolean canHandle(int layoutId) - { + public boolean canHandle(int layoutId) { return this.layoutId == layoutId; } } diff --git a/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ItemBinder.java b/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ItemBinder.java index f689d9e..8fc9bed 100644 --- a/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ItemBinder.java +++ b/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ItemBinder.java @@ -1,7 +1,15 @@ package net.droidlabs.mvvm.recyclerview.adapter.binder; +import java.util.Map; + public interface ItemBinder { int getLayoutRes(T model); int getBindingVariable(T model); + /** + * used to define your own bindings + * @return Map + */ + Map getBindings(); + } diff --git a/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ItemBinderBase.java b/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ItemBinderBase.java index d15dc77..432b2d6 100644 --- a/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ItemBinderBase.java +++ b/recyclerview-binding/src/main/java/net/droidlabs/mvvm/recyclerview/adapter/binder/ItemBinderBase.java @@ -1,23 +1,32 @@ package net.droidlabs.mvvm.recyclerview.adapter.binder; -public class ItemBinderBase implements ItemBinder -{ - protected final int bindingVariable; - protected final int layoutId; +import android.support.annotation.Nullable; + +import java.util.Map; + +public class ItemBinderBase implements ItemBinder { + final int bindingVariable; + final int layoutId; + final Map bindings; + + public ItemBinderBase(int bindingVariable, int layoutId, @Nullable Map bindings) { - public ItemBinderBase(int bindingVariable, int layoutId) - { this.bindingVariable = bindingVariable; this.layoutId = layoutId; + this.bindings = bindings; } - public int getLayoutRes(T model) - { + public int getLayoutRes(T model) { return layoutId; } - public int getBindingVariable(T model) - { + public int getBindingVariable(T model) { return bindingVariable; } + + @Override public Map getBindings() { + return bindings; + } + + }