數據中介者:DataMediator, (ButterKnife最佳拍檔)

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.java

小結

經常使用的屬性綁定都已實現, 想要實現自定義。 使用自定義Binder和BinderFactory便可。
Adapter數據綁定支持對item的 ‘增刪改查-即CRUD’, 支持header, footer.
固然這個框架的能力遠不止此。只要你仔細看項目的示例程序,更多驚喜等着你。
通過1.4.1版本後, 它的數據綁定 能夠完美搭配ButterKnife了。git

地址: github.com/LightSun/da….github

相關文章
相關標籤/搜索