4-多布局.md 9.1 KB
Newer Older
limuyang2's avatar
limuyang2 已提交
1 2 3 4 5 6 7 8
# 多布局

对于多布局,提供了:

`BaseMultiItemQuickAdapter``BaseDelegateMultiAdapter``BaseProviderMultiAdapter`

三种基础类型。

limuyang2's avatar
limuyang2 已提交
9
## 1、BaseMultiItemQuickAdapter
limuyang2's avatar
limuyang2 已提交
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
说明:适用于类型较少,业务不复杂的场景,便于快速使用。

所有的数据类型,都必须实现`MultiItemEntity`接口(注意,这里不是继承抽象类,而是实现接口,避免对业务的实体类带来影响)
```java
public class MultipleItemQuickAdapter extends BaseMultiItemQuickAdapter<QuickMultipleEntity, BaseViewHolder> {

    public MultipleItemQuickAdapter(List<QuickMultipleEntity> data) {
        super(data);
        // 绑定 layout 对应的 type
        addItemType(QuickMultipleEntity.TEXT, R.layout.item_text_view);
        addItemType(QuickMultipleEntity.IMG, R.layout.item_image_view);
        addItemType(QuickMultipleEntity.IMG_TEXT, R.layout.item_img_text_view);
    }

    @Override
    protected void convert(@NonNull BaseViewHolder helper, QuickMultipleEntity item) {
        // 根据返回的 type 分别设置数据
        switch (helper.getItemViewType()) {
            case QuickMultipleEntity.TEXT:
                helper.setText(R.id.tv, item.getContent());
                break;
            case QuickMultipleEntity.IMG_TEXT:
                ...
                ...
                break;
            default:
                break;
        }
    }
}
```

数据实体类写法:

```java
class 你的数据实体类 implements MultiItemEntity {
  
  // 你的数据内容
  ...
  ...
  
  /**
   * 实现此方法,返回类型
   */
  @Override
    public int getItemType() {
        return itemType;
    }
}
```



limuyang2's avatar
limuyang2 已提交
63
## 2、BaseDelegateMultiAdapter
limuyang2's avatar
limuyang2 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105

说明:通过代理类的方式,返回布局 id 和 item 类型;

适用于:
1、实体类不方便扩展,此Adapter的数据类型**可以是任意类型**,只需要在`BaseMultiTypeDelegate.getItemType`中返回对应类型
2、item 类型较少
如果类型较多,为了方便隔离各类型的业务逻辑,推荐使用`BaseProviderMultiAdapter`

### 方式一:

```java
public class DelegateMultiAdapter extends BaseDelegateMultiAdapter<DelegateMultiEntity, BaseViewHolder> {

    public DelegateMultiAdapter() {
        super();
        
        // 第一步,设置代理
        setMultiTypeDelegate(new BaseMultiTypeDelegate<DelegateMultiEntity>() {
            @Override
            public int getItemType(@NotNull List<? extends DelegateMultiEntity> data, int position) {
                // 根据数据,自己判断应该返回的类型
                switch (position % 3) {
                    case 0:
                        return DelegateMultiEntity.TEXT;
                    case 1:
                        return DelegateMultiEntity.IMG;
                    case 2:
                        return DelegateMultiEntity.IMG_TEXT;
                    default:
                        break;
                }
                return 0;
            }
        });
        // 第二部,绑定 item 类型
        getMultiTypeDelegate()
                .addItemType(DelegateMultiEntity.TEXT, R.layout.item_text_view)
                .addItemType(DelegateMultiEntity.IMG, R.layout.item_image_view)
                .addItemType(DelegateMultiEntity.IMG_TEXT, R.layout.item_img_text_view);
    }

    @Override
limuyang2's avatar
limuyang2 已提交
106
    protected void convert(@NotNull BaseViewHolder helper, @NotNull DelegateMultiEntity item) {
limuyang2's avatar
limuyang2 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
        switch (helper.getItemViewType()) {
            case QuickMultipleEntity.TEXT:
                helper.setText(R.id.tv, "CymChad " + helper.getAdapterPosition());
                break;
            case QuickMultipleEntity.IMG_TEXT:
                switch (helper.getLayoutPosition() % 2) {
                    case 0:
                        helper.setImageResource(R.id.iv, R.mipmap.animation_img1);
                        break;
                    case 1:
                        helper.setImageResource(R.id.iv, R.mipmap.animation_img2);
                        break;
                    default:
                        break;
                }
                helper.setText(R.id.tv, "ChayChan " + helper.getAdapterPosition());
                break;
            default:
                break;
        }
    }
}
```

### 方式二:

