MCPcopy Index your code
hub / github.com/JesseWuuu/SuperAdapter

github.com/JesseWuuu/SuperAdapter @0.2.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release 0.2.0 ↗ · + Follow
152 symbols 336 edges 23 files 50 documented · 33%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

SuperAdapter

Android RecyclerView多功能集合适配器

SuperAdapter是什么

SuperAdapter 是对RecyclerView.Adapter进行封装并将许多常用功能集成之中的一个Android库。你不需要为每个列表单独去写ViewHolder后再声明控件,当构建不需要重用的列表时你甚至不需要单独创建类去继承RecyclerView.Adapter定制适配器,只要在ActivityFragment中简单写下几行代码即可实现,有效的减化了复写代码的数量。

SuperAdapter目前有哪些功能

  • 快速绑定单一布局列表
  • 简化多类型布局列表
  • 列表点击事件
  • 分页显示数据
  • 自定义列表唯一顶部Header
  • 自定义列表底部Footer
  • 上拉自动加载更多数据
  • 添加空数据提示视图

下载SuperAdapter

你需要在项目的根 build.gradle 加入如下JitPack仓库链接:

allprojects {
    repositories {
        ...     
        maven { url 'https://jitpack.io' }      
    }
}

着在你的需要依赖的Module的build.gradle加入依赖:

compile 'com.github.JesseWuuu:SuperAdapter:x.y.z'

注意:上面依赖中的 x.y.z 为版本号,目前最新的版本号为 -> 0.1.3

关于开源

如果你只是想了解如何使用它可以跳过本节。

在大学期间懵懵懂懂的听老师说了一大堆开源的意义,虽然现在也还是不太能领会其中的精神,但是这几年一路走来看过不少大神们的开源代码,也算是在其中获得不少的好处。

虽说这个工具只能算是个小玩具级别,但我还是想将它分享给志同道合的朋友们,源码中核心部分我都认真的写全了注释,希望能有同样对这个小工具感兴趣的朋友和我一起来继续完善它,要是能 Star 一下项目就更好啦哈哈哈~

接下来我将继续为这个小工具添加新的实用功能,当然如果使用过程中有问题可以添加到 Issues 中,我会经常看的。

定义与声明

