View基本屬性繫結
/**
* test data-binding of view: setBackground, setBackgroundColor,setBackgroundResource.setEnable . etc.
* Created by heaven7 on 2017/9/24.
*/
public class TestViewBindActivity extends BaseActivity {
@BindView(R.id.v_enable)@BindEnable("enable")
View mV_enable;
@BindView(R.id.v_bg) @BindBackground("background")
View mV_bg;
@BindView(R.id.v_bg_color)@BindBackgroundColor("backgroundColor")
View mV_bg_color;
@BindView(R.id.v_bg_res)@BindBackgroundRes("backgroundRes")
View mV_bg_res;
@BindView(R.id.v_visibility)@BindVisibility("visible")
View mV_visibility;
private ResHelper mHelper = new ResHelper();
private Binder<ViewBind> binder;
@Override
protected int getLayoutId() {
return R.layout.ac_test_view_bind;
}
@Override
protected void onInit(Context context, Bundle savedInstanceState) {
mHelper.init(context);
final ViewBind data = DataMediatorFactory.createData(ViewBind.class);
//bind data.
binder = DataMediatorFactory.bind(this, data);
}
@OnClick(R.id.bt_change_bg)
public void onClickChangeBg(View v){
//改變背景(drawable)
binder.getDataProxy().setBackground(mHelper.toggleDrawable());
}
@OnClick(R.id.bt_change_bg_color)
public void onClickChangeBgColor(View v){
//改變背景(color)
binder.getDataProxy().setBackgroundColor(mHelper.toggleColor());
}
@OnClick(R.id.bt_change_bg_res)
public void onClickChangeBgRes(View v){
//改變背景(resource id)
binder.getDataProxy().setBackgroundRes(mHelper.toggleRes());
}
@OnClick(R.id.bt_change_enable)
public void onClickChangeEnable(View v){
//改變enable 狀態
binder.getDataProxy().setEnable(!binder.getData().isEnable());
}
@OnClick(R.id.bt_change_visibility)
public void onClickChangeVisibility(View v){
binder.getDataProxy().setVisible(!binder.getDataProxy().isVisible());
}
@Override
protected void onDestroy() {
binder.unbindAll();
super.onDestroy();
}
}複製程式碼
下面是 adapter繫結資料.
/**
* test data-binding in adapter. 所有的@BindView是用的 butterKnife。
* Created by heaven7 on 2017/11/9 0009.
*/
public class TestDatabindingAdapter extends BaseActivity {
private static final String TAG = "TD adapter";
private static final Random sRan = new Random();
@BindView(R.id.rv)
RecyclerView mRv;
protected InternalAdapter mAdapter;
@Override
protected int getLayoutId() {
return R.layout.ac_test_databinding_adapter;
}
@Override
protected void onInit(Context context, Bundle savedInstanceState) {
mRv.setLayoutManager(new LinearLayoutManager(context));
mRv.setAdapter(mAdapter = new InternalAdapter(createItems()));
}
//random remove item
@OnClick(R.id.bt_remove)
public void onClickRemove(View v){
AdapterItemManager<Student> manager = mAdapter.getItemManager();
int itemCount = manager.getItemSize();
final int index = new Random().nextInt(itemCount - 1);
Logger.i(TAG, "onClickRemove","index = " + index);
manager.removeItemAt(index);
}
@OnClick(R.id.bt_add)
public void onClickAdd(View v){
AdapterItemManager<Student> manager = mAdapter.getItemManager();
int itemCount = manager.getItemSize();
final int index = new Random().nextInt(itemCount - 1);
Logger.i(TAG, "onClickAdd","index = " + index);
manager.addItem(index, createItem().setAge(1));
}
public static List<Student> createItems() {
sIndex = 0;
List<Student> list = new ArrayList<>();
//just mock data
final int count = 20;
for (int i =0 ; i< count ; i++){
list.add(createItem());
}
return list;
}
public static Student createItem(){
Student data = DataMediatorFactory.createData(Student.class);
data.setAge(sIndex ++ );
data.setName("google__" + sRan.nextInt(100));
return data;
}
private static int sIndex = 0;
public static class InternalAdapter extends DataBindingRecyclerAdapter<Student> {
public InternalAdapter(List<Student> mDatas) {
super(mDatas, true);
}
@Override
public DataBindingViewHolder<Student> onCreateViewHolderImpl(ViewGroup parent, int layoutId) {
return new InnerViewHolder(LayoutInflater.from(parent.getContext())
.inflate(layoutId, parent, false));
}
@Override
protected int getItemLayoutId(int position, Student student) {
return R.layout.item_test_recycler_list;
}
}
public static class InnerViewHolder extends DataBindingRecyclerAdapter.DataBindingViewHolder<Student>{
@BindView(R.id.tv_name) @BindText("name")
TextView mTv_name;
@BindView(R.id.tv_age) @BindText("age")
TextView mTv_age;
public InnerViewHolder(View itemView) {
super(itemView);
}
@Override
protected void onPreCreateDataBinding(View itemView) {
ButterKnife.bind(this, itemView);
}
@OnClick(R.id.tv_name)
public void onClickName(View v){
//here just toast
Toast.makeText(v.getContext(), "onClickName is called, pos = "
+ getAdapterPosition2(), Toast.LENGTH_SHORT).show();
}
@OnClick(R.id.tv_age)
public void onClickAge(View v){
//here just toast
Toast.makeText(v.getContext(), "onClickAge is called, pos = "
+ getAdapterPosition2(), Toast.LENGTH_SHORT).show();
}
@OnClick(R.id.bt_change_item)
public void onClickChangeItem(View v){
final int pos = getAdapterPosition2();
getDataProxy()
.setAge((int) (System.currentTimeMillis() % 99))
.setId(pos)
.setName("google+__" + pos);
//Note: no need notifyItemChanged here.
}
}
}複製程式碼
adapter繫結資料 , 用GridLayoutManger 並且新增header 示例.
/**
* data-binding adapter with header.
* Created by heaven7 on 2017/11/11.
*/
//TestDatabindingAdapter 請看上面
public class DataBindingAdapterWithHeader extends TestDatabindingAdapter {
@BindView(R.id.rv)
RecyclerView mRv;
@Override
protected int getLayoutId() {
return R.layout.ac_databinding_adapter_with_header;
}
@Override
protected void onInit(Context context, Bundle savedInstanceState) {
TestDatabindingAdapter.InternalAdapter adapter =
new TestDatabindingAdapter.InternalAdapter(createItems());
GridLayoutManager glp = RecyclerViewUtils.createGridLayoutManager(adapter, context, 2);
mRv.setLayoutManager(glp);
adapter.addHeaderView(getLayoutInflater().inflate(R.layout.header_data_binding,
mRv, false));
mRv.setAdapter(mAdapter = adapter);
}
}複製程式碼
ImageView圖片繫結.
自定義Binder.
/**
* test self Binder. this demo will show how to override binder method for data-binding.
* Created by heaven7 on 2017/11/13 0013.
*/
@BinderClass(TestSelfBinderActivity.MyBinder.class)
public class TestSelfBinderActivity extends TestImageViewBindActivity implements ImageLoader{
@Override
protected void onInit(Context context, Bundle savedInstanceState) {
mResHelper.init(context);
final ImageViewBind data = DataMediatorFactory.createData(ImageViewBind.class);
mBinder = DataMediatorFactory.createDataBinding(this)
.bind(data, new DataBinding.SimpleParameterSupplier() {
@Override
protected Object getImageLoader() {
return TestSelfBinderActivity.this;
}
}, null);
}
@Override
public void loadImage(String url,final ImageView iv) {
Glide.with(iv.getContext())
.load(url)
.into(new SimpleTarget<Drawable>(200, 200) {
@Override
public void onResourceReady(Drawable resource,
Transition<? super Drawable> transition) {
iv.setImageDrawable(resource);
}
});
}
public static class MyBinder<T> extends AndroidBinder<T>{
/**
* create binder for target data mediator. this constructor must be public .
*
* @param mMediator the target data mediator.
*/
public MyBinder(DataMediator<T> mMediator) {
super(mMediator);
}
@Override
public Binder<T> bindImageUrl(String property, Object imageView, Object imageLoader) {
if(!(imageView instanceof ImageView)){
throw new IllegalArgumentException("the view must be ImageView");
}
if(imageLoader instanceof ImageLoader){
ImageView iv = (ImageView) imageView;
Toaster.show(iv.getContext(), "start using self MyBinder with image loader.");
return bind(property, new ImageUrlBinderCallback<T>(iv, getPropertyInterceptor(),
(ImageLoader)imageLoader));
}
return super.bindImageUrl(property, imageView, imageLoader);
}
}
private static class ImageUrlBinderCallback<T> extends SimpleBinderCallback2<T> {
final ImageLoader mLoader;
public ImageUrlBinderCallback(ImageView tv, PropertyInterceptor interceptor,
ImageLoader loader) {
super(tv, interceptor);
this.mLoader = loader;
}
@Override
protected void apply(Property prop, View view, Object newValue) {
mLoader.loadImage((String) newValue, (ImageView) view);
}
}
}複製程式碼
繫結一組屬性到一個view?
use @BindsView and @BindsTextView.
小結
常用的屬性繫結都已實現, 想要實現自定義。 使用自定義Binder和BinderFactory即可。
Adapter資料繫結支援對item的 ‘增刪改查-即CRUD’, 支援header, footer.
當然這個框架的能力遠不止此。只要你仔細看專案的示例程式,更多驚喜等著你。
經過1.4.1版本後, 它的資料繫結 可以完美搭配ButterKnife了。