```java
public class DelegateMultiAdapter extends BaseDelegateMultiAdapter<DelegateMultiEntity, BaseViewHolder> {

    public DelegateMultiAdapter() {
        super();

        // 实现自己的代理类:
        setMultiTypeDelegate(new MyMultiTypeDelegate());
    }

    @Override
limuyang2's avatar
limuyang2 已提交
144
    protected void convert(@NotNull BaseViewHolder helper, @NotNull DelegateMultiEntity item) {
limuyang2's avatar
limuyang2 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
        switch (helper.getItemViewType()) {
            case QuickMultipleEntity.TEXT:
                helper.setText(R.id.tv, "CymChad " + helper.getAdapterPosition());
                break;
            case QuickMultipleEntity.IMG_TEXT:
                switch (helper.getLayoutPosition() % 2) {
                    case 0:
                        helper.setImageResource(R.id.iv, R.mipmap.animation_img1);
                        break;
                    case 1:
                        helper.setImageResource(R.id.iv, R.mipmap.animation_img2);
                        break;
                    default:
                        break;
                }
                helper.setText(R.id.tv, "ChayChan " + helper.getAdapterPosition());
                break;
            default:
                break;
        }
    }

    // 方式二:实现自己的代理类
    final static class MyMultiTypeDelegate extends BaseMultiTypeDelegate<DelegateMultiEntity> {

        public MyMultiTypeDelegate() {
limuyang2's avatar
limuyang2 已提交
171
            // 绑定 item 类型
limuyang2's avatar
limuyang2 已提交
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
            addItemType(DelegateMultiEntity.TEXT, R.layout.item_text_view);
            addItemType(DelegateMultiEntity.IMG, R.layout.item_image_view);
            addItemType(DelegateMultiEntity.IMG_TEXT, R.layout.item_img_text_view);
        }

        @Override
        public int getItemType(@NotNull List<? extends DelegateMultiEntity> data, int position) {
            switch (position % 3) {
                case 0:
                    return DelegateMultiEntity.TEXT;
                case 1:
                    return DelegateMultiEntity.IMG;
                case 2:
                    return DelegateMultiEntity.IMG_TEXT;
                default:
                    break;
            }
            return 0;
        }
    }
}
```



limuyang2's avatar
limuyang2 已提交
197
## 3、BaseProviderMultiAdapter
limuyang2's avatar
limuyang2 已提交
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239

说明:当有多种条目的时候,避免在`convert()`中做太多的业务逻辑,把逻辑放在对应的 `ItemProvider` 中。以及最大化自定义`VH`类型。

1、此`Adapter`的数据类型**可以是任意类型**,只需要在`getItemType`中返回对应类型
2、`Adapter`不限定`ViewHolder`类型。`ViewHolder``BaseItemProvider` 实现,并且每个`BaseItemProvider`可以拥有自己类型的`ViewHolder`类型。

### 第一步,`Adapter`代码如下:
```java
public class ProviderMultiAdapter extends BaseProviderMultiAdapter<ProviderMultiEntity> {

    public ProviderMultiAdapter() {
        super();
        // 注册 Provider
        addItemProvider(new ImgItemProvider());
        addItemProvider(new TextImgItemProvider());
        addItemProvider(new TextItemProvider());
    }

    /**
     * 自行根据数据、位置等信息,返回 item 类型
     */
    @Override
    protected int getItemType(@NotNull List<? extends ProviderMultiEntity> data, int position) {
        switch (position % 3) {
            case 0:
                return ProviderMultiEntity.IMG;
            case 1:
                return ProviderMultiEntity.TEXT;
            case 2:
                return ProviderMultiEntity.IMG_TEXT;
            default:
                break;
        }
        return 0;
    }
}
```

### 第二步,`Provider`代码如下:
```java
public class ImgItemProvider extends BaseItemProvider<ProviderMultiEntity> {

limuyang2's avatar
limuyang2 已提交
240
    // item 类型
limuyang2's avatar
limuyang2 已提交
241 242 243 244 245
    @Override
    public int getItemViewType() {
        return ProviderMultiEntity.IMG;
    }

limuyang2's avatar
limuyang2 已提交
246
    // 返回 item 布局 layout
limuyang2's avatar
limuyang2 已提交
247 248 249 250 251
    @Override
    public int getLayoutId() {
        return R.layout.item_image_view;
    }
  
limuyang2's avatar
limuyang2 已提交
252 253 254 255 256
    /*
     * (可选)
     * 重写返回自己的 ViewHolder。
     * 默认返回 BaseViewHolder()
     */
limuyang2's avatar
limuyang2 已提交
257 258 259 260 261 262 263
    @NotNull
    @Override
    public BaseViewHolder onCreateViewHolder(@NotNull ViewGroup parent) {
        return super.onCreateViewHolder(parent);
    }

    @Override
limuyang2's avatar
limuyang2 已提交
264
    public void convert(@NotNull BaseViewHolder helper, @NotNull ProviderMultiEntity data) {
limuyang2's avatar
limuyang2 已提交
265
        // 设置 item 数据
limuyang2's avatar
limuyang2 已提交
266 267 268 269 270 271
        if (helper.getAdapterPosition() % 2 == 0) {
            helper.setImageResource(R.id.iv, R.mipmap.animation_img1);
        } else {
            helper.setImageResource(R.id.iv, R.mipmap.animation_img2);
        }
    }
limuyang2's avatar
limuyang2 已提交
272 273
 
    // 点击 item 事件
limuyang2's avatar
limuyang2 已提交
274
    @Override
limuyang2's avatar
limuyang2 已提交
275
    public void onClick(@NotNull BaseViewHolder helper, @NotNull View view, ProviderMultiEntity data, int position) {
limuyang2's avatar
limuyang2 已提交
276 277 278 279 280 281 282 283 284 285 286
        Tips.show("Click: " + position);
    }

    @Override
    public boolean onLongClick(@NotNull BaseViewHolder helper, @NotNull View view, ProviderMultiEntity data, int position) {
        Tips.show("Long Click: " + position);
        return true;
    }
}
```