Android进阶Android开发程序员

Android Databinding对adapter(Recy

2017-10-18  本文已影响114人  闲庭

作为一个android 开发者,心里似乎对RecyclerView又爱又恨,爱的是它对列表数据处理功能够强大,恨得是要写adapter 和 viewholder ,虽然说写adapter 和 viewholder倒不是难,而是烦,千遍一率的相似代码,对于程序员来说,重复是最令人讨厌的。所以这才有这么多仁人志士,前俯后继地进行通用型,万能型 adapter 的抽象。即便已经有好多的通用性、万能型adapter适配器,但是我在这里还是要讲下Databinding对adapter(RecyclerView)适配器基类封装。

DataBinding的核心理念是数据驱动。数据驱动驱动的目标就是View,使用DataBinding,我们通过添加、修改、删除数据源,View就会自动予以相关变化,达到一种双向绑定的效果。也就是说Databinding出现的意义就在于系统自动帮助我们生成Data和View之间的connection.而在Adapter中出现的ViewHolder就是我们手动生成的connection,下面我们就来看看databinding如何精简对应的adapter。

  1. 下面先看看一个简单的RecyclerView Adapter代码:
public class UserAdapter extends RecyclerView.Adapter
    {
        @Override
        public int getItemCount()
        {
            return 0;
        }
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
            return null;
        }
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
    
        }
    }

可以看到,Adapter起的作用和DataBinding是非常类似的,使用DataBinding,可以使Adapter的编写显得更加简单。

  1. 下面看看使用DataBinding编写的adapter:

adapter基础类:

public abstract class RecyclerAdapter<T, B extends ViewDataBinding> extends RecyclerView.Adapter {

    protected Context mContext;
    protected List<T> mList;

    public RecyclerAdapter(Context context) {
        this.mContext = context;
    }

    public RecyclerAdapter(Context context, List<T> list) {
        this.mContext = context;
        this.mList = list;
    }
    @Override
    public int getItemCount() {
        return mList == null ? 0 : mList.size();
    }

    public void refreshData(List<T> list){
        if (mList == null){
            mList = new ArrayList<>();
        }
        mList.addAll(list);
        notifyDataSetChanged();
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        B bing = DataBindingUtil.inflate(LayoutInflater.from(mContext), getLayoutResId(viewType), parent, false);
        return new RecyclerHolder(bing.getRoot());
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        B binding = DataBindingUtil.getBinding(holder.itemView);
        final T t = mList.get(position);
        onBindItem(binding, t, position);
    }

    protected abstract @LayoutRes int getLayoutResId(int viewType);

    protected abstract void onBindItem(B binding, T t, int position);

    static class RecyclerHolder extends RecyclerView.ViewHolder {

        public RecyclerHolder(View itemView) {
            super(itemView);
        }
    }

}

后续RecyclerView的adapter继承基类即可:

public class UserAdapter extends RecyclerAdapter<User,ItemUserBinding>{
    public TakePhotoAdapter(Activity context) {
        super(context);
    }

    @Override
    protected int getLayoutResId(int viewType) {
        return R.layout.item_user;
    }

    @Override
    protected void onBindItem(final ItemUserBinding binding,
                              final User user,
                              final int position) {
        binding.setUserInfo(user);
        binding.executePendingBindings();
        binding.ivTakePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ToastUitl.showShort("点击了"+user.getName()+position);
            }
        });
    }
}

此处处理item的一些click事件或者其他事件直接写到adapter里面去,但是考虑到adapter还是比较纯粹的处理view和data的关系,所以把事件的处理通过接口回调到activity层。代码如下:

@FunctionalInterface
public interface BindingItemListen<T, B extends ViewDataBinding> {
    void onItemClick(B binding, T t, int i);
}



public class UserAdapter extends RecyclerAdapter<User,ItemUserBinding>{
    private BindingItemListen  itemListen;
    public TakePhotoAdapter(Activity context,
            BindingItemListen<User,ItemUserBinding> itemListen) {
        super(context);
        this.itemListen = itemListen;
    }

    @Override
    protected int getLayoutResId(int viewType) {
        return R.layout.item_user;
    }

    @Override
    protected void onBindItem(final ItemUserBinding binding,
                              final User user,
                              final int position) {
        binding.setUserInfo(user);
        binding.executePendingBindings();
        binding.ivTakePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ToastUitl.showShort("点击了"+user.getName()+position);
                itemListen.onItemClick(binding,user,position);
            }
        });
    }
}

此时在activity中的应用:

recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new UserAdapter(this, new BindingItemListen<User, ItemUserBinding>() {
    @Override
    public void onItemClick(ItemUserBinding binding, User user, int i) {

    }
});
recyclerView.setAdapter(adapter);
//此时应从网络/本地获取数据userList
adapter.refreshData(userList);
上一篇下一篇

猜你喜欢

热点阅读