Databinding打造RecyclerView万能适配器

Databinding打造RecyclerView万能适配器_第1张图片

这是最终效果图,用到了两种布局,Listview和Gridview形式的布局,其中垂直布局中显示了不同类型的item。下面示范如何使用,首先BaseRecyleAdapter如下:

public class BaseRecyleAdapter extends RecyclerView.Adapter {
    public List data;//用?代表所有所有类型
    Map hashMap;

    public BaseRecyleAdapter(List data, Map hashMap) {
        this.data = data;
        this.hashMap = hashMap;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater from = LayoutInflater.from(parent.getContext());
        ViewDataBinding inflate = DataBindingUtil.inflate(from, viewType, parent, false);//引入布局
        return new ViewHolder(inflate);
    }

    /**
     * map可以入参多个,也就是添加多布局,至少需要传一个,map中的key代表布局id,value对应布局中实体类的BR id
     *默认取第一个,也就是把布局id取出来
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        Set integers = hashMap.keySet();
        return integers.iterator().next();
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        Integer varid = hashMap.get(getItemViewType(position));
        holder.dataBinding.setVariable(varid, data.get(position));//varid表示的是布局中数据名称对应的BR

        if (onRecycleitemOnClic != null)//这里是实现item点击
            holder.dataBinding.getRoot().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    onRecycleitemOnClic.onItemClic(view, position);//开放接口
                }
            });
    }

    public OnRecycleitemOnClic getOnRecycleitemOnClic() {
        return onRecycleitemOnClic;
    }

    public void setOnRecycleitemOnClic(OnRecycleitemOnClic onRecycleitemOnClic) {
        this.onRecycleitemOnClic = onRecycleitemOnClic;
    }

    OnRecycleitemOnClic onRecycleitemOnClic;

    public interface OnRecycleitemOnClic {
        void onItemClic(View view, int position);
    }

    @Override
    public int getItemCount() {
        if (data == null)
            return 0;
        return data.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        ViewDataBinding dataBinding;

        public ViewHolder(ViewDataBinding itemView) {
            super(itemView.getRoot());
            this.dataBinding = itemView;
        }
    }
}
我们在activity_main中写的布局如下:




    

    

    

        
        

        
        
    
上面data里面的class是我们定义的类名,这个类是databinding自己创建的“隐形”类(不直接显示在文件夹中,但存在),我们这里定义了两个recyclerview,水平和垂直的,这里不用一个Recyclerview是因为嵌套本身也会增加代码的耦合性,如果内容非常丰富多样的话以后改起来麻烦。  

下面是MainActivity:

public class MainActivity extends FragmentActivity {

    private MainData mainData;
    private TestListItemAdapter mainAdapter;
    public BaseRecyleAdapter mainGridAdapter;
    private List userInfo;
    private LinearLayoutManager linearLayoutManager;
    private GridLayoutManager gridLayoutManager;//gridview类型的布局

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initdatabinding();
    }

    private void initdatabinding() {
        mainData = DataBindingUtil.setContentView(this, R.layout.activity_main);
        linearLayoutManager = new LinearLayoutManager(this);//不设置方向默认是垂直
        mainData.rvMain.setLayoutManager(linearLayoutManager);

        userInfo = new ArrayList<>();//初始化的操作放在set之前
        setUserInfo();
        /**
         * 这里用TestListItemAdapter是因为adapter里面需要写不同类型的item或者需要自己单独去设置某控件的值
         * 如果是相同类型的,比如下面的gridLayoutManager就直接用BaseRecyleAdapter
         * 这里的BR是dataBinding自动生成的,我们在布局中写好变量,用“BR.变量名”就能得到
         */
        Map map = new HashMap<>();
        map.put(R.layout.item_main, BR.info);
        map.put(R.layout.item_main_diverse, BR.info2);
        mainAdapter = new TestListItemAdapter(userInfo, map);
        mainData.rvMain.setAdapter(mainAdapter);

        /**
         * 加载Grid类型的,这里设置3行
         */
        gridLayoutManager = new GridLayoutManager(this, 3);
        mainData.rvMainGrid.setLayoutManager(gridLayoutManager);