如果你的列表只出现在了一个布局中并不会重复用使用,那么使用SuperAdapter时就不需要您单独创建类继承父类来定制化适配器,但是还是需要遵守一项规则:在ActivityFragment中声明SuperAdapter属性的同时需要声明您的列表数据源类型: ``` List mData; SuperAdapter mAdapter;

**如果你的列表会在多处重复使用,这时你需要将 SuperAdapter 封装成自定义的 Adapter,下面会有专门一节讲封装 SuperAdapter 需要注意的事项,此处先不提。**

## 绑定单一布局的列表
绑定单一布局列表的方法非常简单,只需要在`SuperAdapter`的构造函数中添加布局文件的`layoutId`与数据源即可。

SuperAdapter adapter = new SuperAdapter(R.layout.view_list_item_1){

@Override
public void bindView(ViewHolder itemView, DataEntity data,int position) {
    // 此处写绑定itemview中的控件逻辑
    itemView.<TextView>getView(R.id.text_1).setText(data.getTitle());
    Button button = holder.<Button>getView(R.id.button);
    button.setEnabled(entity.IsEnabled());   
}

};

我们需要在方法 `void bindView(ViewHolder itemView, DataEntity data,int position)` 中绑定列表每个条目中的控件并进行逻辑处理。其中方法参数`ViewHolder itemView` 为自定义 `ViewHolder`。

### 通用ViewHolder
为方便管理,SuperAdapter 中持有的 ViewHolder 均为一个通用的自定义 ViewHolder ,其中它对外提供了一个 `<T extends View>T getView(int viewId)` 方法来代替 `View findViewById(int ViewId)`获取布局中的控件,目的是简化绑定控件方法以及对每个条目中的子 view 做了简单的缓存,具体使用方法上述代码段中有体现。

## 绑定多种布局的列表


绑定多种类型布局文件需要构造器`MultiItemViewBuilder<T>`来辅助适配器确定每个位置调用对应的布局文件。同理,声明属性同时需要声明数据源类型:

MultiItemViewBuilder multiItemViewBuilder;


`MultiItemViewBuilder`需要您实现两个方法:

- `int getItemType(int position,T data)`,通过参数中的位置和数据源来判断返回ItemView类型,ItemView类型的值需自定义。
- `int getLayoutId(int type)`,通过判断`itemType`返回对应的布局文件id。

MultiItemViewBuilder multiItemViewBuilder = MultiItemViewBuilder() { @Override public int getLayoutId(int type) { if (type == 0){ return R.layout.view_item_normal; } return R.layout.view_item_other; }

    @Override
    public int getItemType(int position, DataEntity data) {

        if(entity.isTest()){
            return 0;
        }else{
            return 1;
        }

    }

};

最后,将`MultiItemViewBuilder`直接添加到`SuperAdapter`构造函数中即可:

mAdapter = new SuperAdapter(multiItemViewBuilder,mData) {

    @Override
    public void convert(ViewHolder holder, DataEntity entity) {
          // 此处写绑定itemview中的控件逻辑
    }

};

最后在方法`convert()`中绑定控件逻辑时需要针对不同的控件类型分别处理。

## 绑定列表点击事件
绑定点击事件:

mAdapter.setOnItemClickListener(new SuperAdapter.OnItemClickListener() { @Override public void onItemClick(int position, DataEntity entity) { // 此处写点击事件的逻辑 } });

绑定长按事件:

mAdapter.setOnItemLongClickListener(new SuperAdapter.OnItemLongClickListener() { @Override public void onItemLongClick(int position, DataEntity entity) { // 此处写长按事件的逻辑 } });


## 设置空数据视图

空数据视图是指列表的数据源数据为空时显示的提示视图。设置的使用方法非常简单:

mAdapter.setEmptyDataView(R.layout.empty_view);

**在为列表添加了 Header 与 Footer 后即使数据源为空也不认为需要显示空视图**

## 添加列表唯一顶部Header

为什么要说是列表“唯一顶部”的 Header 呢?因为除该 Header 外,还有一种用于显示分类信息的 Header ,类似与通讯录中通过首字母 A~Z 顺序显示联系人。

自定义头部控件的本质其实就是列表中的一个特殊`ItemView`,它永远存在列表最上方的位置且跟随列表滑动。

添加自定义头部需要实现一个头部构造器来管理自定义头部布局:

HeaderBuilder builder = new HeaderBuilder() { @Override public int getHeaderLayoutId() { return R.layout.view_header; }

    @Override
    public void bindHeaderView(ViewHolder holder) {
        ImageView background = holder.getView(R.id.header_img);
        holder.<TextView>getView(R.id.header_name).setText("Test UserName);
    }

};

构造器接口中有两个回调方法:

- `int getLayoutId()` 设置自定义头部的布局id;
- `void convert(ViewHolder view) `  绑定布局中的控件及添加逻辑;

最后,将实现好的头部构造器添加到适配器中即可:

mAdapter.addHeader(builder);


## 添加列表分类Header

开发中。。。

这个功能有点费劲啊。。。

## 添加列表底部Footer

Footer 是为满足特殊需求一直存在于列表底部的ItemView,通常情况下是配合列表分页加载数据使用。添加 Footer 的方法与之前添加 Header 的方法类似,需要一个构造器管理:

FooterBuilder builder = new FooterBuilder() {

   /**
    * 获取Footer的布局文件Id
    */        
    @Override
    public int getFooterLayoutId() {
        return R.layout.view_footer;
    }

   /**
    * 非用于分页加载更多数据状态下Footer的界面逻辑处理
    */
    @Override
    public void onNormal(ViewHolder holder) {
        holder.<ProgressBar>getView(R.id.footer_progress).setVisibility(View.GONE);
        holder.<TextView>getView(R.id.footer_msg).setText("这是个底部");
    }

   /**
    * 分页加载更多数据 - “正在加载数据中” 状态的界面逻辑处理
    */
    @Override
    public void onLoading(ViewHolder holder) {
        holder.<ProgressBar>getView(R.id.footer_progress).setVisibility(View.VISIBLE);
        holder.<TextView>getView(R.id.footer_msg).setText("正在加载数据中");
    }

   /**
    * 分页加载更多数据 - “加载数据失败” 状态的界面逻辑处理
    *
    * @param msg 数据加载失败的原因
    */
    @Override
    public void onLoadingFailure(ViewHolder holder, String msg) {
        holder.<ProgressBar>getView(R.id.footer_progress).setVisibility(View.GONE);
        holder.<TextView>getView(R.id.footer_msg).setText(msg);
    }

   /**
    * 分页加载更多数据 - “没有更多数据” 状态的界面逻辑处理
    */
    @Override
    public void onNoMoreData(ViewHolder holder) {
        holder.<ProgressBar>getView(R.id.footer_progress).setVisibility(View.GONE);
        holder.<TextView>getView(R.id.footer_msg).setText("已经到底啦");
    }

};


因为 Footer 需要经常配合列表分页加载数据使用,所以在构造器中除了正常使用情况下的方法`onNormal(ViewHolder holder)`外还提供了三个用于管理分页加载数据状态的方法:

- `onLoading(ViewHolder holder)` 正在加载数据中
- `onLoadingFailure(ViewHolder holder, String msg)` 数据加载失败,`msg`为失败的原因
- `onNoMoreData(ViewHolder holder)` 已经加载完所有数据

最后,将构造器添加到 SuperAdapter 中:

mAdapter.addFooter(builder);


### 简易Footer构造器SimpleFooterBuilder

考虑到构造 Footer 的过程有些繁琐, SuperAdapter 库中提供了一个简易的内部定义好的 Footer 构造器 `SimpleFooterBuilder`,使用方法很简单:

mAdapter.addFooter(new SimpleFooterBuilder("这是个底部","正在加载数据中","加载数据失败","已经到底啦"));


`SimpleFooterBuilder`构造方法中的4个参数依次对应着 Footer 的正常模式、正在加载、加载失败、加载完毕这几种状态的提示信息。


## 分页自动加载更多数据

**注意!在设置分页加载数据前一定要先添加Footer**

在使用该功能时,用户可以自己设置分页请求数据的起始页,每当列表滑动到底部的时候就会按之前设置的页数依次累加请求新的数据。


设置分页加载数据调用 SuperAdapter 的`setPaginationData()`方法就可以,但是在这之前需要一个加载数据监听器`LoadDataListener`来管理数据的加载状态,当列表需要加载新的数据时就会调用监听器的`onLoadingData()`方法,该方法有两个参数:

- `int loadPage` 需要加载新数据的页数
- `LoadDataStatus loadDataStatus`  分页加载数据的状态控制器

分页加载数据的状态控制器`LoadDataStatus` 提供了三种状态:

- `onSuccess(List<T> datas)` 数据请求成功调用该方法传入新数据
- `onFailure(String msg)` 数据请求失败调用该方法传入失败信息
- `onNoMoreData()` 数据全部加载完毕调用该方法


**注意!加载数据一定要调用状态控制器`LoadDataStatus`中的方法给列表加载状态做反馈**


具体的实现代码:

// 分页加载数据的起始页 private static final int START_PAGE = 0;

... ...

// 实现加载数据监听器 LoadDataListener listener = new LoadDataListener() {

    @Override
    public void onLoadingData(final int loadPage, final LoadDataStatus loadDataStatus) {

            DataManager.getListPaginationData(loadPage,new Callback(){

                    @Override
                    public void onSuccess(List<String> datas){
                        if(datas.size() == 0){
                            loadDataStatus.onNoMoreData();
                        }else{
                            loadDataStatus.onSuccess(datas);
                        }
                    }

                    @Override
                    public void onFailure(String msg){
                        loadDataStatus.onFailure(msg);
                    }

                    @Override
                    public void onError(){
                        loadDataStatus.onFailure("网络请求出错");
                    }                                
            });
    }

}

// 设置分页加载数据 mAdapter.setPaginationData(START_PAGE, listener);


## 封装 SuperAdapter 的注意事项

`SuperAdaper`类中提供了两个有参构造方法: 
- `SuperAdapter(int layoutId )`  
- `SuperAdapter(MultiItemViewBuilder multiItemViewBuilder)` 

他们实现了不同类型的子布局,所以继承`SuperAdapter`时要`Super()`其中一个构造方法,但是你肯定不希望每次实例化适配器都要定义它们,所以建议在你的自定义类中将布局类型以`static`方法定义好:

private static int layoutId = R.layout.view_list_item;

或者

private static MultiItemViewBuilder multiItemViewBuilder = new MultiItemViewBuilder() {

    @Override
    public int getLayoutId(int type) {
        if (type == 0){
            return R.layout.view_list_item_1;
        }else {
            return R.layout.view_list_item_2;
        }
    }

    @Override
    public int getItemType(int position, TestEntity data) {
        return data.getType();
    }
};

这样自定义类的构造方法中就无需填写参数:

public MineAdapter() { super(layoutId); // do something }


或者

public MineAdapter() { super(multiItemViewBuilder); // do something } ```

