Git Product home page Git Product logo

items's Introduction

Items

Build Status codecov

这个库可以为 Android 的 RecyclerView 生成基于 Data-View-Binding 的 Adapter。

对比其他一些类似的开源库,它有以下的一些优势:

  • 更好的拓展性。这个库不需要你继承特定的 Adapter 或 ViewHolder 类,你可以继承任何第三方提供的基类;
  • 更好的性能。使用 Annotation Processor 意味着实现 Binding 时无需使用反射。支持 增量处理
  • 更低的侵入性。和传统的 Adapter 写法类似,可以快速从旧的 Codebase 迁移到新的写法;
  • 更可靠的代码。提供了单元测试覆盖大部分的 Case。

集入

替换以下代码中的 ${lastest-version} 为最新版本号 ,并复制到 Android 工程中的 build.gradle 脚本:

repositories {
    maven { url "https://jitpack.io" }
}
dependencies {
    implementation "com.github.nekocode.Items:itemsLib:${lastest-version}"
    annotationProcessor "com.github.nekocode.Items:itemsProcessor:${lastest-version}"
}

注意,在 Kotlin 工程中,需要使用 kapt 关键字代替 annotationProcessor 关键字。

使用

使用 BaseItem 能够帮助你把 ViewHolder 的创建和绑定从 Adapter 中提取出来,并且与特定的数据类型绑定。例如你可以为 String 类型的数据创建一个 Item:

public class StringItem extends BaseItem<String, StringItem.Holder, StringItem.Callback> {

    public StringItem(ItemAdapter adapter, int viewType) {
        super(adapter, viewType);
    }

    @NonNull
    @Override
    public Holder onCreateViewHolder(@NonNull LayoutInflater inflater, @NonNull ViewGroup parent) {
        final View itemView = inflater.inflate(R.layout.item_string, parent, false);
        final Holder holder = new Holder(itemView);
        holder.button.setOnClickListener(v -> {
            if (getCallback() != null) {
                getCallback().onButtonClick(holder.data);
            }
        });
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull Holder holder, int position, @NonNull String data) {
        holder.data = data;
        holder.textView.setText(data);
    }

    static class Holder extends RecyclerView.ViewHolder {
        private TextView textView;
        private Button button;
        private String data;

        Holder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.textView);
            button = itemView.findViewById(R.id.button);
        }
    }

    public interface Callback {
        void onButtonClick(@NonNull String data);
    }
}

Item 提供了很好的拓展能力:

  • 可以使用任意类型的 ViewHolder
  • 可以通过 CallbackViewHolder 设置 UI 事件回调。

接下来你需要创建一个 Adapter 来装载你的所有 Item:

@AdapterClass
public abstract class TestAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements ItemAdapter {
    private final LinkedList mList = new LinkedList();

    @NonNull
    public LinkedList list() {
        return mList;
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    @NonNull
    @Override
    public <T> T getData(int position) {
        return (T) mList.get(position);
    }

    /**
     * 定义一个任意名称的方法来返回你想装载的 Item
     */
    @NonNull
    @ItemMethod
    public abstract StringItem stringItem();
}

这个 Adapter 必须实现 ItemAdapter 接口的 getItemCount()getData() 方法。你可以使用任意类型的 Collection(例如上面的 LinkedList)来装载你的数据,这个 Adapter 会通过这两个方法来访问你的数据,然后根据数据的类型来选择对应的 Item 来创建 ViewHolder

在编译期间,Annotation Processor 会为这个 Adapter 生成一个实现类 TestAdapterImpl,你可以通过以下例子来使用这个 Adapter:

// 创建 Adapter 实例
TestAdapter adapter = new TestAdapterImpl();

// 给 Adapter 插入数据
adapter.list().add("Item1");
adapter.list().add("Item2");

// 给 Item 设置 Callback
adapter.stringItem().setCallback(data -> {
    // Button 点击时
});

// 为 RecyclerView 设置 Adapter
recyclerView.setAdapter(adapter);

以上就是这个工具的基础使用。

此外,你还可以让你的单个数据类型绑定多个 Item:

@Adapter
public abstract class TestAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements ItemAdapter {
    // ...

    @NonNull
    @ItemMethod
    public abstract StringItem stringItem();

    @NonNull
    @ItemMethod
    public abstract StringItem2 stringItem2();

    /**
     * 定义一个任意名称的方法来帮助 Adapter 选择绑定了同一数据类型的 Item
     */
    @SelectorMethod
    public int itemForString(int position, @NonNull String data) {
        if (!data.endsWith(2)) {
            return stringItem().getViewType();
        } else {
            return stringItem2().getViewType();
        }
    }
}

最后,还有一个小的 Tip。你可以定义一些 BaseAdapter 来简化你 Adapter 的代码,例如把对集合的操作封装起来,举个例子:

public abstract class BaseArrayListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements ItemAdapter {
    private final ArrayList mList = new ArrayList();

    public ArrayList getList() {
        return mList;
    }

    @NonNull
    @Override
    public <T> T getData(int position) {
        return (T) mList.get(position);
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }
}

@Adapter
public abstract class TestAdapter extends BaseArrayListAdapter {
    // ...
}

更详细的应用可以参考这个仓库中的 exampleApp 模块。

items's People

Contributors

nekocode avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

items's Issues

Any Plan to support auto load more?

  • Thank for your library, but I hava some problem about the function about auto load more.
  • Is there any plan to support auto load More?
  • I‘m trying to extends the recyclerview to achieve this function(or a wrapper adapter). Is there any better way to doing this ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.