        Map gridMap = new HashMap<>();
        gridMap.put(R.layout.item_main_grid, BR.gridinfo);
        mainGridAdapter = new BaseRecyleAdapter(userInfo, gridMap);
        mainData.rvMainGrid.setAdapter(mainGridAdapter);
    }

    private void setUserInfo() {
        for (int i = 0; i < 5; i++) {
            UserInfo userInfo = new UserInfo();
            userInfo.setTitle("以梦为马,诗酒趁年华" + i);
            userInfo.setName(" ");
            userInfo.setCover("http://jyts-public-oss.longruncloud.com/images/4ee98d67ccf5e5d33db6eba5046e1e289eb8d787f7888aab69280e169b4556c5.jpg");
            userInfo.setAge("年龄:" + String.valueOf(i));
            this.userInfo.add(userInfo);
        }
    }
}

注释已经很详细,就不赘述了,其中用到了实体类是自己写的,如果是服务端给的接口也是一样用的。Bean代码贴出来:

public class UserInfo {

    private String cover;
    private String title;
    private String name;
    private String age;
  
    public String getCover() {
        return cover;
    }

    public void setCover(String cover) {
        this.cover = cover;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}
因为我们垂直布局中需要自己写前面的序号,还有需要自己设置不同类型的item,所以我们需要写自己的Adapter集成BaseRecyleAdapter,重写里面的方法进行设置,就是MainActivity中用到的TestListItemAdapter。

public class TestListItemAdapter extends BaseRecyleAdapter {
    public TestListItemAdapter(List data, Map hashMap) {
        super(data, hashMap);
    }

    /**
     * 如果有值不是从bean类里面获取的,需要自己去设置的话就重写此方法
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        super.onBindViewHolder(holder, position);
        int i = position + 1;
        String text = i >= 10 ? String.valueOf(i) : String.valueOf("0" + i);
        holder.dataBinding.setVariable(BR.itemNum, text);//这里就是设置前面的序号
    }
    /**
     * 编写规则,返回相应布局,比如这里是第四个item加载其他布局
     *
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        if (position == 3)
            return R.layout.item_main_diverse;
        else
            return R.layout.item_main;
    }
}
其中需要注意的是在布局中设置图片的话和文字有些不同,我们需要自己实现:

public class ImagBindingUtils {

    @BindingAdapter("imgurl")
    public static void bindingImage(ImageView imageView, String url) {
        Glide.with(imageView.getContext()).load(url).into(imageView);//用的glide加载,在build.gradle中添加依赖就能使用
    }
}
用到的layout我只贴一种,因为其他的都是一样的,我这里只是做了item颜色修改:




    
        

        
    

    

        

        

        

        

        
    

UserInfo是我们自己创建的Bean类,我们把全类名引入进来,创建了info2的变量,在textview中通过@{info2.}来使用,具体就是这样,如果需要设置item点击事件的话,在自己建的Apater类里实现BaseRecyleAdapter.OnRecycleitemOnClic,然后再构造器里面添加setOnRecycleitemOnClic(this),最后在实现的onItemClic方法中写我们需要进行的操作即可,具体的使用如下:

public class ListenerBookRankAdapter extends BaseRecyleAdapter implements BaseRecyleAdapter.OnRecycleitemOnClic {
    private List booksBeanDes;

    public ListenerBookRankAdapter(List data, Map hashMap) {
        super(data, hashMap);
        this.booksBeanDes = (List) data;
        setOnRecycleitemOnClic(this);//2.设置item点击,Base中已写好
    }
    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        super.onBindViewHolder(holder, position);
        int i = position + 1;
        String text = i >= 10 ? String.valueOf(i) : String.valueOf("0" + i);
        holder.dataBinding.setVariable(BR.itemtestnum, text);
    }

    @Override
    public void onItemClic(View view, int position) {//3.重写方法
        int id = booksBeanDes.get(position).getBook().getId();
        Intent intent = new Intent();
        intent.putExtra("ID", id);
        intent.setClass(view.getContext(), BookRankDetailsActivity.class);
        view.getContext().startActivity(intent);
    }
}
使用过程就是这些,如有问题可以留言,希望可以互相学习,Demo链接是http://download.csdn.net/download/xkyh941/10149648,发现Adapter文件夹里面手抖多建了个新建文件夹,我就不重新上传了,联系管理员麻烦,不会影响使用。

你可能感兴趣的:(android)