Extension points exported contracts — how you extend this code

OnItemClickListener (Interface)
点击事件监听器 [4 implementers]
library/src/main/java/com/jessewu/library/SuperAdapter.java
MultiItemViewBuilder (Interface)
多类型item view构造器 [4 implementers]
library/src/main/java/com/jessewu/library/builder/MultiItemViewBuilder.java
HeaderBuilder (Interface)
列表唯一头部构造器 与分类头部不同,该布局在列表中只有一个且永远处在列表的最上方 [4 implementers]
library/src/main/java/com/jessewu/library/builder/HeaderBuilder.java
OnItemLongClickListener (Interface)
长按事件监听器 [3 implementers]
library/src/main/java/com/jessewu/library/SuperAdapter.java
LoadDataListener (Interface)
分页加载数据 - 加载数据监听器 @param 数据源类型 [2 implementers]
library/src/main/java/com/jessewu/library/paging/LoadDataListener.java

Core symbols most depended-on inside this repo

getView
called by 27
library/src/main/java/com/jessewu/library/view/ViewHolder.java
getData
called by 5
demo/src/main/java/com/jessewu/superadapter/data/DataModel.java
setData
called by 4
library/src/main/java/com/jessewu/library/SuperAdapter.java
bindView
called by 4
library/src/main/java/com/jessewu/library/view/ViewHolder.java
hasHeaderView
called by 4
library/src/main/java/com/jessewu/library/base/BaseSuperAdapter.java
hasFooterView
called by 4
library/src/main/java/com/jessewu/library/base/BaseSuperAdapter.java
setEmptyDataView
called by 3
library/src/main/java/com/jessewu/library/SuperAdapter.java
shouldShowEmptyView
called by 3
library/src/main/java/com/jessewu/library/SuperAdapter.java

Shape

Method 126
Class 17
Interface 9

Languages

Java100%

Modules by API surface

library/src/main/java/com/jessewu/library/SuperAdapter.java28 symbols
library/src/main/java/com/jessewu/library/base/BaseSuperAdapter.java10 symbols
demo/src/main/java/com/jessewu/superadapter/adapter/MineAdapter.java9 symbols
demo/src/main/java/com/jessewu/superadapter/MoreDataActivity.java9 symbols
demo/src/main/java/com/jessewu/superadapter/MainActivity.java9 symbols
demo/src/main/java/com/jessewu/superadapter/ClickActivity.java9 symbols
demo/src/main/java/com/jessewu/superadapter/data/TestEntity.java8 symbols
library/src/main/java/com/jessewu/library/widget/SimpleFooterBuilder.java7 symbols
demo/src/main/java/com/jessewu/superadapter/SingleHeaderViewActivity.java7 symbols
demo/src/main/java/com/jessewu/superadapter/DemoActivity.java7 symbols
library/src/main/java/com/jessewu/library/builder/FooterBuilder.java6 symbols
demo/src/main/java/com/jessewu/superadapter/data/SubHeaderEntity.java6 symbols

For agents

$ claude mcp add SuperAdapter \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact