master c4d7e43c6e5a cached
177 files
379.3 KB
95.2k tokens
119 symbols
1 requests
Download .txt
Showing preview only (431K chars total). Download the full file or copy to clipboard to get everything.
Repository: CymChad/BaseRecyclerViewAdapterHelper
Branch: master
Commit: c4d7e43c6e5a
Files: 177
Total size: 379.3 KB

Directory structure:
gitextract_07v8rp8z/

├── .circleci/
│   └── config.yml
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   └── pull_request_template.md
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── chad/
│           │           └── baserecyclerviewadapterhelper/
│           │               ├── MyApplication.kt
│           │               ├── activity/
│           │               │   ├── WelcomeActivity.java
│           │               │   ├── animation/
│           │               │   │   ├── AnimationUseActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── AnimationAdapter.kt
│           │               │   ├── databinding/
│           │               │   │   ├── DataBindingUseActivity.java
│           │               │   │   └── adapter/
│           │               │   │       └── DataBindingAdapter.java
│           │               │   ├── differ/
│           │               │   │   ├── DifferActivity.java
│           │               │   │   └── adapter/
│           │               │   │       ├── DiffEntityCallback.java
│           │               │   │       └── DiffUtilAdapter.java
│           │               │   ├── dragswipe/
│           │               │   │   ├── DefaultDragAndSwipeActivity.kt
│           │               │   │   ├── DragAndSwipeDifferActivity.kt
│           │               │   │   ├── DragAndSwipeUseActivity.java
│           │               │   │   ├── HeaderDragAndSwipe.kt
│           │               │   │   ├── HeaderDragAndSwipeActivity.kt
│           │               │   │   ├── ManualDragAndSwipeUseActivity.java
│           │               │   │   └── adapter/
│           │               │   │       ├── DiffDragAndSwipeAdapter.kt
│           │               │   │       ├── DragAndSwipeAdapter.java
│           │               │   │       └── HeaderDragAndSwipeAdapter.kt
│           │               │   ├── emptyview/
│           │               │   │   ├── EmptyViewUseActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── EmptyViewAdapter.kt
│           │               │   ├── headerfooter/
│           │               │   │   ├── HeaderAndFooterUseActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       ├── FooterAdapter.kt
│           │               │   │       ├── HeaderAdapter.kt
│           │               │   │       └── HeaderAndFooterAdapter.kt
│           │               │   ├── home/
│           │               │   │   ├── HomeActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       ├── HomeAdapter.kt
│           │               │   │       └── HomeTopHeaderAdapter.kt
│           │               │   ├── itemclick/
│           │               │   │   ├── ItemClickActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── ItemClickAdapter.java
│           │               │   ├── loadmore/
│           │               │   │   ├── AutoLoadMoreRefreshUseActivity.kt
│           │               │   │   ├── NoAutoAutoLoadMoreRefreshUseActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       ├── CustomLoadMoreAdapter.kt
│           │               │   │       └── RecyclerViewAdapter.kt
│           │               │   ├── node/
│           │               │   │   ├── NodeActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── NodeAdapter.kt
│           │               │   ├── scene/
│           │               │   │   ├── GroupDemoActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── GroupAdapter.kt
│           │               │   └── upfetch/
│           │               │       ├── UpFetchUseActivity.kt
│           │               │       └── adapter/
│           │               │           └── UpFetchAdapter.kt
│           │               ├── animator/
│           │               │   ├── CustomAnimation1.java
│           │               │   ├── CustomAnimation2.java
│           │               │   └── CustomAnimation3.java
│           │               ├── base/
│           │               │   ├── BaseActivity.kt
│           │               │   └── BaseViewBindingActivity.kt
│           │               ├── data/
│           │               │   └── DataServer.kt
│           │               ├── decoration/
│           │               │   ├── GridItemDecoration.java
│           │               │   └── GridSectionAverageGapItemDecoration.java
│           │               ├── entity/
│           │               │   ├── ClickEntity.java
│           │               │   ├── DiffEntity.java
│           │               │   ├── GroupDemoEntity.kt
│           │               │   ├── HomeEntity.kt
│           │               │   ├── Movie.java
│           │               │   ├── MoviePresenter.java
│           │               │   ├── NodeEntity.kt
│           │               │   └── Status.java
│           │               ├── utils/
│           │               │   ├── AppUtils.kt
│           │               │   ├── ClickableMovementMethod.java
│           │               │   ├── Ext.kt
│           │               │   ├── Tips.java
│           │               │   └── VibratorUtils.kt
│           │               └── widget/
│           │                   └── BRVAHToolbar.kt
│           └── res/
│               ├── anim/
│               │   ├── item_animation_from_bottom.xml
│               │   └── layout_animation_from_bottom.xml
│               ├── drawable/
│               │   ├── actionbar_bottom_bg.xml
│               │   ├── brvah_sample_footer_loading_progress.xml
│               │   ├── custom_text_state_color.xml
│               │   ├── gv_up_fetch.xml
│               │   ├── ic_node_down.xml
│               │   ├── ic_node_right.xml
│               │   ├── selector_item_child.xml
│               │   ├── shape_right_top_float_bg.xml
│               │   ├── thumb_drawable.xml
│               │   └── touch_bg.xml
│               ├── drawable-v21/
│               │   └── touch_bg.xml
│               ├── layout/
│               │   ├── activity_animation_use.xml
│               │   ├── activity_choose_multiple_item_use_type.xml
│               │   ├── activity_choose_node_use_type.xml
│               │   ├── activity_diffutil.xml
│               │   ├── activity_empty_view_use.xml
│               │   ├── activity_home.xml
│               │   ├── activity_load_more.xml
│               │   ├── activity_node.xml
│               │   ├── activity_universal_recycler.xml
│               │   ├── activity_welcome.xml
│               │   ├── def_section_head.xml
│               │   ├── empty_view.xml
│               │   ├── error_view.xml
│               │   ├── footer_view.xml
│               │   ├── head_view.xml
│               │   ├── home_item_view.xml
│               │   ├── item_click_childview.xml
│               │   ├── item_click_view.xml
│               │   ├── item_draggable_view.xml
│               │   ├── item_group_type.xml
│               │   ├── item_header_and_footer.xml
│               │   ├── item_image_view.xml
│               │   ├── item_img_text_view.xml
│               │   ├── item_long_click_childview.xml
│               │   ├── item_long_click_view.xml
│               │   ├── item_movie.xml
│               │   ├── item_node_level_1.xml
│               │   ├── item_node_level_2.xml
│               │   ├── item_node_level_3.xml
│               │   ├── item_section_content.xml
│               │   ├── layout_animation.xml
│               │   ├── layout_title_bar.xml
│               │   ├── layout_tool_bar.xml
│               │   ├── loading_view.xml
│               │   ├── node_footer.xml
│               │   ├── toolbar_layout.xml
│               │   ├── top_view.xml
│               │   └── view_load_more.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               ├── values-v21/
│               │   └── styles.xml
│               └── values-zh/
│                   └── strings.xml
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library/
│   ├── .gitignore
│   ├── build.gradle.kts
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── chad/
│           │           └── library/
│           │               └── adapter4/
│           │                   ├── BaseDifferAdapter.kt
│           │                   ├── BaseMultiItemAdapter.kt
│           │                   ├── BaseNodeAdapter.kt
│           │                   ├── BaseQuickAdapter.kt
│           │                   ├── BaseSingleItemAdapter.kt
│           │                   ├── QuickAdapterHelper.kt
│           │                   ├── animation/
│           │                   │   ├── AlphaInAnimation.kt
│           │                   │   ├── ItemAnimator.kt
│           │                   │   ├── ScaleInAnimation.kt
│           │                   │   ├── SlideInBottomAnimation.kt
│           │                   │   ├── SlideInLeftAnimation.kt
│           │                   │   └── SlideInRightAnimation.kt
│           │                   ├── dragswipe/
│           │                   │   ├── DragSwipeExt.kt
│           │                   │   ├── QuickDragAndSwipe.kt
│           │                   │   └── listener/
│           │                   │       ├── DragAndSwipeDataCallback.kt
│           │                   │       ├── OnItemDragListener.java
│           │                   │       └── OnItemSwipeListener.java
│           │                   ├── fullspan/
│           │                   │   └── FullSpanAdapterType.kt
│           │                   ├── layoutmanager/
│           │                   │   └── QuickGridLayoutManager.kt
│           │                   ├── loadState/
│           │                   │   ├── LoadState.kt
│           │                   │   ├── LoadStateAdapter.kt
│           │                   │   ├── leading/
│           │                   │   │   ├── DefaultLeadingLoadStateAdapter.kt
│           │                   │   │   └── LeadingLoadStateAdapter.kt
│           │                   │   └── trailing/
│           │                   │       ├── DefaultTrailingLoadStateAdapter.kt
│           │                   │       └── TrailingLoadStateAdapter.kt
│           │                   ├── util/
│           │                   │   ├── AdapterUtils.kt
│           │                   │   └── ItemClickUtils.kt
│           │                   └── viewholder/
│           │                       ├── DataBindingHolder.java
│           │                       ├── QuickViewHolder.kt
│           │                       └── StateLayoutVH.kt
│           └── res/
│               ├── layout/
│               │   ├── brvah_leading_load_more.xml
│               │   └── brvah_trailing_load_more.xml
│               ├── values/
│               │   ├── ids.xml
│               │   └── strings.xml
│               ├── values-en/
│               │   └── strings.xml
│               ├── values-zh-rHK/
│               │   └── strings.xml
│               └── values-zh-rTW/
│                   └── strings.xml
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .circleci/config.yml
================================================
version: 2
jobs:
  build:
    working_directory: ~/code
    docker:
      - image: cimg/android:2023.04
    environment:
      JVM_OPTS: -Xmx3200m
    steps:
      - checkout
      - restore_cache:
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
      - run:
          name: Download Dependencies
          command: ./gradlew androidDependencies
      - save_cache:
          paths:
            - ~/.gradle
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
      - run:
          name: Run Tests
          command: ./gradlew lint test
      - store_artifacts:
          path: app/build/reports
          destination: reports
      - store_test_results:
          path: app/build/test-results


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Additional context**
Add any other context about the problem here.

1. 尝试在[历史问题](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues?q=is%3Aissue+is%3Aclosed)搜索答案。
2. 尝试阅读[文档](http://www.jianshu.com/p/b343fcff51b0)找到答案。
3. 尝试阅读[Demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)找到答案。
4. 尝试自己检查或试验以找到答案。
5. 尝试阅读源代码以找到答案。
6. 请勿将产品的一些特殊交互需求 和 该库暂不支持作为bug混为一谈,请您仔细甄别

如果以上都尝试过了请提一个新的[issues](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues/new)   
参考[提問的智慧](https://github.com/FredWe/How-To-Ask-Questions-The-Smart-Way)

如果还是没有找到答案,提问请带上这几个必要信息
1. 当前使用的版本号
2. 复现操作描述
3. 使用代码
3. crash日志
4. gif复现效果
5. 抽取demo
       **将你出现的问题代码抽出来成一个可直接运行的项目。(最好fork[本库](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)修改)**
       **在本地修改demo,然后把commit push到github上,在issue里贴下demo的地址。**

**有详细的描述才能使得我们更快速的定位问题并解决问题,感谢配合!**


================================================
FILE: .github/pull_request_template.md
================================================
Thank you for contributing to BaseRecyclerViewAdapterHelper. Before pressing the "Create Pull Request" button, please consider the following points:

  - [1] Please give a description about what and why you are contributing, even if it's trivial.

  - [2] Please include the issue list number(s) or other PR numbers in the description if you are contributing in response to those.

  - [3] Please include a reasonable set of demo tests if you contribute new code or change an existing one. please make sure you have demo for working correctly.


================================================
FILE: .gitignore
================================================
#/////////////////////////////////////////////////////////////////////////////
# OS generated files
#/////////////////////////////////////////////////////////////////////////////

.DS_Store
ehthumbs.db
Thumbs.db

# Built application files
*.apk
*.ap_

# Files for the Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/


# Android Studio project files
*.iml
.gradle
.idea
build


================================================
FILE: .travis.yml
================================================
language: android
dist: trusty
jdk: oraclejdk11
sudo: false

android:
components:
    - tools
    - platform-tools
    - build-tools-33.0.0
    - android-32
    - extra-android-m2repository
before_install:
  - chmod +x gradlew
  - mkdir "$ANDROID_HOME/licenses" || true
  # Hack to accept Android licenses
  - yes | sdkmanager "platforms;android-32"

script:
  - ./gradlew assembleRelease


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2023 陈宇明

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
![](https://user-images.githubusercontent.com/7698209/33198075-ef8f2230-d123-11e7-85a3-4cb9b22f877d.png)
[![](https://img.shields.io/maven-central/v/io.github.cymchad/BaseRecyclerViewAdapterHelper4)](https://repo.maven.apache.org/maven2/io/github/cymchad/BaseRecyclerViewAdapterHelper4/) [![API](https://img.shields.io/badge/API-16%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=16) [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-BaseRecyclerViewAdapterHelper-green.svg?style=true)](https://android-arsenal.com/details/1/3644) [![CircleCI](https://circleci.com/gh/CymChad/BaseRecyclerViewAdapterHelper/tree/master.svg?style=svg)](https://circleci.com/gh/CymChad/BaseRecyclerViewAdapterHelper/tree/master) [![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/CymChad/BaseRecyclerViewAdapterHelper) [![](https://img.shields.io/badge/%E4%BD%9C%E8%80%85-%E9%99%88%E5%AE%87%E6%98%8E-7AD6FD.svg)](https://mp.weixin.qq.com/s/U4QAPlu5WDm8U5Ljc7TuAQ) [![](https://img.shields.io/badge/%E4%BD%9C%E8%80%85-limuyang2-7AD6FD)](https://github.com/limuyang2)  
# BRVAH

Powerful and flexible RecyclerView Adapter,
Please feel free to use this. (Welcome to **Star** and **Fork**)  

强大而灵活的RecyclerView Adapter(欢迎 **Star** 和 **Fork**)

​    
新版4.x.x已发布,完美兼容`ConcatAdapter`,解决了许多遗留问题,拆分了功能模块,BaseAdapter更加简洁干净。“多类型布局”更加灵活。向上、向下加载得到极大加强。
v4版本已经上传 maven 中央仓库,不需要再引入三方仓库配置了。欢迎尝试。



Of course, you can continue to use the [2.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/2.x) version.

当然,你也可以继续使用[2.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/2.x) 版本、[3.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/3.x/readme/0-BaseRecyclerViewAdapterHelper.md)版本。

# Document
- English Writing ...
- [3.0版本 中文](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/3.x/readme/0-BaseRecyclerViewAdapterHelper.md)
- [4.0版本 中文](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki)


(由于各位项目成员工作较为繁忙,请各位同学谅解)

## v4 版本
[wiki](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki)
```
implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.3.4")
```

## [demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/master/demo)

# proguard-rules.pro
> 此资源库自带混淆规则,并且会自动导入,正常情况下无需手动导入。

> The library comes with `proguard-rules.pro` rules and is automatically imported. Normally no manual import is required.
> You can also go here to view [proguard-rules](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/library/proguard-rules.pro)




# Thanks  
[JoanZapata / base-adapter-helper](https://github.com/JoanZapata/base-adapter-helper)

# [License](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/LICENSE)


================================================
FILE: app/.gitignore
================================================
.gradle/
.DS_Store
local.properties

# build files
build/
bin/
gen/
output/

# android studio
*.iml
.idea


================================================
FILE: app/build.gradle
================================================
plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'com.google.devtools.ksp'
}

android {
    compileSdk 36

    defaultConfig {
        applicationId "com.chad.baserecyclerviewadapterhelper"
        minSdk 23
        targetSdk 36
        versionCode 21
        versionName "4.3.2"
    }
    buildTypes {
        release {
            minifyEnabled true
            zipAlignEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
            zipAlignEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }

    buildFeatures {
        viewBinding = true
        dataBinding = true
    }
    namespace 'com.chad.baserecyclerviewadapterhelper'
}

dependencies {
    implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
    implementation project(path: ':library')
    implementation 'com.google.android.material:material:1.13.0'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.appcompat:appcompat:1.7.1'
    implementation "androidx.core:core-ktx:1.17.0"

    implementation 'com.kyleduo.switchbutton:library:2.1.0'
    implementation 'androidx.recyclerview:recyclerview:1.4.0'
    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"

    implementation("com.squareup.moshi:moshi:1.15.2")
    ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.2")

    implementation 'com.jaredrummler:material-spinner:1.3.1'
}


================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/huasheng/Desktop/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}
#BaseRecyclerViewAdapterHelper


================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:name=".MyApplication"
        android:icon="@mipmap/logo"
        android:label="BRVAH"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity
            android:name=".activity.WelcomeActivity"
            android:exported="true"
            android:theme="@style/WelcomeTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".activity.home.HomeActivity"
            android:exported="false" />
        <activity
            android:name=".activity.animation.AnimationUseActivity"
            android:exported="false" />
        <activity
            android:name=".activity.headerfooter.HeaderAndFooterUseActivity"
            android:exported="false" />
        <activity
            android:name=".activity.loadmore.AutoLoadMoreRefreshUseActivity"
            android:exported="false" />
        <activity
            android:name=".activity.emptyview.EmptyViewUseActivity"
            android:exported="false" />
        <activity
            android:name=".activity.itemclick.ItemClickActivity"
            android:exported="false" />
        <activity
            android:name=".activity.databinding.DataBindingUseActivity"
            android:exported="false" />
        <activity
            android:name=".activity.dragswipe.ManualDragAndSwipeUseActivity"
            android:exported="false" />
        <activity
            android:name=".activity.upfetch.UpFetchUseActivity"
            android:exported="false" /> <!-- <activity android:name=".activity.node.NodeSectionUseActivity" /> -->
        <activity
            android:name=".activity.differ.DifferActivity"
            android:exported="false" /> <!-- <activity android:name=".activity.node.ChooseNodeUseTypeActivity" /> -->
        <activity
            android:name=".activity.loadmore.NoAutoAutoLoadMoreRefreshUseActivity"
            android:exported="false" />
        <activity
            android:name=".activity.dragswipe.DragAndSwipeDifferActivity"
            android:exported="false" />
        <activity
            android:name=".activity.dragswipe.HeaderDragAndSwipeActivity"
            android:exported="false" />

        <activity
            android:name=".activity.dragswipe.DragAndSwipeUseActivity"
            android:exported="false" />
        <activity
            android:name=".activity.dragswipe.DefaultDragAndSwipeActivity"
            android:exported="false" />
        <activity android:name=".activity.scene.GroupDemoActivity" />
        <activity android:name="com.chad.baserecyclerviewadapterhelper.activity.node.NodeActivity" />
    </application>

</manifest>

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.kt
================================================
/*
******************************* Copyright (c)*********************************\
**
**                 (c) Copyright 2015, Allen, china, shanghai
**                          All Rights Reserved
**
**                          
**                         
**-----------------------------------版本信息------------------------------------
** 版    本: V0.1
**
**------------------------------------------------------------------------------
********************************End of Head************************************\
*/
package com.chad.baserecyclerviewadapterhelper

import android.app.Application
import com.chad.baserecyclerviewadapterhelper.utils.AppUtils

/**
 * 文 件 名: MyApplication
 * 创 建 人: Allen
 * 创建日期: 16/12/24 15:33
 * 邮   箱: AllenCoder@126.com
 * 修改时间:
 * 修改备注:
 */
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        AppUtils.init(this)
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/WelcomeActivity.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;

import androidx.appcompat.app.AppCompatActivity;

import com.chad.baserecyclerviewadapterhelper.R;
import com.chad.baserecyclerviewadapterhelper.activity.home.HomeActivity;

public class WelcomeActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(WelcomeActivity.this, HomeActivity.class);
                startActivity(intent);
                finish();
            }
        }, 1000);
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/AnimationUseActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.animation

import android.os.Bundle
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import com.chad.baserecyclerviewadapterhelper.activity.animation.adapter.AnimationAdapter
import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation1
import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation2
import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation3
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityAnimationUseBinding
import com.chad.library.adapter4.BaseQuickAdapter

/**
 * https://github.com/CymChad/BaseRecyclerViewAdapterHelper
 *
 *
 * modify by AllenCoder
 */
class AnimationUseActivity : BaseViewBindingActivity<ActivityAnimationUseBinding>() {

    private val mAnimationAdapter: AnimationAdapter = AnimationAdapter().apply {
        // 打开 Adapter 的动画
        animationEnable = true
        // 是否是首次显示时候加载动画
        isAnimationFirstOnly = false
    }

    override fun initBinding(): ActivityAnimationUseBinding {
        return ActivityAnimationUseBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        viewBinding.titleBar.title = "Animation Use"
        viewBinding.titleBar.setOnBackListener { finish() }

        viewBinding.rv.adapter = mAnimationAdapter

        initMenu()
    }

    /**
     * Init menu
     * 初始化下拉菜单
     */
    private fun initMenu() {
        viewBinding.spinner.setItems(
            "AlphaIn",
            "ScaleIn",
            "SlideInBottom",
            "SlideInLeft",
            "SlideInRight",
            "Custom1",
            "Custom2",
            "Custom3"
        )
        viewBinding.spinner.setOnItemSelectedListener { _, position, _, _ ->
            when (position) {
                0 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.AlphaIn)
                1 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.ScaleIn)
                2 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInBottom)
                3 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInLeft)
                4 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInRight)
                5 -> mAnimationAdapter.itemAnimation = CustomAnimation1()
                6 -> mAnimationAdapter.itemAnimation = CustomAnimation2()
                7 -> mAnimationAdapter.itemAnimation = CustomAnimation3()
                else -> {}
            }
            mAnimationAdapter.notifyDataSetChanged()

        }

        //init firstOnly state
        viewBinding.switchButton.setOnCheckedChangeListener { _, isChecked ->
            mAnimationAdapter.isAnimationFirstOnly = isChecked
            mAnimationAdapter.notifyDataSetChanged()
        }
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/adapter/AnimationAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.animation.adapter

import android.content.Context
import android.text.TextPaint
import android.text.style.ClickableSpan
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.text.buildSpannedString
import androidx.core.text.inSpans
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.data.DataServer
import com.chad.baserecyclerviewadapterhelper.entity.Status
import com.chad.baserecyclerviewadapterhelper.utils.ClickableMovementMethod
import com.chad.baserecyclerviewadapterhelper.utils.Tips
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder

/**
 * 文 件 名: AnimationAdapter
 * 创 建 人: Allen
 * 创建日期: 16/12/24 15:33
 * 邮   箱: AllenCoder@126.com
 * 修改时间:
 * 修改备注:
 */
class AnimationAdapter :
    BaseQuickAdapter<Status, QuickViewHolder>(DataServer.getSampleData(100)) {
    override fun onCreateViewHolder(
        context: Context,
        parent: ViewGroup,
        viewType: Int
    ): QuickViewHolder {
        return QuickViewHolder(R.layout.layout_animation, parent)
    }

    override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: Status?) {
        when (holder.layoutPosition % 3) {
            0 -> holder.setImageResource(R.id.img, R.mipmap.animation_img1)
            1 -> holder.setImageResource(R.id.img, R.mipmap.animation_img2)
            2 -> holder.setImageResource(R.id.img, R.mipmap.animation_img3)
            else -> {}
        }
        holder.setText(R.id.tweetName, "Hoteis in Rio de Janeiro")
        val msg =
            "\"He was one of Australia's most of distinguished artistes, renowned for his portraits\""



        holder.getView<TextView>(R.id.tweetText).text = buildSpannedString {
            append(msg)
            inSpans(clickableSpan) {
                append("landscapes and nedes")
            }
        }
        holder.getView<TextView>(R.id.tweetText).movementMethod = ClickableMovementMethod.getInstance()
        holder.getView<TextView>(R.id.tweetText).isFocusable = false
        holder.getView<TextView>(R.id.tweetText).isClickable = false
        holder.getView<TextView>(R.id.tweetText).isLongClickable = false
    }

    private val clickableSpan: ClickableSpan = object : ClickableSpan() {
        override fun onClick(widget: View) {
            Tips.show("事件触发了 landscapes and nedes")
        }

        override fun updateDrawState(ds: TextPaint) {
            ds.color = ContextCompat.getColor(context, R.color.clickspan_color)
            ds.isUnderlineText = true
        }
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/DataBindingUseActivity.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity.databinding;

import android.os.Bundle;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.core.graphics.Insets;
import androidx.core.view.OnApplyWindowInsetsListener;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.chad.baserecyclerviewadapterhelper.activity.databinding.adapter.DataBindingAdapter;
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity;
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding;
import com.chad.baserecyclerviewadapterhelper.entity.Movie;
import com.chad.baserecyclerviewadapterhelper.utils.Tips;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author  limuyang
 * @date  2019-12-05
 * @description
 */
public final class DataBindingUseActivity extends BaseViewBindingActivity<ActivityUniversalRecyclerBinding> {

    private final DataBindingAdapter adapter = new DataBindingAdapter();

    @NonNull
    @Override
    public ActivityUniversalRecyclerBinding initBinding() {
        return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater());
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {
        super.onPointerCaptureChanged(hasCapture);
    }

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

        ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() {
            @Override
            public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {
                Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                getViewBinding().titleBar.updateFakeBarHeight(bar.top);
                return insets;
            }
        });

        getViewBinding().titleBar.setTitle("DataBinding Use");
        getViewBinding().titleBar.setOnBackListener(v -> finish());


        getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this));
        getViewBinding().rv.setAdapter(adapter);


        //item 点击事件
        adapter.setOnItemClickListener((movieBaseQuickAdapter, view, position) -> {
            Tips.show("onItemClick: " + position);
        });

        //设置数据
        adapter.submitList(genData());
    }

    private List<Movie> genData() {
        ArrayList<Movie> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            String name = "Chad " + i;
            int price = random.nextInt(10) + 10;
            int len = random.nextInt(80) + 60;
            Movie movie = new Movie(name, len, price, "He was one of Australia's most distinguished artistes");
            list.add(movie);
        }
        return list;
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/adapter/DataBindingAdapter.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity.databinding.adapter;

import android.content.Context;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.chad.baserecyclerviewadapterhelper.R;
import com.chad.baserecyclerviewadapterhelper.databinding.ItemMovieBinding;
import com.chad.baserecyclerviewadapterhelper.entity.Movie;
import com.chad.baserecyclerviewadapterhelper.entity.MoviePresenter;
import com.chad.library.adapter4.BaseQuickAdapter;
import com.chad.library.adapter4.viewholder.DataBindingHolder;

/**
 * @author: limuyang
 * @date: 2019-12-05
 * @Description: DataBinding Adapter
 *
 */
public class DataBindingAdapter extends BaseQuickAdapter<Movie, DataBindingHolder<ItemMovieBinding>> {

    private final MoviePresenter mPresenter = new MoviePresenter();

    @NonNull
    @Override
    protected DataBindingHolder<ItemMovieBinding> onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {
        return new DataBindingHolder<>(R.layout.item_movie, parent);
    }

    @Override
    protected void onBindViewHolder(@NonNull DataBindingHolder<ItemMovieBinding> holder, int position, @Nullable Movie item) {
        if (item == null) return;

        // 获取 Binding
        ItemMovieBinding binding = holder.getBinding();
        binding.setMovie(item);
        binding.setPresenter(mPresenter);
        binding.executePendingBindings();
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/DifferActivity.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity.differ;

import android.os.Bundle;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.core.graphics.Insets;
import androidx.core.view.OnApplyWindowInsetsListener;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.chad.baserecyclerviewadapterhelper.R;
import com.chad.baserecyclerviewadapterhelper.activity.differ.adapter.DiffUtilAdapter;
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity;
import com.chad.baserecyclerviewadapterhelper.data.DataServer;
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityDiffutilBinding;
import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by limuyang
 * Date: 2019/7/14O
 */
public final class DifferActivity extends BaseViewBindingActivity<ActivityDiffutilBinding> {

    private final DiffUtilAdapter mAdapter = new DiffUtilAdapter();

    @NonNull
    @Override
    public ActivityDiffutilBinding initBinding() {
        return ActivityDiffutilBinding.inflate(getLayoutInflater());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() {
            @Override
            public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {
                Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                getViewBinding().titleBar.updateFakeBarHeight(bar.top);
                return insets;
            }
        });

        getViewBinding().titleBar.setTitle("DiffUtil Use");
        getViewBinding().titleBar.setOnBackListener(v -> finish());

        initRv();
        initClick();
    }

    @Override
    protected void onStart() {
        super.onStart();

        // 增加延迟,模拟网络加载
        getViewBinding().diffRv.postDelayed(() -> mAdapter.submitList(DataServer.getDiffUtilDemoEntities()), 1500);
    }


    private void initRv() {
        // 打开空布局功能
        mAdapter.setStateViewEnable(true);
        // 传入 空布局 layout id
        mAdapter.setStateViewLayout(this, R.layout.loading_view);

        getViewBinding().diffRv.setAdapter(mAdapter);
    }

    private int idAdd = 0;

    private void initClick() {
        getViewBinding().btnChange.setOnClickListener(v -> {
            List<DiffEntity> newData = getNewList();
            mAdapter.submitList(newData);
        });

        getViewBinding().btnAdd.setOnClickListener(v -> {
            mAdapter.add(2, new DiffEntity(
                    1000 + idAdd,
                    "add - 😊😊Item " + 1000 + idAdd,
                    "Item " + 0 + " content have change (notifyItemChanged)",
                    "06-12"));
            idAdd++;
        });

        getViewBinding().btnRemove.setOnClickListener(v -> {
            if (2 >= mAdapter.getItems().size()) {
                return;
            }
            mAdapter.removeAt(2);
        });
    }


    /**
     * get new data
     */
    private List<DiffEntity> getNewList() {
        List<DiffEntity> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            /*
            Simulate deletion of data No. 1 and No. 3
            模拟删除1号和3号数据
             */
            if (i == 1 || i == 3) {
                continue;
            }

            /*
            Simulate modification title of data No. 0
            模拟修改0号数据的title
             */
            if (i == 0) {
                list.add(new DiffEntity(
                        i,
                        "😊Item " + i,
                        "This item " + i + " content",
                        "06-12")
                );
                continue;
            }

            /*
            Simulate modification content of data No. 4
            模拟修改4号数据的content发生变化
             */
            if (i == 4) {
                list.add(new DiffEntity(
                        i,
                        "Item " + i,
                        "Oh~~~~~~, Item " + i + " content have change",
                        "06-12")
                );
                continue;
            }

            list.add(new DiffEntity(
                    i,
                    "Item " + i,
                    "This item " + i + " content",
                    "06-12")
            );
        }
        return list;
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffEntityCallback.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;

import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity;

/**
 * Create DiffCallback
 */
public class DiffEntityCallback extends DiffUtil.ItemCallback<DiffEntity> {

    /**
     * Determine if it is the same item
     * <p>
     * 判断是否是同一个item
     *
     * @param oldItem New data
     * @param newItem old Data
     * @return
     */
    @Override
    public boolean areItemsTheSame(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) {
        return oldItem.getId() == newItem.getId();
    }

    /**
     * When it is the same item, judge whether the content has changed.
     * <p>
     * 当是同一个item时,再判断内容是否发生改变
     *
     * @param oldItem New data
     * @param newItem old Data
     * @return
     */
    @Override
    public boolean areContentsTheSame(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) {
        return oldItem.getTitle().equals(newItem.getTitle())
                && oldItem.getContent().equals(newItem.getContent())
                && oldItem.getDate().equals(newItem.getDate());
    }

    /**
     * Optional implementation
     * Implement this method if you need to precisely modify the content of a view.
     * If this method is not implemented, or if null is returned, the entire item will be refreshed.
     *
     * 可选实现
     * 如果需要精确修改某一个view中的内容,请实现此方法。
     * 如果不实现此方法,或者返回null,将会直接刷新整个item。
     *
     * @param oldItem Old data
     * @param newItem New data
     * @return Payload info. if return null, the entire item will be refreshed.
     */
    @Override
    public Object getChangePayload(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) {
        return null;
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffUtilAdapter.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter;

import android.content.Context;
import android.view.ViewGroup;

import androidx.annotation.NonNull;

import com.chad.baserecyclerviewadapterhelper.R;
import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity;
import com.chad.library.adapter4.BaseQuickAdapter;
import com.chad.library.adapter4.viewholder.QuickViewHolder;

/**
 * Create adapter
 */
public class DiffUtilAdapter extends BaseQuickAdapter<DiffEntity, QuickViewHolder> {

    public DiffUtilAdapter() {
        super(new DiffEntityCallback());
    }


    @NonNull
    @Override
    protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {
        return new QuickViewHolder(R.layout.layout_animation, parent);
    }

    @Override
    protected void onBindViewHolder(@NonNull QuickViewHolder holder, int position, DiffEntity item) {
        holder.setText(R.id.tweetName, item.getTitle())
                .setText(R.id.tweetText, item.getContent())
                .setText(R.id.tweetDate, item.getDate());
    }

}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DefaultDragAndSwipeActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.dragswipe

import android.animation.ValueAnimator
import android.graphics.Canvas
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.DragAndSwipeAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding
import com.chad.baserecyclerviewadapterhelper.utils.Tips
import com.chad.baserecyclerviewadapterhelper.utils.vibrate
import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe
import com.chad.library.adapter4.dragswipe.listener.OnItemDragListener
import com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener
import com.chad.library.adapter4.viewholder.QuickViewHolder

/**
 * 默认实现拖动与侧滑效果
 * Drag and Drag effects are implemented by default
 */
class DefaultDragAndSwipeActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {

    private val mAdapter: DragAndSwipeAdapter = DragAndSwipeAdapter()

    private val quickDragAndSwipe = QuickDragAndSwipe()
        .setDragMoveFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN or
                ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)
        .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)

    override fun initBinding(): ActivityUniversalRecyclerBinding =
        ActivityUniversalRecyclerBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        viewBinding.titleBar.title = "Default Drag And Swipe"
        viewBinding.titleBar.setOnBackListener { finish() }

        viewBinding.rv.layoutManager = GridLayoutManager(this,3)
        viewBinding.rv.adapter = mAdapter

        val mData = generateData(50)
        mAdapter.submitList(mData)

        // 拖拽监听
        val listener: OnItemDragListener = object : OnItemDragListener {
            override fun onItemDragStart(viewHolder: RecyclerView.ViewHolder?, pos: Int) {
                vibrate()
                Log.d(TAG, "drag start")
                val holder = viewHolder as QuickViewHolder? ?: return
                // 开始时,item背景色变化,demo这里使用了一个动画渐变,使得自然
                val startColor = Color.WHITE
                val endColor = Color.rgb(245, 245, 245)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    val v = ValueAnimator.ofArgb(startColor, endColor)
                    v.addUpdateListener { animation: ValueAnimator ->
                        holder.itemView.setBackgroundColor(
                            animation.animatedValue as Int
                        )
                    }
                    v.duration = 300
                    v.start()
                }
            }

            override fun onItemDragMoving(
                source: RecyclerView.ViewHolder,
                from: Int,
                target: RecyclerView.ViewHolder,
                to: Int
            ) {
                Log.d(
                    TAG,
                    "move from: " + source.bindingAdapterPosition + " to: " + target.bindingAdapterPosition
                )
            }

            override fun onItemDragEnd(viewHolder: RecyclerView.ViewHolder, pos: Int) {
                Log.d(TAG, "drag end")
                val holder = viewHolder as QuickViewHolder
                // 结束时,item背景色变化,demo这里使用了一个动画渐变,使得自然
                val startColor = Color.rgb(245, 245, 245)
                val endColor = Color.WHITE
                // 动画
                val v = ValueAnimator.ofArgb(startColor, endColor)
                v.addUpdateListener { animation: ValueAnimator ->
                    holder.itemView.setBackgroundColor(
                        animation.animatedValue as Int
                    )
                }
                v.duration = 300
                v.start()

                mAdapter.items.forEach {
                    Log.d(
                        TAG,
                        "-------->> w 顺序 ${it} "
                    )
                }

            }
        }
        val swipeListener: OnItemSwipeListener = object : OnItemSwipeListener {
            override fun onItemSwipeStart(viewHolder: RecyclerView.ViewHolder?, bindingAdapterPosition: Int) {
                Log.d(TAG, "onItemSwipeStart")
            }

            override fun onItemSwipeEnd(viewHolder: RecyclerView.ViewHolder, bindingAdapterPosition: Int) {
                Log.d(TAG, "onItemSwipeEnd: " + bindingAdapterPosition)
            }

            override fun onItemSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int, bindingAdapterPosition: Int) {
                Log.d(TAG, "onItemSwiped")
            }

            override fun onItemSwipeMoving(
                canvas: Canvas,
                viewHolder: RecyclerView.ViewHolder,
                dX: Float,
                dY: Float,
                isCurrentlyActive: Boolean
            ) {
                Log.d(TAG, "onItemSwipeMoving")
            }
        }

        // 滑动事件
        quickDragAndSwipe.attachToRecyclerView(viewBinding.rv)
            .setDataCallback(mAdapter)
            .setItemDragListener(listener)
            .setItemSwipeListener(swipeListener)

        // 点击事件
        mAdapter.setOnItemClickListener { adapter, view, position ->
            Tips.show("点击了:$position")
        }
    }

    private fun generateData(size: Int): List<String> {
        val data = ArrayList<String>(size)
        for (i in 0 until size) {
            data.add("item $i")
        }
        return data
    }

    companion object {
        private const val TAG = "Default Drag And Swipe"
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeDifferActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.dragswipe

import android.animation.ValueAnimator
import android.graphics.Canvas
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.DiffDragAndSwipeAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.data.DataServer
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding
import com.chad.baserecyclerviewadapterhelper.utils.vibrate
import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe
import com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback
import com.chad.library.adapter4.dragswipe.listener.OnItemDragListener
import com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener
import com.chad.library.adapter4.viewholder.QuickViewHolder

/**
 * Created by limuyang
 * Date: 2019/7/14O
 *
 * DiffAdapter DragAndSwipe
 */
class DragAndSwipeDifferActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {

    private var mAdapter: DiffDragAndSwipeAdapter = DiffDragAndSwipeAdapter()

    private var quickDragAndSwipe = QuickDragAndSwipe()
        .setDragMoveFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN)
        .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)

    override fun initBinding(): ActivityUniversalRecyclerBinding =
        ActivityUniversalRecyclerBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        viewBinding.titleBar.title = "Diff Drag Swipe Use"
        viewBinding.titleBar.setOnBackListener { finish() }

        viewBinding.rv.layoutManager = LinearLayoutManager(this)
        initRv()

        initDrag()
    }

    private fun initRv() {
        viewBinding.rv.adapter = mAdapter

        mAdapter.submitList(DataServer.diffUtilDemoEntities)
    }


    private fun initDrag() {
        // 拖拽监听
        val listener: OnItemDragListener = object :
            OnItemDragListener {
            override fun onItemDragStart(viewHolder: RecyclerView.ViewHolder?, pos: Int) {
                vibrate()
                Log.d(TAG, "drag start")
                val holder = viewHolder as QuickViewHolder
                // 开始时,item背景色变化,demo这里使用了一个动画渐变,使得自然
                val startColor = Color.WHITE
                val endColor = Color.rgb(245, 245, 245)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    val v = ValueAnimator.ofArgb(startColor, endColor)
                    v.addUpdateListener { animation: ValueAnimator ->
                        holder.itemView.setBackgroundColor(
                            animation.animatedValue as Int
                        )
                    }
                    v.duration = 300
                    v.start()
                }
            }

            override fun onItemDragMoving(
                source: RecyclerView.ViewHolder,
                from: Int,
                target: RecyclerView.ViewHolder,
                to: Int
            ) {
                Log.d(
                    TAG, "move from: " + source.bindingAdapterPosition + " to: " + target.bindingAdapterPosition
                )
            }

            override fun onItemDragEnd(viewHolder: RecyclerView.ViewHolder, pos: Int) {
                Log.d(TAG, "drag end")
                val holder = viewHolder as QuickViewHolder
                // 结束时,item背景色变化,demo这里使用了一个动画渐变,使得自然
                val startColor = Color.rgb(245, 245, 245)
                val endColor = Color.WHITE
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    val v = ValueAnimator.ofArgb(startColor, endColor)
                    v.addUpdateListener { animation: ValueAnimator ->
                        holder.itemView.setBackgroundColor(
                            animation.animatedValue as Int
                        )
                    }
                    v.duration = 300
                    v.start()
                }
            }
        }

        val swipeListener: OnItemSwipeListener = object :
            OnItemSwipeListener {
            override fun onItemSwipeStart(viewHolder: RecyclerView.ViewHolder?, bindingAdapterPosition: Int) {
                Log.d(TAG, "onItemSwipeStart")
            }

            override fun onItemSwipeEnd(viewHolder: RecyclerView.ViewHolder, bindingAdapterPosition: Int) {
                Log.d(TAG, "onItemSwipeEnd")
            }

            override fun onItemSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int, bindingAdapterPosition: Int) {
                Log.d(TAG, "onItemSwiped")
            }

            override fun onItemSwipeMoving(
                canvas: Canvas,
                viewHolder: RecyclerView.ViewHolder,
                dX: Float,
                dY: Float,
                isCurrentlyActive: Boolean
            ) {
                Log.d(TAG, "onItemSwipeMoving")
            }
        }



        quickDragAndSwipe.attachToRecyclerView(viewBinding.rv)
            .setDataCallback(object : DragAndSwipeDataCallback {
                override fun dataMove(fromPosition: Int, toPosition: Int) {
                    mAdapter.swap(fromPosition, toPosition)
                }

                override fun dataRemoveAt(position: Int) {
                    mAdapter.removeAt(position)
                }
            })
            .setItemDragListener(listener)
            .setItemSwipeListener(swipeListener)
    }

    companion object {
        private const val TAG = "Diff Drag Swipe Use"
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeUseActivity.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity.dragswipe;


import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.core.graphics.Insets;
import androidx.core.view.OnApplyWindowInsetsListener;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.chad.baserecyclerviewadapterhelper.R;
import com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeAdapter;
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity;
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding;
import com.chad.baserecyclerviewadapterhelper.entity.HomeEntity;

import java.util.ArrayList;


public class DragAndSwipeUseActivity extends BaseViewBindingActivity<ActivityUniversalRecyclerBinding> {
    private final ArrayList<HomeEntity> homeItemData = new ArrayList<>();

    @NonNull
    @Override
    public ActivityUniversalRecyclerBinding initBinding() {
        return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() {
            @Override
            public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {
                Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                getViewBinding().titleBar.updateFakeBarHeight(bar.top);
                return insets;
            }
        });

        getViewBinding().titleBar.setTitle("Drag And Swipe");
        getViewBinding().titleBar.setOnBackListener(v -> finish());

        // 设置数据
        homeItemData.add(new HomeEntity("Default Drag And Swipe", DefaultDragAndSwipeActivity.class, R.mipmap.gv_drag_and_swipe, ""));
        homeItemData.add(new HomeEntity("Manual Drag And Swipe", ManualDragAndSwipeUseActivity.class, R.mipmap.gv_drag_and_swipe, ""));
        homeItemData.add(new HomeEntity("Head Drag And Swipe", HeaderDragAndSwipeActivity.class, R.mipmap.gv_drag_and_swipe, ""));
        homeItemData.add(new HomeEntity("Diff Drag And Swipe", DragAndSwipeDifferActivity.class, R.mipmap.gv_drag_and_swipe, ""));

        /*
         * RV适配器
         */
        HomeAdapter mAdapter = new HomeAdapter(homeItemData);


        getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this));
        getViewBinding().rv.setAdapter(mAdapter);

        mAdapter.setOnItemClickListener((adapter, view, position) -> {
            HomeEntity item = adapter.getItems().get(position);
            if (!item.isSection()) {
                startActivity(new Intent(DragAndSwipeUseActivity.this, item.getActivity()));
            }
        });
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipe.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.dragswipe

import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.HeaderDragAndSwipeAdapter
import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe

/**
 * 重写拖拽类,根据itemType 设置某个类型的是否允许拖拽
 */
class HeaderDragAndSwipe : QuickDragAndSwipe() {

    override fun getMovementFlags(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder
    ): Int {
        if (recyclerView.adapter is ConcatAdapter) {
            val adapter = recyclerView.adapter as ConcatAdapter
            val absoluteAdapter =
                adapter.getWrappedAdapterAndPosition(viewHolder.absoluteAdapterPosition).first
            if (absoluteAdapter is HeaderDragAndSwipeAdapter) {
                return super.getMovementFlags(recyclerView, viewHolder)
            }
            return makeMovementFlags(0, 0)
        }
        return makeMovementFlags(0, 0)
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipeActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.dragswipe

import android.animation.ValueAnimator
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.HeaderDragAndSwipeAdapter
import com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeTopHeaderAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding
import com.chad.baserecyclerviewadapterhelper.utils.vibrate
import com.chad.library.adapter4.QuickAdapterHelper
import com.chad.library.adapter4.dragswipe.setItemDragListener
import com.chad.library.adapter4.dragswipe.setItemSwipeListener
import com.chad.library.adapter4.loadState.LoadState.NotLoading
import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * 带头部局以及带加载下一页的,拖拽demo
 */
class HeaderDragAndSwipeActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {


    private val pageInfo = PageInfo()

    internal class PageInfo {
        var page = 0
        fun nextPage() {
            page++
        }

        fun reset() {
            page = 0
        }

        val isFirstPage: Boolean
            get() = page == 0
    }

    var headerDragAndSwipe = HeaderDragAndSwipe()
        .setDragMoveFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN)
        .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)

    private val mAdapter: HeaderDragAndSwipeAdapter = HeaderDragAndSwipeAdapter()
    private lateinit var helper: QuickAdapterHelper

    override fun initBinding(): ActivityUniversalRecyclerBinding =
        ActivityUniversalRecyclerBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        viewBinding.titleBar.title = "Head Drag And Swipe"
        viewBinding.titleBar.setOnBackListener { finish() }

        viewBinding.rv.layoutManager = LinearLayoutManager(this)


        helper = QuickAdapterHelper.Builder(mAdapter)
            .setTrailingLoadStateAdapter(
                object : TrailingLoadStateAdapter.OnTrailingListener {
                    override fun onLoad() {
                        loadMore()
                    }

                    override fun onFailRetry() {
                    }

                    override fun isAllowLoading(): Boolean {
                        return true
                    }
                })
            .build()
            .addBeforeAdapter(HomeTopHeaderAdapter())

        headerDragAndSwipe.attachToRecyclerView(viewBinding.rv)
            .setDataCallback(mAdapter)
            .setItemDragListener(
                onItemDragStart = { viewHolder, pos ->
                    Log.d(TAG, "drag start")
                    vibrate()
                    val holder = viewHolder as QuickViewHolder
                    // 开始时,item背景色变化,demo这里使用了一个动画渐变,使得自然
                    val startColor = Color.WHITE
                    val endColor = Color.rgb(245, 245, 245)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        ValueAnimator.ofArgb(startColor, endColor).apply {
                            addUpdateListener { animation: ValueAnimator ->
                                holder.itemView.setBackgroundColor(
                                    animation.animatedValue as Int
                                )
                            }
                            duration = 300
                            start()
                        }
                    }
                },
                onItemDragMoving = { source, from, target, to ->
                    Log.d(TAG, "move from: $from  to:  $to")
                },
                onItemDragEnd = { viewHolder, pos ->
                    Log.d(TAG, "drag end")
                    val holder = viewHolder as QuickViewHolder
                    // 结束时,item背景色变化,demo这里使用了一个动画渐变,使得自然
                    val startColor = Color.rgb(245, 245, 245)
                    val endColor = Color.WHITE
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        ValueAnimator.ofArgb(startColor, endColor).apply {
                            addUpdateListener { animation: ValueAnimator ->
                                holder.itemView.setBackgroundColor(
                                    animation.animatedValue as Int
                                )
                            }
                            duration = 300
                            start()
                        }
                    }
                }

            )
            .setItemSwipeListener(
                onItemSwipeStart = { viewHolder, pos ->
                    Log.d(TAG, "onItemSwipeStart")
                },
                onItemSwipeMoving = { canvas, viewHolder, dX, dY, isCurrentlyActive ->
                    Log.d(TAG, "onItemSwipeMoving")
                },
                onItemSwiped = { viewHolder, _, pos ->
                    Log.d(TAG, "onItemSwiped")
                },
                onItemSwipeEnd = { viewHolder, pos ->
                    Log.d(TAG, "onItemSwipeEnd")
                }
            )
        viewBinding.rv.adapter = helper.adapter
        loadMore()
    }


    private fun loadMore() {
        Request(pageInfo.page, object : RequestCallBack {
            override fun success(data: List<String>) {
                if (pageInfo.page == 0) {
                    mAdapter.submitList(data)
                } else {
                    mAdapter.addAll(data)
                }

                helper.trailingLoadState = NotLoading(false)
                // page加一
                pageInfo.nextPage()
            }

            override fun fail(e: Exception?) {

            }

            override fun end() {
                helper.trailingLoadState = NotLoading(true)
            }
        }).loadMore()
    }

    /**
     * 模拟加载数据的类,不用特别关注
     */
    internal class Request(
        private val mPage: Int,
        private val mCallBack: RequestCallBack
    ) {

        fun loadMore() {
            GlobalScope.launch(Dispatchers.IO) {
                if (mPage != 0) {
                    delay(1500)
                }
                withContext(Dispatchers.Main) {
                    val size = PAGE_SIZE
                    if (mPage == 3) {
                        mCallBack.end()
                    } else {
                        val starIndex = mPage.times(size)
                        mCallBack.success(generateData(starIndex, size))
                    }
                }
            }
        }

        private fun generateData(starIndex: Int, size: Int): List<String> {
            val data = java.util.ArrayList<String>(size)
            val endIndex = starIndex.plus(size)
            for (i in starIndex until endIndex) {
                data.add("item $i")
            }
            return data
        }

    }

    internal interface RequestCallBack {
        /**
         * 模拟加载成功
         *
         * @param data 数据
         */
        fun success(data: List<String>)

        /**
         * 模拟加载失败
         *
         * @param e 错误信息
         */
        fun fail(e: Exception?)

        /**
         * 模拟加载结束
         */
        fun end()
    }

    companion object {
        private const val PAGE_SIZE = 20
        private const val TAG = "Default Drag And Swipe"
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/ManualDragAndSwipeUseActivity.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity.dragswipe;

import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.Insets;
import androidx.core.view.OnApplyWindowInsetsListener;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.DragAndSwipeAdapter;
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity;
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding;
import com.chad.baserecyclerviewadapterhelper.utils.Tips;
import com.chad.baserecyclerviewadapterhelper.utils.VibratorUtilsKt;
import com.chad.library.adapter4.QuickAdapterHelper;
import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe;
import com.chad.library.adapter4.dragswipe.listener.OnItemDragListener;
import com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener;
import com.chad.library.adapter4.viewholder.QuickViewHolder;

import java.util.ArrayList;
import java.util.List;

/**
 * 手动实现拖动与侧滑效果
 * Manual drag and Drag effects
 */
public class ManualDragAndSwipeUseActivity extends BaseViewBindingActivity<ActivityUniversalRecyclerBinding> {

    private final String TAG = "Manual Drag And Swipe";

    private DragAndSwipeAdapter mAdapter;
    private QuickAdapterHelper helper;

    QuickDragAndSwipe quickDragAndSwipe = new QuickDragAndSwipe()
            .setDragMoveFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN)
            .setSwipeMoveFlags(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)
            .setItemViewSwipeEnabled(true)
            .setLongPressDragEnabled(false);//关闭默认的长按拖拽功能,通过自定义长按事件进行拖拽

    @NonNull
    @Override
    public ActivityUniversalRecyclerBinding initBinding() {
        return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() {
            @Override
            public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {
                Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                getViewBinding().titleBar.updateFakeBarHeight(bar.top);
                return insets;
            }
        });

        getViewBinding().titleBar.setTitle("Manual Drag And Swipe");
        getViewBinding().titleBar.setOnBackListener(v -> finish());


        getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this));

        // 拖拽监听
        OnItemDragListener listener = new OnItemDragListener() {
            @Override
            public void onItemDragStart(@Nullable RecyclerView.ViewHolder viewHolder, int pos) {
                VibratorUtilsKt.vibrate(getApplicationContext());
                Log.d(TAG, "drag start");
                final QuickViewHolder holder = ((QuickViewHolder) viewHolder);
                if (holder == null) return;
                // 开始时,item背景色变化,demo这里使用了一个动画渐变,使得自然
                int startColor = Color.WHITE;
                int endColor = Color.rgb(245, 245, 245);
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                    ValueAnimator v = ValueAnimator.ofArgb(startColor, endColor);
                    v.addUpdateListener(animation -> holder.itemView.setBackgroundColor((int) animation.getAnimatedValue()));
                    v.setDuration(300);
                    v.start();
                }
            }

            @Override
            public void onItemDragMoving(@NonNull RecyclerView.ViewHolder source, int from, @NonNull RecyclerView.ViewHolder target, int to) {
                Log.d(TAG, "move from: " + source.getBindingAdapterPosition() + " to: " + target.getBindingAdapterPosition());
            }

            @Override
            public void onItemDragEnd(@NonNull RecyclerView.ViewHolder viewHolder, int pos) {
                Log.d(TAG, "drag end");
                final QuickViewHolder holder = ((QuickViewHolder) viewHolder);
                // 结束时,item背景色变化,demo这里使用了一个动画渐变,使得自然
                int startColor = Color.rgb(245, 245, 245);
                int endColor = Color.WHITE;
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                    ValueAnimator v = ValueAnimator.ofArgb(startColor, endColor);
                    v.addUpdateListener(animation -> holder.itemView.setBackgroundColor((int) animation.getAnimatedValue()));
                    v.setDuration(300);
                    v.start();
                }
            }
        };

        OnItemSwipeListener swipeListener = new OnItemSwipeListener() {
            @Override
            public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int bindingAdapterPosition) {
                Log.d(TAG, "onItemSwipeStart");
            }

            @Override
            public void onItemSwipeEnd(@NonNull RecyclerView.ViewHolder viewHolder, int bindingAdapterPosition) {
                Log.d(TAG, "onItemSwipeEnd " + bindingAdapterPosition);
            }

            @Override
            public void onItemSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction, int bindingAdapterPosition) {
                Log.d(TAG,  "onItemSwiped");
            }

            @Override
            public void onItemSwipeMoving(@NonNull Canvas canvas, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {
                Log.d(TAG, "onItemSwipeMoving");
            }
        };

        List<String> mData = generateData(50);
        mAdapter = new DragAndSwipeAdapter();
        helper = new QuickAdapterHelper.Builder(mAdapter)
                .build();
        getViewBinding().rv.setAdapter(helper.getAdapter());
        mAdapter.submitList(mData);
        quickDragAndSwipe.attachToRecyclerView(getViewBinding().rv)
                .setDataCallback(mAdapter)
                .setItemDragListener(listener)
                .setItemSwipeListener(swipeListener);
        mAdapter.setOnItemClickListener((adapter, view, position) -> {
            Tips.show("点击了:" + position + ",侧滑可进行删除" + position);
            quickDragAndSwipe.startSwipe(position);
        });
        mAdapter.setOnItemLongClickListener((adapter, view, position) -> {
            /*
             * 长按默认可拖动,可不进行设置此方法
             * 此方法可以做特殊使用进行调用
             * 如:长按此条position对应的item,触发 position+1 对应的item
             * 此处使用,关闭了默认长按拖拽功能
             */
            Tips.show("长按了:" + position + ",现在拖动可进行变换位置");
            quickDragAndSwipe.startDrag(position);
            return false;
        });
    }

    private List<String> generateData(int size) {
        ArrayList<String> data = new ArrayList<>(size);
        for (int i = 0; i < size; i++) {
            data.add("item " + i);
        }
        return data;
    }
}




================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DiffDragAndSwipeAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter

import android.content.Context
import android.view.ViewGroup
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.activity.differ.adapter.DiffEntityCallback
import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder

/**
 * Create adapter
 */
class DiffDragAndSwipeAdapter :
    BaseQuickAdapter<DiffEntity, QuickViewHolder>(DiffEntityCallback()) {

    override fun onCreateViewHolder(
        context: Context, parent: ViewGroup, viewType: Int
    ): QuickViewHolder {
        return QuickViewHolder(R.layout.layout_animation, parent)
    }

    override fun onBindViewHolder(
        holder: QuickViewHolder, position: Int, item: DiffEntity?
    ) {
        if (item == null) return

        holder.setText(R.id.tweetName, item.title)
            .setText(R.id.tweetText, item.content)
            .setText(R.id.tweetDate, item.date)
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DragAndSwipeAdapter.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter;


import android.content.Context;
import android.view.ViewGroup;

import androidx.annotation.NonNull;

import com.chad.baserecyclerviewadapterhelper.R;
import com.chad.library.adapter4.BaseQuickAdapter;
import com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback;
import com.chad.library.adapter4.viewholder.QuickViewHolder;

public class DragAndSwipeAdapter extends BaseQuickAdapter<String, QuickViewHolder> implements DragAndSwipeDataCallback {

    @NonNull
    @Override
    protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {
        return new QuickViewHolder(R.layout.item_draggable_view, parent);
    }

    @Override
    protected void onBindViewHolder(@NonNull QuickViewHolder holder, int position, String item) {
        switch (holder.getLayoutPosition() % 3) {
            case 0 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img0);
            case 1 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img1);
            case 2 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img2);
            default -> {
            }
        }
        holder.setText(R.id.tv, item);
    }

    @Override
    public void dataMove(int fromPosition, int toPosition) {
        move(fromPosition, toPosition);
    }

    @Override
    public void dataRemoveAt(int position) {
        removeAt(position);
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/HeaderDragAndSwipeAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter

import android.content.Context
import android.view.ViewGroup
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback

/**
 * kotlin方式集成案例
 */
open class HeaderDragAndSwipeAdapter : BaseQuickAdapter<String, QuickViewHolder>(),
    DragAndSwipeDataCallback {

    override fun onCreateViewHolder(
        context: Context,
        parent: ViewGroup,
        viewType: Int
    ): QuickViewHolder {
        return QuickViewHolder(R.layout.item_draggable_view, parent)
    }

     override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: String?) {
        when (holder.layoutPosition % 3) {
            0 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img0)
            1 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img1)
            2 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img2)
            else -> {}
        }
        holder.setText(R.id.tv, item)
    }

    override fun dataMove(fromPosition: Int, toPosition: Int) {
        move(fromPosition, toPosition)
    }

    override fun dataRemoveAt(position: Int) {
        removeAt(position)
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/EmptyViewUseActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.emptyview

import android.os.Bundle
import android.view.View
import android.widget.FrameLayout
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.activity.emptyview.adapter.EmptyViewAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.data.DataServer
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityEmptyViewUseBinding

class EmptyViewUseActivity : BaseViewBindingActivity<ActivityEmptyViewUseBinding>() {

    private val mAdapter = EmptyViewAdapter()

    private var mError = true
    private var mNoData = true

    override fun initBinding(): ActivityEmptyViewUseBinding =
        ActivityEmptyViewUseBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        viewBinding.titleBar.title = "EmptyView Use"
        viewBinding.titleBar.setOnBackListener { finish() }

        viewBinding.btnReset.setOnClickListener { reset() }

        viewBinding.rvList.adapter = mAdapter
        viewBinding.rvList.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)

        // 打开空布局功能
        mAdapter.isStateViewEnable = true
        mAdapter.isUseStateViewSize = true

        onRefresh()
    }

    private fun reset() {
        mError = true
        mNoData = true
        mAdapter.submitList(null)
        onRefresh()
    }

    private val emptyDataView: View
        get() {
            val notDataView = layoutInflater.inflate(R.layout.empty_view, FrameLayout(this), false)
            notDataView.setOnClickListener { onRefresh() }
            return notDataView
        }

    private val errorView: View
        get() {
            val errorView = layoutInflater.inflate(R.layout.error_view, FrameLayout(this), false)
            errorView.setOnClickListener { onRefresh() }
            return errorView
        }

    private fun onRefresh() {
        // 方式一:直接传入 layout id
        mAdapter.setStateViewLayout(this, R.layout.loading_view)

        viewBinding.rvList.postDelayed({
            if (mError) { // 模拟网络错误
                // 方式二:传入View
                mAdapter.stateView = errorView

                mError = false
            } else {
                if (mNoData) { // 模拟接口没有数据
                    mAdapter.stateView = emptyDataView
                    mNoData = false
                } else {
                    // 模拟正常数据返回
                    mAdapter.submitList(DataServer.getSampleData(10))
                }
            }
        }, 1000)
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/adapter/EmptyViewAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.emptyview.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.databinding.LayoutAnimationBinding
import com.chad.baserecyclerviewadapterhelper.entity.Status
import com.chad.library.adapter4.BaseQuickAdapter

class EmptyViewAdapter : BaseQuickAdapter<Status, EmptyViewAdapter.VH>() {

    class VH(
        parent: ViewGroup,
        val binding: LayoutAnimationBinding = LayoutAnimationBinding.inflate(
            LayoutInflater.from(parent.context), parent, false
        ),
    ) : RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
        return VH(parent)
    }

    override fun onBindViewHolder(holder: VH, position: Int, item: Status?) {
        if (item == null) return
        holder.binding.img.setImageResource(item.userAvatar)
        holder.binding.tweetName.text = item.userName
        holder.binding.tweetText.text = "O ever youthful,O ever weeping"
    }

}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/HeaderAndFooterUseActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.headerfooter

import android.os.Bundle
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.FooterAdapter
import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter
import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAndFooterAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.data.DataServer
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding
import com.chad.baserecyclerviewadapterhelper.utils.Tips
import com.chad.library.adapter4.QuickAdapterHelper

/**
 * https://github.com/CymChad/BaseRecyclerViewAdapterHelper
 */
class HeaderAndFooterUseActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {

    private lateinit var helper: QuickAdapterHelper

    override fun initBinding(): ActivityUniversalRecyclerBinding =
        ActivityUniversalRecyclerBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        viewBinding.titleBar.title = "Header And Footer Use"
        viewBinding.titleBar.setOnBackListener { finish() }


        val adapter = HeaderAndFooterAdapter(DataServer.getSampleData(PAGE_SIZE))
        adapter.setOnItemClickListener { _, _, position ->
            Tips.show("position: $position")
        }


        helper = QuickAdapterHelper.Builder(adapter)
            .build()

        viewBinding.rv.layoutManager = LinearLayoutManager(this)
        viewBinding.rv.adapter = helper.adapter
        addHeader()

        helper.addAfterAdapter(
            FooterAdapter(false).setOnItemClickListener { _, _, _ ->
                addFooter()
            }
        )
    }

    private fun addHeader() {
        helper.addBeforeAdapter(0, HeaderAdapter().apply {
            setOnItemClickListener { _, _, _ ->
                addHeader()
            }
        })
    }

    private fun addFooter() {
        helper.addAfterAdapter(FooterAdapter(true).setOnItemClickListener{ adapter, _, _ ->
            helper.removeAdapter(adapter)
        })
    }

    companion object {
        private const val PAGE_SIZE = 3
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/FooterAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter

import android.content.Context
import android.view.ViewGroup
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.library.adapter4.BaseSingleItemAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder

class FooterAdapter(
    private val isDelete: Boolean
) : BaseSingleItemAdapter<Any, QuickViewHolder>() {

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): QuickViewHolder {
        return QuickViewHolder(R.layout.footer_view, parent)
    }

    override fun onBindViewHolder(holder: QuickViewHolder, item: Any?) {
        if (isDelete) {
            holder.setImageResource(R.id.iv, R.mipmap.rm_icon)
        }
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.library.adapter4.BaseSingleItemAdapter

class HeaderAdapter: BaseSingleItemAdapter<Any, HeaderAdapter.VH>() {

    class VH(view: View): RecyclerView.ViewHolder(view)

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.head_view, parent, false)
        return VH(view)
    }

    override fun onBindViewHolder(holder: VH, item: Any?) {

    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAndFooterAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.databinding.ItemHeaderAndFooterBinding
import com.chad.baserecyclerviewadapterhelper.entity.Status
import com.chad.library.adapter4.BaseQuickAdapter

/**
 * https://github.com/CymChad/BaseRecyclerViewAdapterHelper
 */
class HeaderAndFooterAdapter(list: List<Status>) :
    BaseQuickAdapter<Status, HeaderAndFooterAdapter.VH>(list) {

    class VH(var binding: ItemHeaderAndFooterBinding) : RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
        val binding =
            ItemHeaderAndFooterBinding.inflate(LayoutInflater.from(context), parent, false)
        return VH(binding)
    }

    override fun onBindViewHolder(holder: VH, position: Int, item: Status?) {
        when (holder.layoutPosition % 3) {
            0 -> holder.binding.iv.setImageResource(R.mipmap.animation_img1)
            1 -> holder.binding.iv.setImageResource(R.mipmap.animation_img2)
            2 -> holder.binding.iv.setImageResource(R.mipmap.animation_img3)
            else -> {}
        }
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/HomeActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.home

import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.activity.animation.AnimationUseActivity
import com.chad.baserecyclerviewadapterhelper.activity.databinding.DataBindingUseActivity
import com.chad.baserecyclerviewadapterhelper.activity.differ.DifferActivity
import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.DragAndSwipeUseActivity
import com.chad.baserecyclerviewadapterhelper.activity.emptyview.EmptyViewUseActivity
import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.HeaderAndFooterUseActivity
import com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeAdapter
import com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeTopHeaderAdapter
import com.chad.baserecyclerviewadapterhelper.activity.itemclick.ItemClickActivity
import com.chad.baserecyclerviewadapterhelper.activity.loadmore.AutoLoadMoreRefreshUseActivity
import com.chad.baserecyclerviewadapterhelper.activity.loadmore.NoAutoAutoLoadMoreRefreshUseActivity
import com.chad.baserecyclerviewadapterhelper.activity.node.NodeActivity
import com.chad.baserecyclerviewadapterhelper.activity.scene.GroupDemoActivity
import com.chad.baserecyclerviewadapterhelper.activity.upfetch.UpFetchUseActivity
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityHomeBinding
import com.chad.baserecyclerviewadapterhelper.entity.HomeEntity
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.QuickAdapterHelper

class HomeActivity : AppCompatActivity(), BaseQuickAdapter.OnItemClickListener<HomeEntity> {

    private lateinit var binding: ActivityHomeBinding

    /**
     * RV适配器
     */
    private val homeAdapter by lazy(LazyThreadSafetyMode.NONE) {
        HomeAdapter(homeItemData)
    }

    private val helper by lazy(LazyThreadSafetyMode.NONE) {
        QuickAdapterHelper.Builder(homeAdapter)
            .build()
            .addBeforeAdapter(HomeTopHeaderAdapter())
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityHomeBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 从 QuickAdapterHelper 获取 adapter,设置给 RecycleView
        binding.recyclerView.adapter = helper.adapter

        // 设置点击事件
        homeAdapter.setOnItemClickListener(this)
    }

    /**
     * item 点击事件
     *
     * @param adapter
     * @param view
     * @param position
     */
    override fun onClick(
        adapter: BaseQuickAdapter<HomeEntity, *>,
        view: View,
        position: Int,
    ) {
        val item = adapter.getItem(position)
        if (!item.isSection) {
            startActivity(Intent(this@HomeActivity, item.activity))
        }
    }

    private val homeItemData: ArrayList<HomeEntity>
        get() = arrayListOf(
            HomeEntity(sectionTitle = "BaseQuickAdapter 基础功能"),
            HomeEntity("Animation", AnimationUseActivity::class.java, R.mipmap.gv_animation),
            HomeEntity(
                "Header/Footer",
                HeaderAndFooterUseActivity::class.java,
                R.mipmap.gv_header_and_footer
            ),
            HomeEntity("EmptyView", EmptyViewUseActivity::class.java, R.mipmap.gv_empty),
            HomeEntity("ItemClick", ItemClickActivity::class.java, R.mipmap.gv_item_click),
            HomeEntity("DataBinding", DataBindingUseActivity::class.java, R.mipmap.gv_databinding),
            HomeEntity("DiffUtil", DifferActivity::class.java, R.mipmap.gv_databinding),
            HomeEntity("Multi-node", NodeActivity::class.java, R.mipmap.gv_databinding),
//
            HomeEntity(sectionTitle = "功能模块"),
            HomeEntity("LoadMore(Auto)", AutoLoadMoreRefreshUseActivity::class.java, R.mipmap.gv_pulltorefresh),
            HomeEntity("LoadMore", NoAutoAutoLoadMoreRefreshUseActivity::class.java, R.mipmap.gv_pulltorefresh),
            HomeEntity("DragAndSwipe", DragAndSwipeUseActivity::class.java, R.mipmap.gv_drag_and_swipe),
            HomeEntity("UpFetch", UpFetchUseActivity::class.java, R.drawable.gv_up_fetch),


            HomeEntity(sectionTitle = "场景演示"),
            HomeEntity("Group(ConcatAdapter)", GroupDemoActivity::class.java, R.mipmap.gv_animation),
        )
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.home.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.databinding.DefSectionHeadBinding
import com.chad.baserecyclerviewadapterhelper.databinding.HomeItemViewBinding
import com.chad.baserecyclerviewadapterhelper.entity.HomeEntity
import com.chad.library.adapter4.BaseMultiItemAdapter

/**
 * https://github.com/CymChad/BaseRecyclerViewAdapterHelper
 */
class HomeAdapter(data: List<HomeEntity>) : BaseMultiItemAdapter<HomeEntity>(data) {

    class ItemVH(val viewBinding: HomeItemViewBinding) : RecyclerView.ViewHolder(viewBinding.root)

    class HeaderVH(val viewBinding: DefSectionHeadBinding) : RecyclerView.ViewHolder(viewBinding.root)

    init {
        addItemType(ITEM_TYPE, object : OnMultiItemAdapterListener<HomeEntity, ItemVH> {
            override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH {
                val viewBinding =
                    HomeItemViewBinding.inflate(LayoutInflater.from(context), parent, false)
                return ItemVH(viewBinding)
            }

            override fun onBind(holder: ItemVH, position: Int, item: HomeEntity?) {
                if (item == null) return
                holder.viewBinding.textView.text = item.name
                holder.viewBinding.icon.setImageResource(item.imageResource)
            }
        }).addItemType(SECTION_TYPE, object : OnMultiItemAdapterListener<HomeEntity, HeaderVH> {
            override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): HeaderVH {
                val viewBinding =
                    DefSectionHeadBinding.inflate(LayoutInflater.from(context), parent, false)
                return HeaderVH(viewBinding)
            }

            override fun onBind(holder: HeaderVH, position: Int, item: HomeEntity?) {
                if (item == null) return

                holder.viewBinding.more.visibility = View.GONE
                holder.viewBinding.header.text = item.sectionTitle
            }

            override fun isFullSpanItem(itemType: Int): Boolean {
                return true
            }

        }).onItemViewType { position, list ->
            if (list[position].isSection) {
                SECTION_TYPE
            } else {
                ITEM_TYPE
            }
        }
    }

    companion object {
        private const val ITEM_TYPE = 10
        private const val SECTION_TYPE = 11
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeTopHeaderAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.home.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.library.adapter4.BaseSingleItemAdapter
import com.chad.library.adapter4.fullspan.FullSpanAdapterType

class HomeTopHeaderAdapter : BaseSingleItemAdapter<Any, HomeTopHeaderAdapter.VH>(),
    FullSpanAdapterType {

    companion object {
        val HEAD_VIEWTYPE = 0x10000556
    }

    class VH(view: View) : RecyclerView.ViewHolder(view)

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
        return VH(LayoutInflater.from(parent.context).inflate(R.layout.top_view, parent, false))
    }

    override fun onBindViewHolder(holder: VH, item: Any?) {
    }

    override fun getItemViewType(position: Int, list: List<Any>): Int {
        return HEAD_VIEWTYPE
    }


}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/ItemClickActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.itemclick

import android.os.Bundle
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.activity.itemclick.adapter.ItemClickAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding
import com.chad.baserecyclerviewadapterhelper.entity.ClickEntity
import com.chad.baserecyclerviewadapterhelper.utils.Tips
import com.chad.library.adapter4.util.addOnDebouncedChildClick
import com.chad.library.adapter4.util.setOnDebouncedItemClick

/**
 * @author Allen
 */
class ItemClickActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {

    private val adapter: ItemClickAdapter by lazy(LazyThreadSafetyMode.NONE) {
        // 创建数据
        val data = ArrayList<ClickEntity>().apply {
            add(ClickEntity(ClickEntity.CLICK_ITEM_VIEW))
            add(ClickEntity(ClickEntity.CLICK_ITEM_CHILD_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))
            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))
        }
        // 创建Adapter
        ItemClickAdapter(data)
    }

    override fun initBinding(): ActivityUniversalRecyclerBinding =
        ActivityUniversalRecyclerBinding.inflate(layoutInflater)


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        viewBinding.titleBar.title = "Item Click Use"
        viewBinding.titleBar.setOnBackListener { finish() }
        viewBinding.rv.layoutManager = LinearLayoutManager(this)
        viewBinding.rv.adapter = adapter

        // 设置点击事件
        adapter.setOnItemClickListener { _, _, position ->
            Tips.show("onItemClick $position")
        }
        // 去除点击抖动的扩展方法
        adapter.setOnDebouncedItemClick {adapter, view, position ->
            Tips.show("onItemClick $position")
        }

        // 设置item 长按事件
        adapter.setOnItemLongClickListener { _, _, position ->
            Tips.show("onItemLongClick $position")
            true
        }

        // 添加子 view 的点击事件
        adapter.addOnItemChildClickListener(R.id.btn) { adapter, view, position ->
            Tips.show("onItemChildClick: $position")
        }
        adapter.addOnItemChildClickListener(R.id.iv_num_reduce) { adapter, view, position ->
            Tips.show("onItemChildClick:  reduce $position")
        }
        adapter.addOnItemChildClickListener(R.id.iv_num_add) { adapter, view, position ->
            Tips.show("onItemChildClick:  add $position")
            adapter.removeAt(position)
        }

        // 添加子 view 的点击事件(去除点击抖动的扩展方法)
        adapter.addOnDebouncedChildClick(R.id.btn) { adapter, view, position ->
            Tips.show("onItemChildClick: $position")
        }

        // 设置子 view 长按事件
        adapter.addOnItemChildLongClickListener(R.id.btn_long) { adapter, view, position ->
            Tips.show("onItemChildLongClick $position")
            true
        }
    }

}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/adapter/ItemClickAdapter.java
================================================
package com.chad.baserecyclerviewadapterhelper.activity.itemclick.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.baserecyclerviewadapterhelper.databinding.ItemClickChildviewBinding;
import com.chad.baserecyclerviewadapterhelper.databinding.ItemClickViewBinding;
import com.chad.baserecyclerviewadapterhelper.databinding.ItemLongClickChildviewBinding;
import com.chad.baserecyclerviewadapterhelper.databinding.ItemLongClickViewBinding;
import com.chad.baserecyclerviewadapterhelper.entity.ClickEntity;
import com.chad.library.adapter4.BaseMultiItemAdapter;

import java.util.List;

/**
 *
 */
public class ItemClickAdapter extends BaseMultiItemAdapter<ClickEntity> {

    static class ItemViewVH extends RecyclerView.ViewHolder {

        ItemClickViewBinding viewBinding;

        public ItemViewVH(@NonNull ItemClickViewBinding viewBinding) {
            super(viewBinding.getRoot());
            this.viewBinding = viewBinding;
        }

        public ItemViewVH(@NonNull ViewGroup parent) {
            this(ItemClickViewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
        }
    }

    static class ItemChildVH extends RecyclerView.ViewHolder {

        ItemClickChildviewBinding viewBinding;

        public ItemChildVH(@NonNull ItemClickChildviewBinding viewBinding) {
            super(viewBinding.getRoot());
            this.viewBinding = viewBinding;
        }

        public ItemChildVH(@NonNull ViewGroup parent) {
            this(ItemClickChildviewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
        }
    }

    static class ItemLongClickVH extends RecyclerView.ViewHolder {

        ItemLongClickViewBinding viewBinding;

        public ItemLongClickVH(@NonNull ItemLongClickViewBinding viewBinding) {
            super(viewBinding.getRoot());
            this.viewBinding = viewBinding;
        }

        public ItemLongClickVH(@NonNull ViewGroup parent) {
            this(ItemLongClickViewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
        }
    }

    static class ItemChildLongClickVH extends RecyclerView.ViewHolder {

        ItemLongClickChildviewBinding viewBinding;

        public ItemChildLongClickVH(@NonNull ItemLongClickChildviewBinding viewBinding) {
            super(viewBinding.getRoot());
            this.viewBinding = viewBinding;
        }

        public ItemChildLongClickVH(@NonNull ViewGroup parent) {
            this(ItemLongClickChildviewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
        }
    }

    /**
     * 构造方法
     */
    public ItemClickAdapter(List<ClickEntity> data) {
        super(data);

        addItemType(ClickEntity.CLICK_ITEM_VIEW, new OnMultiItemAdapterListener<ClickEntity, ItemViewVH>() {

            @NonNull
            @Override
            public ItemViewVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {
                return new ItemViewVH(parent);
            }

            @Override
            public void onBind(@NonNull ItemViewVH holder, int position, ClickEntity item) {
            }

            @Override
            public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
                if (holder instanceof ItemViewVH) {
                    System.out.println("---------------------- >> onViewDetachedFromWindow ItemViewVH");
                }
            }
        }).addItemType(ClickEntity.CLICK_ITEM_CHILD_VIEW, new OnMultiItemAdapterListener<ClickEntity, ItemChildVH>() {

            @NonNull
            @Override
            public ItemChildVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {
                return new ItemChildVH(parent);
            }

            @Override
            public void onBind(@NonNull ItemChildVH holder, int position, ClickEntity item) {
            }
        }).addItemType(ClickEntity.LONG_CLICK_ITEM_VIEW, new OnMultiItemAdapterListener<ClickEntity, ItemLongClickVH>() {

            @NonNull
            @Override
            public ItemLongClickVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {
                return new ItemLongClickVH(parent);
            }

            @Override
            public void onBind(@NonNull ItemLongClickVH holder, int position, ClickEntity item) {
            }
        }).addItemType(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW, new OnMultiItemAdapterListener<ClickEntity, ItemChildLongClickVH>() {

            @NonNull
            @Override
            public ItemChildLongClickVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {
                return new ItemChildLongClickVH(parent);
            }

            @Override
            public void onBind(@NonNull ItemChildLongClickVH holder, int position, ClickEntity item) {
            }
        }).onItemViewType(new OnItemViewTypeListener<ClickEntity>() {
            @Override
            public int onItemViewType(int position, @NonNull List<? extends ClickEntity> list) {
                return list.get(position).getItemType();
            }
        });

    }


}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/AutoLoadMoreRefreshUseActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.loadmore

import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter
import com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter.RecyclerViewAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.data.DataServer
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityLoadMoreBinding
import com.chad.baserecyclerviewadapterhelper.entity.Status
import com.chad.baserecyclerviewadapterhelper.utils.Tips
import com.chad.library.adapter4.QuickAdapterHelper
import com.chad.library.adapter4.loadState.LoadState
import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter.OnTrailingListener

/**
 * 自动加载更多
 */
class AutoLoadMoreRefreshUseActivity : BaseViewBindingActivity<ActivityLoadMoreBinding>() {
    internal class PageInfo {
        var page = 0
        fun nextPage() {
            page++
        }

        fun reset() {
            page = 0
        }

        val isFirstPage: Boolean
            get() = page == 0
    }

    private val pageInfo = PageInfo()

    private val mAdapter: RecyclerViewAdapter = RecyclerViewAdapter()
    private lateinit var helper: QuickAdapterHelper

    override fun initBinding(): ActivityLoadMoreBinding =
        ActivityLoadMoreBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            viewBinding.rvList.updatePadding(bottom = bar.bottom)
            insets
        }

        viewBinding.titleBar.title = "Auto LoadMore Use"
        viewBinding.titleBar.setOnBackListener { finish() }


        viewBinding.rvList.layoutManager = LinearLayoutManager(this)
        initAdapter()
        addHeadView()
        initRefreshLayout()
    }

    override fun onStart() {
        super.onStart()
        // 进入页面,先显示加载状态布局
        mAdapter.setEmptyViewLayout(this, R.layout.loading_view)
        viewBinding.refreshLayout.isRefreshing = true
        refresh()
    }

    private fun initAdapter() {
        // 使用默认的"加载更多"的样式
        helper = QuickAdapterHelper.Builder(mAdapter)
            .setTrailingLoadStateAdapter(object : OnTrailingListener {
                override fun onLoad() {
                    request()
                }

                override fun onFailRetry() {
                    request()
                }

                override fun isAllowLoading(): Boolean {
                    return !viewBinding.refreshLayout.isRefreshing
                }
            })
            .setTrailPreloadSize(0) // 预加载(默认值为0)
            .isTrailAutoLoadMore(true) // 是否自动加载更多(默认为true)
            .build()

        // 设置预加载,请调用以下方法
        // helper.trailingLoadStateAdapter?.preloadSize = 1
        viewBinding.rvList.adapter = helper.adapter
    }

    private fun addHeadView() {
        val headerAdapter = HeaderAdapter()
        headerAdapter.setOnItemClickListener { _, _, _ ->
            addHeadView()
        }
        helper.addBeforeAdapter(0, headerAdapter)
    }

    private fun initRefreshLayout() {
        viewBinding.refreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189))
        viewBinding.refreshLayout.setOnRefreshListener { refresh() }
    }

    /**
     * 刷新
     */
    private fun refresh() {
        // 下拉刷新,需要重置页数
        pageInfo.reset()
        // 重置“加载更多”时状态
        helper.trailingLoadState = LoadState.None
        request()
    }

    /**
     * 请求数据
     */
    private fun request() {

        Request(pageInfo.page, object : RequestCallBack {
            override fun success(data: List<Status>) {
                viewBinding.refreshLayout.isRefreshing = false
                if (pageInfo.isFirstPage) {
                    // 如果是加载的第一页数据,用 submitList()
                    // If it is the first page of data loaded, use submitList().
                    mAdapter.submitList(data)
                } else {
                    //不是第一页,则用add
                    mAdapter.addAll(data)
                }

                // 如果在数据不满足一屏时,暂停加载更多,请调用下面方法
                // helper.trailingLoadStateAdapter?.checkDisableLoadMoreIfNotFullPage()

                if (pageInfo.page >= PAGE_SIZE) {
                    /*
                    Set the status to not loaded, and there is no paging data.
                    设置状态为未加载,并且没有分页数据了
                     */
                    helper.trailingLoadState = LoadState.NotLoading(true)
                    Tips.show("no more data")
                } else {
                    /*
                    Set the state to not loaded, and there is also paginated data
                    设置状态为未加载,并且还有分页数据
                     */
                    helper.trailingLoadState = LoadState.NotLoading(false)
                }

                // page加一
                pageInfo.nextPage()
            }

            override fun fail(e: Exception) {
                Tips.show(resources.getString(R.string.network_err))
                viewBinding.refreshLayout.isRefreshing = false
                helper.trailingLoadState = LoadState.Error(e)
            }
        }).start()
    }

    /**
     * 模拟加载数据的类,不用特别关注
     */
    internal class Request(private val mPage: Int, private val mCallBack: RequestCallBack) : Thread() {
        private val mHandler: Handler = Handler(Looper.getMainLooper())

        override fun run() {
            try {
                sleep(800) // 模拟网络延迟
            } catch (ignored: InterruptedException) {
            }
            if (mPage == 2 && mFirstError) {
                mFirstError = false
                mHandler.post { mCallBack.fail(RuntimeException("load fail")) }
            } else {
                var size = PAGE_SIZE
                if (mPage == 1) {
                    if (mFirstPageNoMore) {
                        size = 1
                    }
                    mFirstPageNoMore = !mFirstPageNoMore
                    if (!mFirstError) {
                        mFirstError = true
                    }
                } else if (mPage == 4) {
                    size = 1
                }
                val dataSize = size
                mHandler.post { mCallBack.success(DataServer.getSampleData(dataSize)) }
            }
        }

        companion object {
            private var mFirstPageNoMore = false
            private var mFirstError = true
        }
    }

    internal interface RequestCallBack {
        /**
         * 模拟加载成功
         *
         * @param data 数据
         */
        fun success(data: List<Status>)

        /**
         * 模拟加载失败
         *
         * @param e 错误信息
         */
        fun fail(e: Exception)
    }

    companion object {
        private const val PAGE_SIZE = 5
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/NoAutoAutoLoadMoreRefreshUseActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.loadmore

import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter
import com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter.CustomLoadMoreAdapter
import com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter.RecyclerViewAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.data.DataServer
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityLoadMoreBinding
import com.chad.baserecyclerviewadapterhelper.entity.Status
import com.chad.baserecyclerviewadapterhelper.utils.Tips
import com.chad.library.adapter4.QuickAdapterHelper
import com.chad.library.adapter4.loadState.LoadState
import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter.OnTrailingListener

/**
 * 不进行自动加载更多
 */
class NoAutoAutoLoadMoreRefreshUseActivity : BaseViewBindingActivity<ActivityLoadMoreBinding>() {
    internal class PageInfo {
        var page = 0
        fun nextPage() {
            page++
        }

        fun reset() {
            page = 0
        }

        val isFirstPage: Boolean
            get() = page == 0
    }

    private val pageInfo = AutoLoadMoreRefreshUseActivity.PageInfo()

    private val mAdapter: RecyclerViewAdapter = RecyclerViewAdapter()
    private lateinit var helper: QuickAdapterHelper

    override fun initBinding(): ActivityLoadMoreBinding =
        ActivityLoadMoreBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            viewBinding.rvList.updatePadding(bottom = bar.bottom)
            insets
        }

        viewBinding.titleBar.title = "No Auto LoadMore Use"
        viewBinding.titleBar.setOnBackListener { finish() }


        viewBinding.rvList.layoutManager = LinearLayoutManager(this)
        initAdapter()
        addHeadView()
        initRefreshLayout()
    }

    override fun onStart() {
        super.onStart()
        // 进入页面,刷新数据
        mAdapter.setEmptyViewLayout(this, R.layout.loading_view)
        viewBinding.refreshLayout.isRefreshing = true
        refresh()
    }

    private fun initAdapter() {
        // 自定义"加载更多"的样式
        val loadMoreAdapter = CustomLoadMoreAdapter()
        loadMoreAdapter.setOnLoadMoreListener(object : OnTrailingListener {
            override fun onLoad() {
                request()
            }

            override fun onFailRetry() {
                request()
            }

            override fun isAllowLoading(): Boolean {
                // 下拉刷新的适合,不允许进行"加载更多"
                return !viewBinding.refreshLayout.isRefreshing
            }
        })

        //——————————————————————————————————————————————————————————
        // 可选,监听加载状态的变化。
        //——————————————————————————————————————————————————————————
        loadMoreAdapter.addLoadStateListener { previousState, currentState ->
            // 你的业务逻辑
            println("----------- previousState: $previousState   -   currentState: $currentState ")
        }

        //——————————————————————————————————————————————————————————
        // 关闭"自动加载更多"
        //——————————————————————————————————————————————————————————
        loadMoreAdapter.isAutoLoadMore = false
        helper = QuickAdapterHelper.Builder(mAdapter)
            .setTrailingLoadStateAdapter(loadMoreAdapter)
            .build()
        viewBinding.rvList.adapter = helper.adapter
    }

    private fun addHeadView() {
        val headerAdapter = HeaderAdapter()
        headerAdapter.setOnItemClickListener { _, _, _ ->
            addHeadView()
        }
        helper.addBeforeAdapter(headerAdapter)
    }

    private fun initRefreshLayout() {
        viewBinding.refreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189))
        viewBinding.refreshLayout.setOnRefreshListener { refresh() }
    }

    /**
     * 刷新
     */
    private fun refresh() {
        // 下拉刷新,需要重置页数
        pageInfo.reset()
        request()
    }

    /**
     * 请求数据
     */
    private fun request() {

        Request(pageInfo.page, object : RequestCallBack {
            override fun success(data: List<Status>) {
                viewBinding.refreshLayout.isRefreshing = false
                if (pageInfo.isFirstPage) {
                    // 如果是加载的第一页数据,用 submitList()
                    // If it is the first page of data loaded, use submitList().
                    mAdapter.submitList(data)
                } else {
                    //不是第一页,则用add
                    mAdapter.addAll(data)
                }
                if (pageInfo.page >= PAGE_SIZE) {
                    /*
                    Set the status to not loaded, and there is no paging data.
                    设置状态为未加载,并且没有分页数据了
                     */
                    helper.trailingLoadState = LoadState.NotLoading(true)
                    Tips.show("no more data")
                } else {
                    /*
                    Set the state to not loaded, and there is also paginated data
                    设置状态为未加载,并且还有分页数据
                    */
                    helper.trailingLoadState = LoadState.NotLoading(false)
                }

                // page加一
                pageInfo.nextPage()
            }

            override fun fail(e: Exception) {
                Tips.show(resources.getString(R.string.network_err))
                viewBinding.refreshLayout.isRefreshing = false
                helper.trailingLoadState = LoadState.Error(e)
            }
        }).start()
    }

    /**
     * 模拟加载数据的类,不用特别关注
     */
    internal class Request(private val mPage: Int, private val mCallBack: RequestCallBack) :
        Thread() {
        private val mHandler: Handler = Handler(Looper.getMainLooper())

        override fun run() {
            try {
                sleep(1000) // 模拟网络延迟
            } catch (ignored: InterruptedException) {
            }
            if (mPage == 2 && mFirstError) {
                mFirstError = false
                mHandler.post { mCallBack.fail(RuntimeException("load fail")) }
            } else {
                var size = PAGE_SIZE
                if (mPage == 1) {
                    if (mFirstPageNoMore) {
                        size = 1
                    }
                    mFirstPageNoMore = !mFirstPageNoMore
                    if (!mFirstError) {
                        mFirstError = true
                    }
                } else if (mPage == 4) {
                    size = 1
                }
                val dataSize = size
                mHandler.post { mCallBack.success(DataServer.getSampleData(dataSize)) }
            }
        }

        companion object {
            private var mFirstPageNoMore = false
            private var mFirstError = true
        }
    }

    internal interface RequestCallBack {
        /**
         * 模拟加载成功
         *
         * @param data 数据
         */
        fun success(data: List<Status>)

        /**
         * 模拟加载失败
         *
         * @param e 错误信息
         */
        fun fail(e: Exception)
    }

    companion object {
        private const val PAGE_SIZE = 5
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/CustomLoadMoreAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.databinding.ViewLoadMoreBinding
import com.chad.library.adapter4.loadState.LoadState
import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter

/**
 * 自定义的"加载更多"。
 * 这里可以做很多事情,这里仅展示了更改自定义布局的使用。
 *
 * There are many things that can be done here, only the use of changing custom layouts is shown here.
 */
class CustomLoadMoreAdapter : TrailingLoadStateAdapter<CustomLoadMoreAdapter.CustomVH>() {

    override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): CustomVH {
        val viewBinding = ViewLoadMoreBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return CustomVH(viewBinding).apply {
            viewBinding.loadMoreLoadFailView.setOnClickListener {
                // 失败重试点击事件
                invokeFailRetry()
            }
            viewBinding.loadMoreLoadCompleteView.setOnClickListener {
                // 加载更多,手动点击事件
                invokeLoadMore()
            }
        }
    }

    override fun onBindViewHolder(holder: CustomVH, loadState: LoadState) {
        when (loadState) {
            is LoadState.NotLoading -> {
                if (loadState.endOfPaginationReached) {
                    holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE
                    holder.viewBinding.loadMoreLoadingView.visibility = View.GONE
                    holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE
                    holder.viewBinding.loadMoreLoadEndView.visibility = View.VISIBLE
                } else {
                    holder.viewBinding.loadMoreLoadCompleteView.visibility = View.VISIBLE
                    holder.viewBinding.loadMoreLoadingView.visibility = View.GONE
                    holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE
                    holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE
                }
            }
            is LoadState.Loading -> {
                holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE
                holder.viewBinding.loadMoreLoadingView.visibility = View.VISIBLE
                holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE
                holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE
            }
            is LoadState.Error -> {
                holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE
                holder.viewBinding.loadMoreLoadingView.visibility = View.GONE
                holder.viewBinding.loadMoreLoadFailView.visibility = View.VISIBLE
                holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE
            }
            is LoadState.None -> {
                holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE
                holder.viewBinding.loadMoreLoadingView.visibility = View.GONE
                holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE
                holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE
            }
        }
    }


    class CustomVH(val viewBinding: ViewLoadMoreBinding) : RecyclerView.ViewHolder(viewBinding.root)
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/RecyclerViewAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter

import android.content.Context
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.text.buildSpannedString
import androidx.core.text.inSpans
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.databinding.LayoutAnimationBinding
import com.chad.baserecyclerviewadapterhelper.entity.Status
import com.chad.baserecyclerviewadapterhelper.utils.Tips
import com.chad.library.adapter4.BaseQuickAdapter

/**
 * @author: limuyang
 * @date: 2019-12-04
 * @Description:
 */
class RecyclerViewAdapter : BaseQuickAdapter<Status, RecyclerViewAdapter.VH>() {
    class VH(
        parent: ViewGroup,
        val viewBinding: LayoutAnimationBinding = LayoutAnimationBinding.inflate(
            LayoutInflater.from(parent.context), parent, false
        )
    ) : RecyclerView.ViewHolder(viewBinding.root)

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
        return VH(parent)
    }

    protected override fun onBindViewHolder(holder: VH, position: Int, item: Status?) {
        when (holder.layoutPosition % 3) {
            0 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img1)
            1 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img2)
            2 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img3)
            else -> {}
        }
        holder.viewBinding.tweetName.text =
            "Hoteis in Rio de Janeiro " + position + "  " + item!!.userName
        val msg =
            "\"He was one of Australia's most of distinguished artistes, renowned for his portraits\""
        holder.viewBinding.tweetText.text = buildSpannedString {
            append(msg)
            inSpans(clickableSpan) {
                append("landscapes and nedes")
            }
        }
        holder.viewBinding.tweetText.movementMethod = LinkMovementMethod.getInstance()
    }

    private val clickableSpan: ClickableSpan = object : ClickableSpan() {
        override fun onClick(widget: View) {
            Tips.show("事件触发了 landscapes and nedes")
        }

        override fun updateDrawState(ds: TextPaint) {
            ds.color = ContextCompat.getColor(context, R.color.clickspan_color)
            ds.isUnderlineText = true
        }
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/NodeActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.node

import android.os.Bundle
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import com.chad.baserecyclerviewadapterhelper.activity.node.adapter.NodeAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.data.DataServer
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityNodeBinding

/**
 * @author LiMuYang
 * @date 2025/9/5
 * @description 多节点demo
 */
class NodeActivity : BaseViewBindingActivity<ActivityNodeBinding>() {

    private val adapter = NodeAdapter()

    override fun initBinding(): ActivityNodeBinding {
        return ActivityNodeBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        viewBinding.titleBar.title = "Multi-node Use"
        viewBinding.titleBar.setOnBackListener { finish() }

        viewBinding.rv.adapter = adapter

        adapter.submitList(DataServer.getNodeData())


        viewBinding.btnCloseAll.setOnClickListener {
            adapter.closeAll()
        }
        viewBinding.btnRef.setOnClickListener {
            adapter.submitList(DataServer.getNodeData())
        }
        viewBinding.btnRefOnSave.setOnClickListener {
            adapter.submitList(DataServer.getNodeData(),  clearOpenStates = true)
        }
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/adapter/NodeAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.node.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.databinding.ItemNodeLevel1Binding
import com.chad.baserecyclerviewadapterhelper.databinding.ItemNodeLevel2Binding
import com.chad.baserecyclerviewadapterhelper.databinding.ItemNodeLevel3Binding
import com.chad.baserecyclerviewadapterhelper.entity.NodeEntity
import com.chad.library.adapter4.BaseNodeAdapter

/**
 * @author LiMuYang
 * @date 2025/9/5
 * @description
 */
class NodeAdapter : BaseNodeAdapter() {

    override fun getChildNodeList(position: Int, parent: Any): List<Any>? {
        when (parent) {
            is NodeEntity -> {
                // 一级
                return parent.childNode
            }

            is NodeEntity.Level2NodeEntity -> {
                // 二级
                return parent.childNode
            }

            is NodeEntity.Level2NodeEntity.Level3NodeEntity -> {
                // 三级 没有子node
                return null
            }

            else -> return null
        }
    }

    override fun isInitialOpen(position: Int, item: Any): Boolean {
        // 哪些数据需要默认展开
        if (item is NodeEntity) {
            return item.title == "Item 1"
        } else if (item is NodeEntity.Level2NodeEntity) {
            // 二级
            return item.title.startsWith("Item 1", ignoreCase = true)
        }
        return false
    }

    override fun isSameNode(item1: Any, item2: Any): Boolean {
        return when (item1) {
            is NodeEntity if item2 is NodeEntity -> {
                item1.title == item2.title
            }

            is NodeEntity.Level2NodeEntity if item2 is NodeEntity.Level2NodeEntity -> {
                // 二级
                item1.title == item2.title
            }

            is NodeEntity.Level2NodeEntity.Level3NodeEntity if item2 is NodeEntity.Level2NodeEntity.Level3NodeEntity -> {
                // 三级
                item1.title == item2.title
            }

            else -> {
                false
            }
        }
    }

    override fun getItemViewType(position: Int, list: List<Any>): Int {
        val item = list[position]
        when (item) {
            is NodeEntity -> {
                // 一级
                return 1
            }

            is NodeEntity.Level2NodeEntity -> {
                // 二级
                return 2
            }

            is NodeEntity.Level2NodeEntity.Level3NodeEntity -> {
                // 三级
                return 3
            }

            else -> return 0
        }
    }

    override fun onCreateViewHolder(
        context: Context, parent: ViewGroup, viewType: Int,
    ): RecyclerView.ViewHolder {
        return when (viewType) {
            1 -> {
                Level1Hodler(parent).apply {
                    itemView.setOnClickListener {
                        openOrClose(bindingAdapterPosition)
                    }
                }
            }

            2 -> {
                Level2Hodler(parent).apply {
                    itemView.setOnClickListener {
                        openOrClose(bindingAdapterPosition)
                    }
                }
            }

            3 -> {
                Level3Hodler(parent).apply {
                    itemView.setOnClickListener {
                        Toast.makeText(
                            it.context,
                            "Level 3 _ index $bindingAdapterPosition",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
                }
            }

            else -> {
                Level1Hodler(parent)
            }
        }
    }

    override fun onBindViewHolder(
        holder: RecyclerView.ViewHolder, position: Int, item: Any?,
    ) {
        when (holder) {
            is Level1Hodler -> {
                // 一级
                val nodeEntity = item as NodeEntity

                holder.viewBinding.tvTitle.text = nodeEntity.title

                // 设置箭头图标
                if (nodeEntity.childNode.isNullOrEmpty()) {
                    holder.viewBinding.ivArrow.setBackgroundResource(0)
                } else {
                    if (isOpened(item)) {
                        holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_down)
                    } else {
                        holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_right)
                    }
                }
            }

            is Level2Hodler -> {
                // 二级
                val nodeEntity = item as NodeEntity.Level2NodeEntity
                holder.viewBinding.tvTitle.text = nodeEntity.title

                // 设置箭头图标
                if (nodeEntity.childNode.isNullOrEmpty()) {
                    holder.viewBinding.ivArrow.setBackgroundResource(0)
                } else {
                    if (isOpened(item)) {
                        holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_down)
                    } else {
                        holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_right)
                    }
                }
            }

            is Level3Hodler -> {
                // 三级
                val nodeEntity = item as NodeEntity.Level2NodeEntity.Level3NodeEntity
                holder.viewBinding.tvTitle.text = nodeEntity.title
            }
        }
    }
}


class Level1Hodler(
    parent: ViewGroup,
    val viewBinding: ItemNodeLevel1Binding = ItemNodeLevel1Binding.inflate(
        LayoutInflater.from(parent.context), parent, false
    ),
) : RecyclerView.ViewHolder(viewBinding.root)

class Level2Hodler(
    parent: ViewGroup,
    val viewBinding: ItemNodeLevel2Binding = ItemNodeLevel2Binding.inflate(
        LayoutInflater.from(parent.context), parent, false
    ),
) : RecyclerView.ViewHolder(viewBinding.root)

class Level3Hodler(
    parent: ViewGroup,
    val viewBinding: ItemNodeLevel3Binding = ItemNodeLevel3Binding.inflate(
        LayoutInflater.from(parent.context), parent, false
    ),
) : RecyclerView.ViewHolder(viewBinding.root)

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/GroupDemoActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.scene

import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.activity.scene.adapter.GroupAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding
import com.chad.baserecyclerviewadapterhelper.entity.GroupDemoEntity
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import androidx.core.graphics.drawable.toDrawable


class GroupDemoActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {

    // 创建一个 ConcatAdapter,用来包裹 GroupAdapter
    private val concatAdapter = ConcatAdapter()


    override fun initBinding(): ActivityUniversalRecyclerBinding =
        ActivityUniversalRecyclerBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        window.setBackgroundDrawable(ContextCompat.getColor(this, R.color.bg).toDrawable())

        viewBinding.titleBar.title = "Group Scene(ConcatAdapter)"
        viewBinding.titleBar.setOnBackListener { finish() }

        viewBinding.rv.layoutManager = LinearLayoutManager(this)
        viewBinding.rv.adapter = concatAdapter

        /*
        往常,我们获得这样一个 List 嵌套 List 的结构时,需要展平数据成一个 List<Any>,
        然后用一个 Adapter 通过不同的ItemViewType 去做,非常繁琐,容易出错,而且不方便数据刷新

        现在我们不需要去对数据做处理了,直接使用!
         */
        val list: List<GroupDemoEntity> = jsonToList()


        // 循环 list,有多少个数组,就创建多少个 GroupAdapter,就这么简单
        list.forEach {
            val adapter = GroupAdapter()
            adapter.submitList(it.groupList)

            // 创建好以后,直接扔进 ConcatAdapter
            concatAdapter.addAdapter(adapter)
        }
    }

    /**
     * 解析 Json,不用关注
     */
    private fun jsonToList(): List<GroupDemoEntity> {
        val moshi = Moshi.Builder().build()
        val type = Types.newParameterizedType(List::class.java, GroupDemoEntity::class.java)
        val jsonAdapter: JsonAdapter<List<GroupDemoEntity>> = moshi.adapter(type)
        return jsonAdapter.fromJson(JSON) ?: throw IllegalStateException("json 解析出错")
    }

    companion object {
        // 此种格式的json,在业务场景中比较常见
        private const val JSON = """
[{
		"group_name": "1",
		"group_list": [{
				"title": "patton",
				"content": "this is content"
			},
			{
				"title": "nicole",
				"content": "this is content"
			},
			{
				"title": "anthony",
				"content": "this is content"
			}
		]
	},
	{
		"group_name": "2",
		"group_list": [{
				"title": "zane",
				"content": "this is content"
			},
			{
				"title": "venus",
				"content": "this is content"
			},
			{
				"title": "yahya",
				"content": "this is content"
			},
			{
				"title": "starlight",
				"content": "this is content"
			},
			{
				"title": "twinkle",
				"content": "this is content"
			}
		]
	},
	{
		"group_name": "3",
		"group_list": [{
				"title": "esther",
				"content": "this is content"
			},
			{
				"title": "asta",
				"content": "this is content"
			},
			{
				"title": "gary",
				"content": "this is content"
			}
		]
	},
	{
		"group_name": "4",
		"group_list": [{
				"title": "peter",
				"content": "this is content"
			},
			{
				"title": "aldrich",
				"content": "this is content"
			}
		]
	},
	{
		"group_name": "5",
		"group_list": [{
				"title": "edgar",
				"content": "this is content"
			},
			{
				"title": "danika",
				"content": "this is content"
			},
			{
				"title": "clement",
				"content": "this is content"
			}
		]
	}
]
        """
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/adapter/GroupAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.scene.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.databinding.ItemGroupTypeBinding
import com.chad.baserecyclerviewadapterhelper.entity.GroupDemoEntity
import com.chad.baserecyclerviewadapterhelper.utils.dp
import com.chad.library.adapter4.BaseQuickAdapter

/**
 * 每一组的Adapter
 *
 */
class GroupAdapter : BaseQuickAdapter<GroupDemoEntity.Group, GroupAdapter.VH>(){

    class VH(
        parent: ViewGroup,
        val binding: ItemGroupTypeBinding = ItemGroupTypeBinding.inflate(LayoutInflater.from(parent.context), parent ,false)
    ):RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
        return VH(parent)
    }

    override fun onBindViewHolder(holder: VH, position: Int, item: GroupDemoEntity.Group?) {
        if (item == null) return

        holder.binding.tvTitle.text = item.title
        holder.binding.tvContent.text = item.content

        holder.binding.lineView.isVisible = position > 0

        when (position) {
            0 -> {
                // 第一个item,设置上圆角背景
                holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_top_bg)

                // 设置点间距
                holder.binding.root.updateLayoutParams<MarginLayoutParams> {
                    topMargin = 15.dp
                }
            }
            items.size - 1 -> {
                // 最后一个item,设置下圆角背景
                holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_bottom_bg)
            }
            else -> {
                // 其他的,没有圆角的背景
                holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_mid_bg)
            }
        }
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/UpFetchUseActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.upfetch

import android.os.Bundle
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.recyclerview.widget.LinearLayoutManager
import com.chad.baserecyclerviewadapterhelper.activity.upfetch.adapter.UpFetchAdapter
import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity
import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding
import com.chad.baserecyclerviewadapterhelper.entity.Movie
import com.chad.library.adapter4.QuickAdapterHelper
import com.chad.library.adapter4.loadState.LoadState
import com.chad.library.adapter4.loadState.LoadState.NotLoading
import com.chad.library.adapter4.loadState.leading.LeadingLoadStateAdapter.OnLeadingListener
import java.util.*

/**
 * @author limuyang
 * 2019-12-06
 */
class UpFetchUseActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {

    private val mAdapter = UpFetchAdapter()
    private lateinit var helper: QuickAdapterHelper

    override fun initBinding(): ActivityUniversalRecyclerBinding =
        ActivityUniversalRecyclerBinding.inflate(layoutInflater)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->
            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            viewBinding.titleBar.updateFakeBarHeight(bar.top)
            insets
        }

        viewBinding.titleBar.title = "UpFetch Use"
        viewBinding.titleBar.setOnBackListener { finish() }


        viewBinding.rv.layoutManager = LinearLayoutManager(this)

        helper = QuickAdapterHelper.Builder(mAdapter)
            .setLeadingLoadStateAdapter(object : OnLeadingListener {
                override fun onLoad() {
                    requestUoFetch()
                }

                override fun isAllowLoading(): Boolean {
                    return true
                }
            })
            .setLeadPreloadSize(0) // 预加载(默认值为0)
            .build()
        viewBinding.rv.adapter = helper.adapter
    }

    override fun onStart() {
        super.onStart()
        requestUoFetch()
    }

    private var count = 0
    private fun requestUoFetch() {
        if (count == 0) {
            count++
            // 首次进入页面,设置数据
            mAdapter.submitList(genData())
            scrollToBottom()
            helper.leadingLoadState = NotLoading(false)
            return
        }
        count++

        /**
         * When starting to request data from the network, set the status to loading.
         * 当开始网络请求数据的时候,设置状态为加载中
         */
        helper.leadingLoadState = LoadState.Loading

        /*
         * get data from internet.
         * 从网络获取数据
         */
        viewBinding.rv.postDelayed({
            mAdapter.addAll(0, genData())
            if (count > 5) {
                /*
                 * Set the status to not loaded, and there is no paging data.
                 * 设置状态为未加载,并且没有分页数据了
                 */
                helper.leadingLoadState = NotLoading(true)
            } else {
                /**
                 * Set the state to not loaded, and there is also paginated data
                 * 设置状态为未加载,并且还有分页数据
                 */
                helper.leadingLoadState = NotLoading(false)
            }
        }, 600)
    }

    /**
     * 滚动到底部(不带动画)
     */
    private fun scrollToBottom() {
        val ll = viewBinding.rv.layoutManager as LinearLayoutManager
        ll.scrollToPositionWithOffset(bottomDataPosition, 0)
    }

    private val bottomDataPosition: Int
        get() = mAdapter.items.size - 1

    private fun genData(): List<Movie> {
        val list = ArrayList<Movie>()
        val random = Random()
        for (i in 0..9) {
            val name = "Chad"
            val price = random.nextInt(10) + 10
            val len = random.nextInt(80) + 60
            val movie =
                Movie(name, len, price, "He was one of Australia's most distinguished artistes")
            list.add(movie)
        }
        return list
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/adapter/UpFetchAdapter.kt
================================================
package com.chad.baserecyclerviewadapterhelper.activity.upfetch.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.databinding.ItemHeaderAndFooterBinding
import com.chad.baserecyclerviewadapterhelper.entity.Movie
import com.chad.library.adapter4.BaseQuickAdapter

/**
 * @author: limuyang
 * @date: 2019-12-06
 * @Description:
 */
class UpFetchAdapter : BaseQuickAdapter<Movie, UpFetchAdapter.VH>() {
    class VH(
        parent: ViewGroup,
        val viewBinding: ItemHeaderAndFooterBinding = ItemHeaderAndFooterBinding.inflate(
            LayoutInflater.from(parent.context), parent, false
        )
    ) : RecyclerView.ViewHolder(viewBinding.root)

    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
        return VH(parent)
    }

    override fun onBindViewHolder(holder: VH, position: Int, item: Movie?) {
        when (holder.layoutPosition % 3) {
            0 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img1)
            1 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img2)
            2 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img3)
            else -> {}
        }
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation1.java
================================================
package com.chad.baserecyclerviewadapterhelper.animator;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import com.chad.library.adapter4.animation.ItemAnimator;
import org.jetbrains.annotations.NotNull;

/**
 * 自定义动画1
 */
public class CustomAnimation1 implements ItemAnimator {
    @NotNull
    @Override
    public Animator animator(@NotNull View view) {
        Animator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1f);

        Animator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1.3f, 1);
        Animator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1.3f, 1);

        scaleY.setInterpolator(new DecelerateInterpolator());
        scaleX.setInterpolator(new DecelerateInterpolator());

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(350);
        animatorSet.play(alpha).with(scaleX).with(scaleY);

        return animatorSet;
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation2.java
================================================
package com.chad.baserecyclerviewadapterhelper.animator;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.animation.Interpolator;

import com.chad.library.adapter4.animation.ItemAnimator;

import org.jetbrains.annotations.NotNull;

import static java.lang.Math.PI;
import static java.lang.Math.pow;
import static java.lang.Math.sin;


/**
 * 自定义动画2
 */
public class CustomAnimation2 implements ItemAnimator {
    @NotNull
    @Override
    public Animator animator(@NotNull View view) {
        Animator translationX =
                ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0f);

        translationX.setDuration(800);
        translationX.setInterpolator(new MyInterpolator2());

        return translationX;
    }

    private static class MyInterpolator2 implements Interpolator {
        @Override
        public float getInterpolation(float input) {
            float factor = 0.7f;
            return (float) (pow(2.0, -10.0 * input) * sin((input - factor / 4) * (2 * PI) / factor) + 1);
        }
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation3.java
================================================
package com.chad.baserecyclerviewadapterhelper.animator;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import com.chad.library.adapter4.animation.ItemAnimator;

import org.jetbrains.annotations.NotNull;

public class CustomAnimation3 implements ItemAnimator {

    @NotNull
    @Override
    public Animator animator(@NotNull View view) {
        Animator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1f);

        Animator translationY =
                ObjectAnimator.ofFloat(view, "translationY", view.getRootView().getHeight(), 0f);
        translationY.setInterpolator(new DecelerateInterpolator(1.2f));

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(450);
        animatorSet.play(alpha).with(translationY);

        return animatorSet;
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.base

import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.utils.statusBarLightMode

abstract class BaseActivity(@LayoutRes layoutRes: Int = 0) : AppCompatActivity(layoutRes) {


    protected open val contentView: View? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        enableEdgeToEdge()

        contentView?.let {
            setContentView(it)
        }





        window.statusBarColor = ContextCompat.getColor(this, R.color.spinner_bg)
        window.statusBarLightMode = false


    }


}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseViewBindingActivity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.base

import android.view.View
import androidx.viewbinding.ViewBinding

abstract class BaseViewBindingActivity<V : ViewBinding> : BaseActivity() {

    private var _viewBinding: V? = null

    protected val viewBinding: V
        get() {
            return _viewBinding ?: throw IllegalStateException(
                "Should be called initBinding()"
            )
        }

    /**
     * 初始化 [viewBinding]
     */
    abstract fun initBinding(): V

    final override val contentView: View
        get() {
            return initBinding().apply {
                _viewBinding = this
            }.root
        }

}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.kt
================================================
package com.chad.baserecyclerviewadapterhelper.data

import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity
import com.chad.baserecyclerviewadapterhelper.entity.NodeEntity
import com.chad.baserecyclerviewadapterhelper.entity.Status

/**
 * https://github.com/CymChad/BaseRecyclerViewAdapterHelper
 */
object DataServer {
    const val HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK =
        "https://avatars1.githubusercontent.com/u/7698209?v=3&s=460"
    const val CYM_CHAD = "CymChad"
    const val CHAY_CHAN = "ChayChan"

    fun getSampleData(lenth: Int): MutableList<Status> {
        val list: MutableList<Status> = ArrayList()
        for (i in 0 until lenth) {
            val status = Status()
            status.userName = "Chad$i"
            status.createdAt = "04/05/$i"
            status.isRetweet = i % 2 == 0


            status.userAvatar = when (i % 3) {
                0 -> R.mipmap.animation_img1
                1 -> R.mipmap.animation_img2
                else -> R.mipmap.animation_img3
            }
            status.text = "BaseRecyclerViewAdpaterHelper https://www.recyclerview.org"
            list.add(status)
        }
        return list
    }


    val strData: List<String>
        get() {
            val list: MutableList<String> = ArrayList()
            for (i in 0..19) {
                var str = HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK
                if (i % 2 == 0) {
                    str = CYM_CHAD
                }
                list.add(str)
            }
            return list
        }

    @JvmStatic
    val diffUtilDemoEntities: List<DiffEntity>
        get() {
            val list: MutableList<DiffEntity> = ArrayList()
            for (i in 0..9) {
                list.add(
                    DiffEntity(
                        i,
                        "Item $i",
                        "This item $i content",
                        "06-12"
                    )
                )
            }
            return list
        }


    fun getNodeData(): List<NodeEntity> {
        val list = ArrayList<NodeEntity>()
        for (i in 0..9) {
            val node = if (i % 2 == 0) {
                NodeEntity("Item $i", null)
            } else {
                val level2list = ArrayList<NodeEntity.Level2NodeEntity>()
                for (n in 0..4) {
                    val leve2Node = if (n % 2 != 0) {
                        NodeEntity.Level2NodeEntity("Item ${i} - Level 2 - Index $n", null)
                    } else {
                        val level3list = ArrayList<NodeEntity.Level2NodeEntity.Level3NodeEntity>()

                        for (m in 0..4) {
                            val level3Node =
                                NodeEntity.Level2NodeEntity.Level3NodeEntity("Item${i} - Level2-index:${n} - Level 3 - Index $m")
                            level3list.add(level3Node)
                        }

                        NodeEntity.Level2NodeEntity("Item ${i} - Level 2 - Index $n with Child", level3list)
                    }
                    level2list.add(leve2Node)
                }

                NodeEntity("Item $i", level2list)
            }
            list.add(node)
        }

        return list
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridItemDecoration.java
================================================
package com.chad.baserecyclerviewadapterhelper.decoration;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

/**
 * https://github.com/CymChad/BaseRecyclerViewAdapterHelper
 */
public class GridItemDecoration extends RecyclerView.ItemDecoration {

    private Drawable dividerDrawable;
    private int orientation = LinearLayoutManager.VERTICAL;

    public GridItemDecoration(Drawable divider) {
        dividerDrawable = divider;
    }

    public GridItemDecoration(Context context, int resId) {
        dividerDrawable = context.getResources().getDrawable(resId);
    }

    public GridItemDecoration(Context context, int resId, int orientation) {
        dividerDrawable = context.getResources().getDrawable(resId);
        this.orientation = orientation;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (dividerDrawable == null) {
            return;
        }

        if (parent.getChildLayoutPosition(view) < 1) {
            return;
        }

        if (orientation == LinearLayoutManager.VERTICAL) {
            outRect.top = dividerDrawable.getIntrinsicHeight();
        } else if (orientation == LinearLayoutManager.HORIZONTAL) {
            outRect.left = dividerDrawable.getIntrinsicWidth();
        }
    }

    /**
     * @param c
     * @param parent
     * @param state
     */
    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (dividerDrawable == null) {
            return;
        }

        int childCount = parent.getChildCount();
        int rightV = parent.getWidth();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            int leftV = parent.getPaddingLeft() + child.getPaddingLeft();
            int bottomV = child.getTop() - params.topMargin;
            int topV = bottomV - dividerDrawable.getIntrinsicHeight();

            int topH = child.getTop() + params.topMargin;
            int bottomH = child.getBottom() + params.bottomMargin;
            int rightH = child.getLeft() - params.leftMargin;
            int leftH = rightH - dividerDrawable.getIntrinsicWidth();
            dividerDrawable.setBounds(leftH, topH, rightH, bottomH);
            dividerDrawable.draw(c);
            dividerDrawable.setBounds(leftV, topV, rightV, bottomV);
            dividerDrawable.draw(c);
        }
    }


}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridSectionAverageGapItemDecoration.java
================================================
//package com.chad.baserecyclerviewadapterhelper.decoration;
//
//import android.graphics.Rect;
//import android.os.Build;
//import android.util.DisplayMetrics;
//import android.util.TypedValue;
//import android.view.View;
//
//import androidx.annotation.Nullable;
//import androidx.recyclerview.widget.GridLayoutManager;
//import androidx.recyclerview.widget.RecyclerView;
//
//import com.chad.library.adapter.base.BaseSectionQuickAdapter;
//import com.chad.library.adapter.base.viewholder.BaseViewHolder;
//import com.chad.library.adapter.base.entity.SectionEntity;
//
//import java.util.ArrayList;
//import java.util.List;
//
///**
// * 应用于RecyclerView的GridLayoutManager,水平方向上固定间距大小,从而使条目宽度自适应。<br>
// * 配合Brvah的Section使用,不对Head生效,仅对每个Head的子Grid列表生效<br>
// * Section Grid中Item的宽度应设为MATCH_PARAENT
// *
// * @author : renpeng
// * @since : 2018/9/29
// */
//public class GridSectionAverageGapItemDecoration extends RecyclerView.ItemDecoration {
//
//    private class Section {
//        public int startPos = 0;
//        public int endPos = 0;
//
//        public int getCount() {
//            return endPos - startPos + 1;
//        }
//
//        public boolean contains(int pos) {
//            return pos >= startPos && pos <= endPos;
//        }
//
//        @Override
//        public String toString() {
//            return "Section{" +
//                    "startPos=" + startPos +
//                    ", endPos=" + endPos +
//                    '}';
//        }
//    }
//
//    private float                            gapHorizontalDp;
//    private float                            gapVerticalDp;
//    private float                            sectionEdgeHPaddingDp;
//    private float                            sectionEdgeVPaddingDp;
//    private int                              gapHSizePx = -1;
//    private int                              gapVSizePx = -1;
//    private int                              sectionEdgeHPaddingPx;
//    private int                              eachItemHPaddingPx; //每个条目应该在水平方向上加的padding 总大小,即=paddingLeft+paddingRight
//    private int                              sectionEdgeVPaddingPx;
//    private List<Section>                    mSectionList = new ArrayList<>();
//    private BaseSectionQuickAdapter          mAdapter;
//    private RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {
//        @Override
//        public void onChanged() {
//            markSections();
//        }
//
//        @Override
//        public void onItemRangeChanged(int positionStart, int itemCount) {
//            markSections();
//        }
//
//        @Override
//        public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
//            markSections();
//        }
//
//        @Override
//        public void onItemRangeInserted(int positionStart, int itemCount) {
//            markSections();
//        }
//
//        @Override
//        public void onItemRangeRemoved(int positionStart, int itemCount) {
//            markSections();
//        }
//
//        @Override
//        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
//            markSections();
//        }
//    };
//
//
//    /**
//     * @param gapHorizontalDp       item之间的水平间距
//     * @param gapVerticalDp         item之间的垂直间距
//     * @param sectionEdgeHPaddingDp section左右两端的padding大小
//     * @param sectionEdgeVPaddingDp section上下两端的padding大小
//     */
//    public GridSectionAverageGapItemDecoration(float gapHorizontalDp, float gapVerticalDp, float sectionEdgeHPaddingDp, float sectionEdgeVPaddingDp) {
//        this.gapHorizontalDp = gapHorizontalDp;
//        this.gapVerticalDp = gapVerticalDp;
//        this.sectionEdgeHPaddingDp = sectionEdgeHPaddingDp;
//        this.sectionEdgeVPaddingDp = sectionEdgeVPaddingDp;
//    }
//
//    @Override
//    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
//        if (parent.getLayoutManager() instanceof GridLayoutManager && parent.getAdapter() instanceof BaseSectionQuickAdapter) {
//            GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
//            BaseSectionQuickAdapter<SectionEntity, BaseViewHolder> adapter = (BaseSectionQuickAdapter) parent.getAdapter();
//            if (mAdapter != adapter) {
//                setUpWithAdapter(adapter);
//            }
//            int spanCount = layoutManager.getSpanCount();
//            int position = parent.getChildAdapterPosition(view);
//            SectionEntity entity = adapter.getItem(position);
//
//            if (entity == null || entity.isHeader()) {
//                //不处理header
//                outRect.set(0, 0, 0, 0);
////                Log.w("GridAverageGapItem", "pos=" + position + "," + outRect.toShortString());
//                return;
//            }
//
//            Section section = findSectionLastItemPos(position);
//
//            if (gapHSizePx < 0 || gapVSizePx < 0) {
//                transformGapDefinition(parent, spanCount);
//            }
//            outRect.top = gapVSizePx;
//            outRect.bottom = 0;
//
//            //下面的visualPos为单个Section内的视觉Pos
//            int visualPos = position + 1 - section.startPos;
//            if (visualPos % spanCount == 1) {
//                //第一列
//                outRect.left = sectionEdgeHPaddingPx;
//                outRect.right = eachItemHPaddingPx - sectionEdgeHPaddingPx;
//            } else if (visualPos % spanCount == 0) {
//                //最后一列
//                outRect.left = eachItemHPaddingPx - sectionEdgeHPaddingPx;
//                outRect.right = sectionEdgeHPaddingPx;
//            } else {
//                outRect.left = gapHSizePx - (eachItemHPaddingPx - sectionEdgeHPaddingPx);
//                outRect.right = eachItemHPaddingPx - outRect.left;
//            }
//
//            if (visualPos - spanCount <= 0) {
//                //第一行
//                outRect.top = sectionEdgeVPaddingPx;
//            }
//
//            if (isLastRow(visualPos, spanCount, section.getCount())) {
//                //最后一行
//                outRect.bottom = sectionEdgeVPaddingPx;
////                Log.w("GridAverageGapItem", "last row pos=" + position);
//            }
////            Log.w("GridAverageGapItem", "pos=" + position + ",vPos=" + visualPos + "," + outRect.toShortString());
//        } else {
//            super.getItemOffsets(outRect, view, parent, state);
//        }
//    }
//
//    private void setUpWithAdapter(BaseSectionQuickAdapter<SectionEntity, BaseViewHolder> adapter) {
//        if (mAdapter != null) {
//            mAdapter.unregisterAdapterDataObserver(mDataObserver);
//        }
//        mAdapter = adapter;
//        mAdapter.registerAdapterDataObserver(mDataObserver);
//        markSections();
//    }
//
//    private void markSections() {
//        if (mAdapter != null) {
//            BaseSectionQuickAdapter<SectionEntity, BaseViewHolder> adapter = mAdapter;
//            mSectionList.clear();
//            SectionEntity sectionEntity = null;
//            Section section = new Section();
//            for (int i = 0, size = adapter.getItemCount(); i < size; i++) {
//                sectionEntity = adapter.getItem(i);
//                if (sectionEntity != null && sectionEntity.isHeader()) {
//                    //找到新Section起点
//                    if (section != null && i != 0) {
//                        //已经有待添加的section
//                        section.endPos = i - 1;
//                        mSectionList.add(section);
//                    }
//                    section = new Section();
//                    section.startPos = i + 1;
//                } else {
//                    section.endPos = i;
//                }
//            }
//            //处理末尾情况
//            if (!mSectionList.contains(section)) {
//                mSectionList.add(section);
//            }
//
////            Log.w("GridAverageGapItem", "section list=" + mSectionList);
//        }
//    }
//
//    private void transformGapDefinition(RecyclerView parent, int spanCount) {
//        DisplayMetrics displayMetrics = new DisplayMetrics();
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
//            parent.getDisplay().getMetrics(displayMetrics);
//        }
//        gapHSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapHorizontalDp, displayMetrics);
//        gapVSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapVerticalDp, displayMetrics);
//        sectionEdgeHPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeHPaddingDp, displayMetrics);
//        sectionEdgeVPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeVPaddingDp, displayMetrics);
//        eachItemHPaddingPx = (sectionEdgeHPaddingPx * 2 + gapHSizePx * (spanCount - 1)) / spanCount;
//    }
//
//    private Section findSectionLastItemPos(int curPos) {
//        for (Section section : mSectionList) {
//            if (section.contains(curPos)) {
//                return section;
//            }
//        }
//        return null;
//    }
//
//    private boolean isLastRow(int visualPos, int spanCount, int sectionItemCount) {
//        int lastRowCount = sectionItemCount % spanCount;
//        lastRowCount = lastRowCount == 0 ? spanCount : lastRowCount;
//        return visualPos > sectionItemCount - lastRowCount;
//    }
//}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/ClickEntity.java
================================================
/*
******************************* Copyright (c)*********************************\
**
**                 (c) Copyright 2015, Allen, china, shanghai
**                          All Rights Reserved
**
**                          
**                         
**-----------------------------------版本信息------------------------------------
** 版    本: V0.1
**
**------------------------------------------------------------------------------
********************************End of Head************************************\
*/
package com.chad.baserecyclerviewadapterhelper.entity;

/**
 * 文 件 名: ClickEntity
 * 创 建 人: Allen
 * 创建日期: 16/11/1 22:16
 * 邮   箱: AllenCoder@126.com
 * 修改时间:
 * 修改备注:
 */
public class ClickEntity {
    public static final int CLICK_ITEM_VIEW = 1;
    public static final int CLICK_ITEM_CHILD_VIEW = 2;
    public static final int LONG_CLICK_ITEM_VIEW = 3;
    public static final int LONG_CLICK_ITEM_CHILD_VIEW = 4;
    private final int type;

    public ClickEntity(final int type) {
        this.type = type;
    }

    public int getItemType() {
        return type;
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/DiffEntity.java
================================================
package com.chad.baserecyclerviewadapterhelper.entity;

import java.util.Objects;

public class DiffEntity {

    private int id;
    private String title;
    private String content;
    private String date;

    public DiffEntity(int id, String title, String content, String date) {
        this.id = id;
        this.title = title;
        this.content = content;
        this.date = date;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

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

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof DiffEntity)) return false;
        DiffEntity that = (DiffEntity) o;
        return id == that.id && Objects.equals(title, that.title) && Objects.equals(content, that.content) && Objects.equals(date, that.date);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, title, content, date);
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/GroupDemoEntity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.entity

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class GroupDemoEntity(
    @Json(name = "group_name")
    val groupName: String,
    @Json(name = "group_list")
    val groupList: List<Group>,
) {

    @JsonClass(generateAdapter = true)
    data class Group(
        @Json(name = "title")
        val title: String,
        @Json(name = "content")
        val content: String,
    )
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeEntity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.entity

/**
 * @author: limuyang
 * @date: 2019-12-06
 * @Description:
 */
data class HomeEntity(
    val name: String = "",
    val activity: Class<*>? = null,
    val imageResource: Int = 0,
    val sectionTitle: String = ""
) {
    val isSection: Boolean
        get() = sectionTitle.isNotBlank()
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Movie.java
================================================
package com.chad.baserecyclerviewadapterhelper.entity;

/**
 * Created by luoxiongwen on 16/10/24.
 */

public class Movie {

    public String name;
    public int length;
    public int price;
    public String content;

    public Movie(String name, int length, int price, String content) {
        this.length = length;
        this.name = name;
        this.price = price;
        this.content=content;
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MoviePresenter.java
================================================
package com.chad.baserecyclerviewadapterhelper.entity;

import android.view.View;

import com.chad.baserecyclerviewadapterhelper.utils.Tips;

/**
 * Created by luoxiongwen on 16/10/24.
 */

public class MoviePresenter {
    public void buyTicket(View view, Movie movie) {
        Tips.show("buy ticket: " + movie.name);
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/NodeEntity.kt
================================================
package com.chad.baserecyclerviewadapterhelper.entity

/**
 * @author LiMuYang
 * @date 2025/9/5
 * @description
 */
data class NodeEntity(
    val title: String,
    val childNode: List<Level2NodeEntity>?,
) {

    data class Level2NodeEntity(
        val title: String,
        val childNode: List<Level3NodeEntity>?,
    ) {

        data class Level3NodeEntity(
            val title: String,
        )
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Status.java
================================================
package com.chad.baserecyclerviewadapterhelper.entity;

/**
 * https://github.com/CymChad/BaseRecyclerViewAdapterHelper
 */
public class Status {
    private boolean isRetweet;
    private String text;
    private String userName;
    private int userAvatar;
    private String createdAt;

    public boolean isRetweet() {
        return isRetweet;
    }

    public void setRetweet(boolean retweet) {
        isRetweet = retweet;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getUserAvatar() {
        return userAvatar;
    }

    public void setUserAvatar(int userAvatar) {
        this.userAvatar = userAvatar;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(String createdAt) {
        this.createdAt = createdAt;
    }

    @Override
    public String toString() {
        return "Status{" +
                "isRetweet=" + isRetweet +
                ", text='" + text + '\'' +
                ", userName='" + userName + '\'' +
                ", userAvatar='" + userAvatar + '\'' +
                ", createdAt='" + createdAt + '\'' +
                '}';
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/AppUtils.kt
================================================
package com.chad.baserecyclerviewadapterhelper.utils

import android.app.Application

object AppUtils {
    private lateinit var mApplication: Application

    val app: Application get() = mApplication

    fun init(application: Application) {
        mApplication = application
    }

}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/ClickableMovementMethod.java
================================================
package com.chad.baserecyclerviewadapterhelper.utils;

import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.BaseMovementMethod;
import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.widget.TextView;

public class ClickableMovementMethod extends BaseMovementMethod {

    private static ClickableMovementMethod sInstance;

    public static ClickableMovementMethod getInstance() {
        if (sInstance == null) {
            sInstance = new ClickableMovementMethod();
        }
        return sInstance;
    }

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {

        int action = event.getActionMasked();
        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {

            int x = (int) event.getX();
            int y = (int) event.getY();
            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();
            x += widget.getScrollX();
            y += widget.getScrollY();

            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
            if (link.length > 0) {
                if (action == MotionEvent.ACTION_UP) {
                    link[0].onClick(widget);
                } else {
                    Selection.setSelection(buffer, buffer.getSpanStart(link[0]),
                            buffer.getSpanEnd(link[0]));
                }
                return true;
            } else {
                Selection.removeSelection(buffer);
            }
        }

        return false;
    }

    @Override
    public void initialize(TextView widget, Spannable text) {
        Selection.removeSelection(text);
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/Ext.kt
================================================
package com.chad.baserecyclerviewadapterhelper.utils

import android.view.Window
import androidx.core.view.WindowCompat


/**
 * 设置状态栏高亮模式
 */
inline var Window.statusBarLightMode: Boolean
    set(value) {
        WindowCompat.getInsetsController(this, decorView).isAppearanceLightStatusBars = value
    }
    get() {
        return WindowCompat.getInsetsController(this, decorView).isAppearanceLightStatusBars
    }


/**
 * dp 转 px
 */
inline val Int.dp: Int
    get() {
        return (this * AppUtils.app.resources.displayMetrics.density + 0.5f).toInt()
    }

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/Tips.java
================================================
package com.chad.baserecyclerviewadapterhelper.utils;

import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

public class Tips {

    /**
     * 显示 Toast
     * @param message 提示信息
     */
    public static void show(String message) {
        show(message, Toast.LENGTH_SHORT);
    }

    /**
     * 显示 Toast
     * @param message 提示信息
     * @param duration 显示时间长短
     */
    public static void show(String message, int duration) {
        Toast toast = new Toast(AppUtils.INSTANCE.getApp());
        toast.setDuration(duration);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.setView(createTextToastView(message));
        toast.show();
    }

    /**
     * 创建自定义 Toast View
     *
     * @param message 文本消息
     * @return View
     */
    private static View createTextToastView(String message) {
        // 画圆角矩形背景
        float rc = dp2px(6);
        RoundRectShape shape = new RoundRectShape(new float[]{rc, rc, rc, rc, rc, rc, rc, rc}, null, null);
        ShapeDrawable drawable = new ShapeDrawable(shape);
        drawable.getPaint().setColor(Color.argb(225, 240, 240, 240));
        drawable.getPaint().setStyle(Paint.Style.FILL);
        drawable.getPaint().setAntiAlias(true);
        drawable.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);

        // 创建View
        FrameLayout layout = new FrameLayout(AppUtils.INSTANCE.getApp());
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layout.setLayoutParams(layoutParams);
        layout.setPadding(dp2px(16), dp2px(12), dp2px(16), dp2px(12));
        layout.setBackground(drawable);

        TextView textView = new TextView(AppUtils.INSTANCE.getApp());
        textView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
        textView.setTextSize(15);
        textView.setText(message);
        textView.setLineSpacing(dp2px(4), 1f);
        textView.setTextColor(Color.BLACK);

        layout.addView(textView);

        return layout;
    }

    private static int dp2px(float dpValue) {
        final float scale = AppUtils.INSTANCE.getApp().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}


================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/VibratorUtils.kt
================================================
package com.chad.baserecyclerviewadapterhelper.utils

import android.app.Service
import android.content.Context
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import android.os.VibratorManager

/**
 * 震动
 */
fun Context.vibrate() {
    if (Build.VERSION.SDK_INT >= 31) {
        // android 12 及以上使用新的 VibratorManager,创建 EFFECT_TICK 轻微震动(需要线性震动马达硬件支持)
        val manager: VibratorManager =
            getSystemService(VibratorManager::class.java)
        manager.defaultVibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
    } else if (Build.VERSION.SDK_INT >= 29) {
        // android 10 及以上使用原 Vibrator,创建 EFFECT_TICK 轻微震动(需要线性震动马达硬件支持)
        val vib = getSystemService(Vibrator::class.java) as Vibrator
        vib.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
    } else {
        // 10 以下的系统,没有系统 API 驱动线性震动马达,只能创建普通震动
        val vib = getSystemService(Service.VIBRATOR_SERVICE) as Vibrator //震动70毫秒
        vib.vibrate(70)
    }
}

================================================
FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/widget/BRVAHToolbar.kt
================================================
package com.chad.baserecyclerviewadapterhelper.widget

import android.content.Context
import android.os.Build
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import android.widget.RelativeLayout
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.databinding.LayoutToolBarBinding

class BRVAHToolbar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    private val binding = LayoutToolBarBinding.inflate(LayoutInflater.from(context), this)

    var title: String?
        get() = binding.tvTitle.text.toString()
        set(value) {
            binding.tvTitle.text = value
        }

    init {
        orientation = VERTICAL
        setBackgroundColor(ContextCompat.getColor(context, R.color.spinner_bg))
        elevation = context.dpF(10)
    }


    fun updateFakeBarHeight(h: Int) {
        binding.fakeBar.updateLayoutParams { this.height = h }
    }

    fun setOnBackListener(listener: OnClickListener) {
        binding.ivBack.setOnClickListener(listener)
    }

    private companion object {
        fun Context.dp(value: Int): Int {
            return (value * this.resources.displayMetrics.density + 0.5f).toInt()
        }

        fun Context.dpF(value: Int): Float {
            return value * this.resources.displayMetrics.density + 0.5f
        }
    }

}

================================================
FILE: app/src/main/res/anim/item_animation_from_bottom.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="400">
    <translate
        android:fromYDelta="50%p"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:toYDelta="0" />
    <alpha
        android:fromAlpha="0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:toAlpha="1" />
</set>

================================================
FILE: app/src/main/res/anim/layout_animation_from_bottom.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/item_animation_from_bottom"
    android:animationOrder="normal"
    android:delay="15%" />

================================================
FILE: app/src/main/res/drawable/actionbar_bottom_bg.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android = "http://schemas.android.com/apk/res/android" >

    <!-- 红色背景 -->
    <item>
        <color android:color="@color/spinner_bg" />
    </item>
    <!-- 白色背景 -->
    <item android:bottom="1px" android:drawable="@color/spinner_bg" />
</layer-list >


================================================
FILE: app/src/main/res/drawable/brvah_sample_footer_loading_progress.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <rotate
            android:drawable="@drawable/brvah_sample_footer_loading"
            android:duration="500"
            android:fromDegrees="0.0"
            android:pivotX="50.0%"
            android:pivotY="50.0%"
            android:toDegrees="360.0" />
    </item>

</layer-list>

================================================
FILE: app/src/main/res/drawable/custom_text_state_color.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:color="#ffffff" android:state_checked="true"/>
	<item android:color="@color/gray_color" android:state_checked="false"/>
</selector>


================================================
FILE: app/src/main/res/drawable/gv_up_fetch.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/gv_animation"
    android:fromDegrees="180"
    android:toDegrees="180"
    android:pivotX="50%"
    android:pivotY="50%">

</rotate>

================================================
FILE: app/src/main/res/drawable/ic_node_down.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="48dp"
    android:height="48dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
  <path
      android:pathData="M533.3,388.3L358.4,213.3 298.7,277.3l234.7,234.7L768,277.3 708.3,213.3l-174.9,174.9zM533.3,648.5l-174.9,-174.9L298.7,533.3l234.7,234.7 234.7,-234.7 -59.7,-59.7 -174.9,174.9z"
      android:fillColor="#444444"/>
</vector>


================================================
FILE: app/src/main/res/drawable/ic_node_right.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="48dp"
    android:height="48dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
  <path
      android:pathData="M430.9,490.7L256,665.6 315.7,725.3l234.7,-234.7L315.7,256 256,315.7l174.9,174.9zM686.9,490.7L512,665.6l59.7,59.7 234.7,-234.7L576,256 512,315.7l174.9,174.9z"
      android:fillColor="#444444"/>
</vector>


================================================
FILE: app/src/main/res/drawable/selector_item_child.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/holo_orange_light" android:state_pressed="true" />
    <item android:drawable="@android:color/holo_red_light" android:state_pressed="true"/>
    <item android:state_active="false">
        <shape android:shape="rectangle">
            <corners android:radius="4dp"/>
            <solid android:color="@color/item_bg"/>
            <stroke android:color="@color/color_light_blue" android:width="1dp"/>
        </shape>
    </item>
</selector>


================================================
FILE: app/src/main/res/drawable/shape_right_top_float_bg.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <solid android:color="@color/bg" />
    <corners android:bottomLeftRadius="16dp" />

    <stroke
        android:width="2dp"
        android:color="@color/colorPrimary" />

</shape>

================================================
FILE: app/src/main/res/drawable/thumb_drawable.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:state_enabled="false" android:state_checked="true">
		<shape android:shape="oval">
			<solid android:color="#E1E1E1"/>
			<stroke
				android:width="1px"
				android:color="#ECECEC"/>
		</shape>
	</item>
	<item android:state_enabled="false">
		<shape android:shape="oval">
			<solid android:color="#555771"/>
			<stroke
				android:width="1px"
				android:color="#55577E"/>
		</shape>
	</item>
	<item android:state_checked="true">
		<shape android:shape="oval">
			<solid android:color="#E1E1E1"/>
			<stroke
				android:width="1px"
				android:color="#D0D0D0"/>
		</shape>
	</item>
	<item>
		<shape android:shape="oval">
			<solid android:color="#555771"/>
			<stroke
				android:width="1px"
				android:color="#55577E"/>
		</shape>
	</item>
</selector>


================================================
FILE: app/src/main/res/drawable/touch_bg.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/gray_color" android:state_pressed="true"/>
    <item android:drawable="@color/gray_color" android:state_focused="true"/>
    <item android:drawable="@color/item_bg"/>
</selector>


================================================
FILE: app/src/main/res/drawable-v21/touch_bg.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/gray_color">
    <item android:id="@android:id/mask"
          android:drawable="@android:color/white" />
    <item>
        <shape android:shape="rectangle" >
            <corners android:radius="@dimen/dp_4"/>
            <solid android:color="@color/item_bg"/>
            <stroke android:color="@color/gray_color" android:width="1px"/>
        </shape>
    </item>
</ripple>


================================================
FILE: app/src/main/res/layout/activity_animation_use.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/bg">

    <com.chad.baserecyclerviewadapterhelper.widget.BRVAHToolbar
        android:id="@+id/title_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="@color/spinner_bg"
        android:gravity="center"
        android:orientation="horizontal"
        android:paddingLeft="@dimen/dp_10"
        android:paddingRight="@dimen/dp_10">


        <com.jaredrummler.materialspinner.MaterialSpinner
            android:id="@+id/spinner"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@null"
            app:ms_background_color="@color/spinner_bg"
            app:ms_hide_arrow="false"
            app:ms_text_color="#ffffff" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@color/spinner_bg"
            android:gravity="center|right">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="IsFirstOnly"
                android:textColor="@color/new_text_color"
                android:textSize="16sp" />

            <com.kyleduo.switchbutton.SwitchButton
                android:id="@+id/switch_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="12dp"
                android:textColor="@drawable/custom_text_state_color"
                app:kswTextOff="false"
                app:kswTextOn="true"
                app:kswThumbColor="#555771"
                app:kswThumbDrawable="@drawable/thumb_drawable"
                app:kswTintColor="#00ddB6" />

        </LinearLayout>
    </LinearLayout>


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fadingEdge="none"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

</LinearLayout>


================================================
FILE: app/src/main/res/layout/activity_choose_multiple_item_use_type.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="vertical">

        <androidx.cardview.widget.CardView
            android:id="@+id/card_view0"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="5dp"
            android:foreground="?android:attr/selectableItemBackground"
            card_view:cardBackgroundColor="@color/item_bg"
            card_view:cardCornerRadius="4dp"
            card_view:cardElevation="2dp"
            card_view:cardUseCompatPadding="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:scaleType="centerCrop"
                    android:src="@mipmap/animation_img1" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:gravity="center"
                    android:text="BaseBinderAdapter"
                    android:textColor="@android:color/black"
                    android:textSize="18sp"
                    android:textStyle="bold" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginTop="8dp"
                    android:gravity="center"
                    android:text="更高灵活度,推荐优先使用"
                    android:textColor="@android:color/black"
                    android:textSize="16sp" />

            </LinearLayout>

        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView
            android:id="@+id/card_view1"
            android:layout_width="match_parent"
            android:layout_height="150dp"
            android:layout_gravity="center"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="5dp"
            android:foreground="?android:attr/selectableItemBackground"
            card_view:cardBackgroundColor="@color/item_bg"
            card_view:cardCornerRadius="4dp"
            card_view:cardElevation="2dp"
            car
Download .txt
gitextract_07v8rp8z/

├── .circleci/
│   └── config.yml
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   └── bug_report.md
│   └── pull_request_template.md
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── chad/
│           │           └── baserecyclerviewadapterhelper/
│           │               ├── MyApplication.kt
│           │               ├── activity/
│           │               │   ├── WelcomeActivity.java
│           │               │   ├── animation/
│           │               │   │   ├── AnimationUseActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── AnimationAdapter.kt
│           │               │   ├── databinding/
│           │               │   │   ├── DataBindingUseActivity.java
│           │               │   │   └── adapter/
│           │               │   │       └── DataBindingAdapter.java
│           │               │   ├── differ/
│           │               │   │   ├── DifferActivity.java
│           │               │   │   └── adapter/
│           │               │   │       ├── DiffEntityCallback.java
│           │               │   │       └── DiffUtilAdapter.java
│           │               │   ├── dragswipe/
│           │               │   │   ├── DefaultDragAndSwipeActivity.kt
│           │               │   │   ├── DragAndSwipeDifferActivity.kt
│           │               │   │   ├── DragAndSwipeUseActivity.java
│           │               │   │   ├── HeaderDragAndSwipe.kt
│           │               │   │   ├── HeaderDragAndSwipeActivity.kt
│           │               │   │   ├── ManualDragAndSwipeUseActivity.java
│           │               │   │   └── adapter/
│           │               │   │       ├── DiffDragAndSwipeAdapter.kt
│           │               │   │       ├── DragAndSwipeAdapter.java
│           │               │   │       └── HeaderDragAndSwipeAdapter.kt
│           │               │   ├── emptyview/
│           │               │   │   ├── EmptyViewUseActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── EmptyViewAdapter.kt
│           │               │   ├── headerfooter/
│           │               │   │   ├── HeaderAndFooterUseActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       ├── FooterAdapter.kt
│           │               │   │       ├── HeaderAdapter.kt
│           │               │   │       └── HeaderAndFooterAdapter.kt
│           │               │   ├── home/
│           │               │   │   ├── HomeActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       ├── HomeAdapter.kt
│           │               │   │       └── HomeTopHeaderAdapter.kt
│           │               │   ├── itemclick/
│           │               │   │   ├── ItemClickActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── ItemClickAdapter.java
│           │               │   ├── loadmore/
│           │               │   │   ├── AutoLoadMoreRefreshUseActivity.kt
│           │               │   │   ├── NoAutoAutoLoadMoreRefreshUseActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       ├── CustomLoadMoreAdapter.kt
│           │               │   │       └── RecyclerViewAdapter.kt
│           │               │   ├── node/
│           │               │   │   ├── NodeActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── NodeAdapter.kt
│           │               │   ├── scene/
│           │               │   │   ├── GroupDemoActivity.kt
│           │               │   │   └── adapter/
│           │               │   │       └── GroupAdapter.kt
│           │               │   └── upfetch/
│           │               │       ├── UpFetchUseActivity.kt
│           │               │       └── adapter/
│           │               │           └── UpFetchAdapter.kt
│           │               ├── animator/
│           │               │   ├── CustomAnimation1.java
│           │               │   ├── CustomAnimation2.java
│           │               │   └── CustomAnimation3.java
│           │               ├── base/
│           │               │   ├── BaseActivity.kt
│           │               │   └── BaseViewBindingActivity.kt
│           │               ├── data/
│           │               │   └── DataServer.kt
│           │               ├── decoration/
│           │               │   ├── GridItemDecoration.java
│           │               │   └── GridSectionAverageGapItemDecoration.java
│           │               ├── entity/
│           │               │   ├── ClickEntity.java
│           │               │   ├── DiffEntity.java
│           │               │   ├── GroupDemoEntity.kt
│           │               │   ├── HomeEntity.kt
│           │               │   ├── Movie.java
│           │               │   ├── MoviePresenter.java
│           │               │   ├── NodeEntity.kt
│           │               │   └── Status.java
│           │               ├── utils/
│           │               │   ├── AppUtils.kt
│           │               │   ├── ClickableMovementMethod.java
│           │               │   ├── Ext.kt
│           │               │   ├── Tips.java
│           │               │   └── VibratorUtils.kt
│           │               └── widget/
│           │                   └── BRVAHToolbar.kt
│           └── res/
│               ├── anim/
│               │   ├── item_animation_from_bottom.xml
│               │   └── layout_animation_from_bottom.xml
│               ├── drawable/
│               │   ├── actionbar_bottom_bg.xml
│               │   ├── brvah_sample_footer_loading_progress.xml
│               │   ├── custom_text_state_color.xml
│               │   ├── gv_up_fetch.xml
│               │   ├── ic_node_down.xml
│               │   ├── ic_node_right.xml
│               │   ├── selector_item_child.xml
│               │   ├── shape_right_top_float_bg.xml
│               │   ├── thumb_drawable.xml
│               │   └── touch_bg.xml
│               ├── drawable-v21/
│               │   └── touch_bg.xml
│               ├── layout/
│               │   ├── activity_animation_use.xml
│               │   ├── activity_choose_multiple_item_use_type.xml
│               │   ├── activity_choose_node_use_type.xml
│               │   ├── activity_diffutil.xml
│               │   ├── activity_empty_view_use.xml
│               │   ├── activity_home.xml
│               │   ├── activity_load_more.xml
│               │   ├── activity_node.xml
│               │   ├── activity_universal_recycler.xml
│               │   ├── activity_welcome.xml
│               │   ├── def_section_head.xml
│               │   ├── empty_view.xml
│               │   ├── error_view.xml
│               │   ├── footer_view.xml
│               │   ├── head_view.xml
│               │   ├── home_item_view.xml
│               │   ├── item_click_childview.xml
│               │   ├── item_click_view.xml
│               │   ├── item_draggable_view.xml
│               │   ├── item_group_type.xml
│               │   ├── item_header_and_footer.xml
│               │   ├── item_image_view.xml
│               │   ├── item_img_text_view.xml
│               │   ├── item_long_click_childview.xml
│               │   ├── item_long_click_view.xml
│               │   ├── item_movie.xml
│               │   ├── item_node_level_1.xml
│               │   ├── item_node_level_2.xml
│               │   ├── item_node_level_3.xml
│               │   ├── item_section_content.xml
│               │   ├── layout_animation.xml
│               │   ├── layout_title_bar.xml
│               │   ├── layout_tool_bar.xml
│               │   ├── loading_view.xml
│               │   ├── node_footer.xml
│               │   ├── toolbar_layout.xml
│               │   ├── top_view.xml
│               │   └── view_load_more.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── dimens.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               ├── values-v21/
│               │   └── styles.xml
│               └── values-zh/
│                   └── strings.xml
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library/
│   ├── .gitignore
│   ├── build.gradle.kts
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── chad/
│           │           └── library/
│           │               └── adapter4/
│           │                   ├── BaseDifferAdapter.kt
│           │                   ├── BaseMultiItemAdapter.kt
│           │                   ├── BaseNodeAdapter.kt
│           │                   ├── BaseQuickAdapter.kt
│           │                   ├── BaseSingleItemAdapter.kt
│           │                   ├── QuickAdapterHelper.kt
│           │                   ├── animation/
│           │                   │   ├── AlphaInAnimation.kt
│           │                   │   ├── ItemAnimator.kt
│           │                   │   ├── ScaleInAnimation.kt
│           │                   │   ├── SlideInBottomAnimation.kt
│           │                   │   ├── SlideInLeftAnimation.kt
│           │                   │   └── SlideInRightAnimation.kt
│           │                   ├── dragswipe/
│           │                   │   ├── DragSwipeExt.kt
│           │                   │   ├── QuickDragAndSwipe.kt
│           │                   │   └── listener/
│           │                   │       ├── DragAndSwipeDataCallback.kt
│           │                   │       ├── OnItemDragListener.java
│           │                   │       └── OnItemSwipeListener.java
│           │                   ├── fullspan/
│           │                   │   └── FullSpanAdapterType.kt
│           │                   ├── layoutmanager/
│           │                   │   └── QuickGridLayoutManager.kt
│           │                   ├── loadState/
│           │                   │   ├── LoadState.kt
│           │                   │   ├── LoadStateAdapter.kt
│           │                   │   ├── leading/
│           │                   │   │   ├── DefaultLeadingLoadStateAdapter.kt
│           │                   │   │   └── LeadingLoadStateAdapter.kt
│           │                   │   └── trailing/
│           │                   │       ├── DefaultTrailingLoadStateAdapter.kt
│           │                   │       └── TrailingLoadStateAdapter.kt
│           │                   ├── util/
│           │                   │   ├── AdapterUtils.kt
│           │                   │   └── ItemClickUtils.kt
│           │                   └── viewholder/
│           │                       ├── DataBindingHolder.java
│           │                       ├── QuickViewHolder.kt
│           │                       └── StateLayoutVH.kt
│           └── res/
│               ├── layout/
│               │   ├── brvah_leading_load_more.xml
│               │   └── brvah_trailing_load_more.xml
│               ├── values/
│               │   ├── ids.xml
│               │   └── strings.xml
│               ├── values-en/
│               │   └── strings.xml
│               ├── values-zh-rHK/
│               │   └── strings.xml
│               └── values-zh-rTW/
│                   └── strings.xml
└── settings.gradle
Download .txt
SYMBOL INDEX (119 symbols across 24 files)

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/WelcomeActivity.java
  class WelcomeActivity (line 12) | public class WelcomeActivity extends AppCompatActivity {
    method onCreate (line 14) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/DataBindingUseActivity.java
  class DataBindingUseActivity (line 28) | public final class DataBindingUseActivity extends BaseViewBindingActivit...
    method initBinding (line 32) | @NonNull
    method onPointerCaptureChanged (line 38) | @Override
    method onCreate (line 43) | @Override
    method genData (line 73) | private List<Movie> genData() {

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/adapter/DataBindingAdapter.java
  class DataBindingAdapter (line 22) | public class DataBindingAdapter extends BaseQuickAdapter<Movie, DataBind...
    method onCreateViewHolder (line 26) | @NonNull
    method onBindViewHolder (line 32) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/DifferActivity.java
  class DifferActivity (line 26) | public final class DifferActivity extends BaseViewBindingActivity<Activi...
    method initBinding (line 30) | @NonNull
    method onCreate (line 36) | @Override
    method onStart (line 55) | @Override
    method initRv (line 64) | private void initRv() {
    method initClick (line 75) | private void initClick() {
    method getNewList (line 102) | private List<DiffEntity> getNewList() {

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffEntityCallback.java
  class DiffEntityCallback (line 11) | public class DiffEntityCallback extends DiffUtil.ItemCallback<DiffEntity> {
    method areItemsTheSame (line 22) | @Override
    method areContentsTheSame (line 36) | @Override
    method getChangePayload (line 56) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffUtilAdapter.java
  class DiffUtilAdapter (line 16) | public class DiffUtilAdapter extends BaseQuickAdapter<DiffEntity, QuickV...
    method DiffUtilAdapter (line 18) | public DiffUtilAdapter() {
    method onCreateViewHolder (line 23) | @NonNull
    method onBindViewHolder (line 29) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeUseActivity.java
  class DragAndSwipeUseActivity (line 24) | public class DragAndSwipeUseActivity extends BaseViewBindingActivity<Act...
    method initBinding (line 27) | @NonNull
    method onCreate (line 33) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/ManualDragAndSwipeUseActivity.java
  class ManualDragAndSwipeUseActivity (line 38) | public class ManualDragAndSwipeUseActivity extends BaseViewBindingActivi...
    method initBinding (line 51) | @NonNull
    method onCreate (line 57) | @Override
    method generateData (line 164) | private List<String> generateData(int size) {

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DragAndSwipeAdapter.java
  class DragAndSwipeAdapter (line 14) | public class DragAndSwipeAdapter extends BaseQuickAdapter<String, QuickV...
    method onCreateViewHolder (line 16) | @NonNull
    method onBindViewHolder (line 22) | @Override
    method dataMove (line 34) | @Override
    method dataRemoveAt (line 39) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/adapter/ItemClickAdapter.java
  class ItemClickAdapter (line 22) | public class ItemClickAdapter extends BaseMultiItemAdapter<ClickEntity> {
    class ItemViewVH (line 24) | static class ItemViewVH extends RecyclerView.ViewHolder {
      method ItemViewVH (line 28) | public ItemViewVH(@NonNull ItemClickViewBinding viewBinding) {
      method ItemViewVH (line 33) | public ItemViewVH(@NonNull ViewGroup parent) {
    class ItemChildVH (line 38) | static class ItemChildVH extends RecyclerView.ViewHolder {
      method ItemChildVH (line 42) | public ItemChildVH(@NonNull ItemClickChildviewBinding viewBinding) {
      method ItemChildVH (line 47) | public ItemChildVH(@NonNull ViewGroup parent) {
    class ItemLongClickVH (line 52) | static class ItemLongClickVH extends RecyclerView.ViewHolder {
      method ItemLongClickVH (line 56) | public ItemLongClickVH(@NonNull ItemLongClickViewBinding viewBinding) {
      method ItemLongClickVH (line 61) | public ItemLongClickVH(@NonNull ViewGroup parent) {
    class ItemChildLongClickVH (line 66) | static class ItemChildLongClickVH extends RecyclerView.ViewHolder {
      method ItemChildLongClickVH (line 70) | public ItemChildLongClickVH(@NonNull ItemLongClickChildviewBinding v...
      method ItemChildLongClickVH (line 75) | public ItemChildLongClickVH(@NonNull ViewGroup parent) {
    method ItemClickAdapter (line 83) | public ItemClickAdapter(List<ClickEntity> data) {

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation1.java
  class CustomAnimation1 (line 14) | public class CustomAnimation1 implements ItemAnimator {
    method animator (line 15) | @NotNull

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation2.java
  class CustomAnimation2 (line 20) | public class CustomAnimation2 implements ItemAnimator {
    method animator (line 21) | @NotNull
    class MyInterpolator2 (line 33) | private static class MyInterpolator2 implements Interpolator {
      method getInterpolation (line 34) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation3.java
  class CustomAnimation3 (line 13) | public class CustomAnimation3 implements ItemAnimator {
    method animator (line 15) | @NotNull

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridItemDecoration.java
  class GridItemDecoration (line 15) | public class GridItemDecoration extends RecyclerView.ItemDecoration {
    method GridItemDecoration (line 20) | public GridItemDecoration(Drawable divider) {
    method GridItemDecoration (line 24) | public GridItemDecoration(Context context, int resId) {
    method GridItemDecoration (line 28) | public GridItemDecoration(Context context, int resId, int orientation) {
    method getItemOffsets (line 33) | @Override
    method onDrawOver (line 55) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/ClickEntity.java
  class ClickEntity (line 25) | public class ClickEntity {
    method ClickEntity (line 32) | public ClickEntity(final int type) {
    method getItemType (line 36) | public int getItemType() {

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/DiffEntity.java
  class DiffEntity (line 5) | public class DiffEntity {
    method DiffEntity (line 12) | public DiffEntity(int id, String title, String content, String date) {
    method getId (line 19) | public int getId() {
    method setId (line 23) | public void setId(int id) {
    method getTitle (line 27) | public String getTitle() {
    method setTitle (line 31) | public void setTitle(String title) {
    method getContent (line 35) | public String getContent() {
    method setContent (line 39) | public void setContent(String content) {
    method getDate (line 43) | public String getDate() {
    method setDate (line 47) | public void setDate(String date) {
    method equals (line 51) | @Override
    method hashCode (line 59) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Movie.java
  class Movie (line 7) | public class Movie {
    method Movie (line 14) | public Movie(String name, int length, int price, String content) {

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MoviePresenter.java
  class MoviePresenter (line 11) | public class MoviePresenter {
    method buyTicket (line 12) | public void buyTicket(View view, Movie movie) {

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Status.java
  class Status (line 6) | public class Status {
    method isRetweet (line 13) | public boolean isRetweet() {
    method setRetweet (line 17) | public void setRetweet(boolean retweet) {
    method getText (line 21) | public String getText() {
    method setText (line 25) | public void setText(String text) {
    method getUserName (line 29) | public String getUserName() {
    method setUserName (line 33) | public void setUserName(String userName) {
    method getUserAvatar (line 37) | public int getUserAvatar() {
    method setUserAvatar (line 41) | public void setUserAvatar(int userAvatar) {
    method getCreatedAt (line 45) | public String getCreatedAt() {
    method setCreatedAt (line 49) | public void setCreatedAt(String createdAt) {
    method toString (line 53) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/ClickableMovementMethod.java
  class ClickableMovementMethod (line 11) | public class ClickableMovementMethod extends BaseMovementMethod {
    method getInstance (line 15) | public static ClickableMovementMethod getInstance() {
    method onTouchEvent (line 22) | @Override
    method initialize (line 56) | @Override

FILE: app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/Tips.java
  class Tips (line 14) | public class Tips {
    method show (line 20) | public static void show(String message) {
    method show (line 29) | public static void show(String message, int duration) {
    method createTextToastView (line 43) | private static View createTextToastView(String message) {
    method dp2px (line 72) | private static int dp2px(float dpValue) {

FILE: library/src/main/java/com/chad/library/adapter4/dragswipe/listener/OnItemDragListener.java
  type OnItemDragListener (line 10) | public interface OnItemDragListener {
    method onItemDragStart (line 11) | void onItemDragStart(@Nullable RecyclerView.ViewHolder viewHolder, int...
    method onItemDragMoving (line 13) | void onItemDragMoving(@NonNull RecyclerView.ViewHolder source, int fro...
    method onItemDragEnd (line 15) | void onItemDragEnd(@NonNull RecyclerView.ViewHolder viewHolder, int pos);

FILE: library/src/main/java/com/chad/library/adapter4/dragswipe/listener/OnItemSwipeListener.java
  type OnItemSwipeListener (line 12) | public interface OnItemSwipeListener {
    method onItemSwipeStart (line 16) | void onItemSwipeStart(@Nullable RecyclerView.ViewHolder viewHolder, in...
    method onItemSwipeEnd (line 24) | void onItemSwipeEnd(@NonNull RecyclerView.ViewHolder viewHolder, int b...
    method onItemSwiped (line 29) | void onItemSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int dir...
    method onItemSwipeMoving (line 42) | void onItemSwipeMoving(@NonNull Canvas canvas, @NonNull RecyclerView.V...

FILE: library/src/main/java/com/chad/library/adapter4/viewholder/DataBindingHolder.java
  class DataBindingHolder (line 18) | public class DataBindingHolder<DB extends ViewDataBinding> extends Recyc...
    method DataBindingHolder (line 22) | public DataBindingHolder(DB binding) {
    method DataBindingHolder (line 27) | public DataBindingHolder(@NonNull View itemView) {
    method DataBindingHolder (line 35) | public DataBindingHolder(@LayoutRes int resId, @NonNull ViewGroup pare...
    method getBinding (line 39) | @NonNull
Condensed preview — 177 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (421K chars).
[
  {
    "path": ".circleci/config.yml",
    "chars": 764,
    "preview": "version: 2\njobs:\n  build:\n    working_directory: ~/code\n    docker:\n      - image: cimg/android:2023.04\n    environment:"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1284,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\n\n---\n\n**Describe the bug**\nA clear and concise descriptio"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 544,
    "preview": "Thank you for contributing to BaseRecyclerViewAdapterHelper. Before pressing the \"Create Pull Request\" button, please co"
  },
  {
    "path": ".gitignore",
    "chars": 543,
    "preview": "#/////////////////////////////////////////////////////////////////////////////\n# OS generated files\n#///////////////////"
  },
  {
    "path": ".travis.yml",
    "chars": 389,
    "preview": "language: android\ndist: trusty\njdk: oraclejdk11\nsudo: false\n\nandroid:\ncomponents:\n    - tools\n    - platform-tools\n    -"
  },
  {
    "path": "LICENSE",
    "chars": 1060,
    "preview": "MIT License\n\nCopyright (c) 2023 陈宇明\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof thi"
  },
  {
    "path": "README.md",
    "chars": 4206,
    "preview": "![](https://user-images.githubusercontent.com/7698209/33198075-ef8f2230-d123-11e7-85a3-4cb9b22f877d.png)\n[![](https://im"
  },
  {
    "path": "app/.gitignore",
    "chars": 106,
    "preview": ".gradle/\n.DS_Store\nlocal.properties\n\n# build files\nbuild/\nbin/\ngen/\noutput/\n\n# android studio\n*.iml\n.idea\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 1779,
    "preview": "plugins {\n    id 'com.android.application'\n    id 'kotlin-android'\n    id 'kotlin-kapt'\n    id 'com.google.devtools.ksp'"
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 689,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 3109,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <uses-"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.kt",
    "chars": 906,
    "preview": "/*\n******************************* Copyright (c)*********************************\\\n**\n**                 (c) Copyright 2"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/WelcomeActivity.java",
    "chars": 837,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimpor"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/AnimationUseActivity.kt",
    "chars": 3303,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.animation\n\nimport android.os.Bundle\nimport androidx.core.view.Vi"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/adapter/AnimationAdapter.kt",
    "chars": 2722,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.animation.adapter\n\nimport android.content.Context\nimport android"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/DataBindingUseActivity.java",
    "chars": 2968,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.databinding;\n\nimport android.os.Bundle;\nimport android.view.View"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/adapter/DataBindingAdapter.java",
    "chars": 1467,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.databinding.adapter;\n\nimport android.content.Context;\nimport and"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/DifferActivity.java",
    "chars": 4557,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.differ;\n\nimport android.os.Bundle;\nimport android.view.View;\n\nim"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffEntityCallback.java",
    "chars": 1805,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter;\n\nimport androidx.annotation.NonNull;\nimport andr"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffUtilAdapter.java",
    "chars": 1115,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter;\n\nimport android.content.Context;\nimport android."
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DefaultDragAndSwipeActivity.kt",
    "chars": 6317,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe\n\nimport android.animation.ValueAnimator\nimport android"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeDifferActivity.kt",
    "chars": 6298,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe\n\nimport android.animation.ValueAnimator\nimport android"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeUseActivity.java",
    "chars": 2969,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe;\n\n\nimport android.content.Intent;\nimport android.os.Bu"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipe.kt",
    "chars": 1042,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe\n\nimport androidx.recyclerview.widget.ConcatAdapter\nimp"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipeActivity.kt",
    "chars": 8307,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe\n\nimport android.animation.ValueAnimator\nimport android"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/ManualDragAndSwipeUseActivity.java",
    "chars": 7436,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe;\n\nimport android.animation.ValueAnimator;\nimport andro"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DiffDragAndSwipeAdapter.kt",
    "chars": 1075,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter\n\nimport android.content.Context\nimport android"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DragAndSwipeAdapter.java",
    "chars": 1483,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter;\n\n\nimport android.content.Context;\nimport andr"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/HeaderDragAndSwipeAdapter.kt",
    "chars": 1354,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter\n\nimport android.content.Context\nimport android"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/EmptyViewUseActivity.kt",
    "chars": 3114,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.emptyview\n\nimport android.os.Bundle\nimport android.view.View\nimp"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/adapter/EmptyViewAdapter.kt",
    "chars": 1162,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.emptyview.adapter\n\nimport android.content.Context\nimport android"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/HeaderAndFooterUseActivity.kt",
    "chars": 2736,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.headerfooter\n\nimport android.os.Bundle\nimport androidx.core.view"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/FooterAdapter.kt",
    "chars": 763,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter\n\nimport android.content.Context\nimport andr"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAdapter.kt",
    "chars": 771,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter\n\nimport android.content.Context\nimport andr"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAndFooterAdapter.kt",
    "chars": 1380,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter\n\nimport android.content.Context\nimport andr"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/HomeActivity.kt",
    "chars": 4449,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.home\n\nimport android.content.Intent\nimport android.os.Bundle\nimp"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeAdapter.kt",
    "chars": 2612,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.home.adapter\n\nimport android.content.Context\nimport android.view"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeTopHeaderAdapter.kt",
    "chars": 1019,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.home.adapter\n\nimport android.content.Context\nimport android.view"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/ItemClickActivity.kt",
    "chars": 4041,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.itemclick\n\nimport android.os.Bundle\nimport androidx.core.view.Vi"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/adapter/ItemClickAdapter.java",
    "chars": 5333,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.itemclick.adapter;\n\nimport android.content.Context;\nimport andro"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/AutoLoadMoreRefreshUseActivity.kt",
    "chars": 7355,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.loadmore\n\nimport android.graphics.Color\nimport android.os.Bundle"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/NoAutoAutoLoadMoreRefreshUseActivity.kt",
    "chars": 7783,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.loadmore\n\nimport android.graphics.Color\nimport android.os.Bundle"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/CustomLoadMoreAdapter.kt",
    "chars": 3383,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter\n\nimport android.view.LayoutInflater\nimport andr"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/RecyclerViewAdapter.kt",
    "chars": 2614,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter\n\nimport android.content.Context\nimport android."
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/NodeActivity.kt",
    "chars": 1737,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.node\n\nimport android.os.Bundle\nimport androidx.core.view.ViewCom"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/adapter/NodeAdapter.kt",
    "chars": 6334,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.node.adapter\n\nimport android.content.Context\nimport android.view"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/GroupDemoActivity.kt",
    "chars": 4235,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.scene\n\nimport android.graphics.drawable.ColorDrawable\nimport and"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/adapter/GroupAdapter.kt",
    "chars": 2077,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.scene.adapter\n\nimport android.content.Context\nimport android.vie"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/UpFetchUseActivity.kt",
    "chars": 4220,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.upfetch\n\nimport android.os.Bundle\nimport androidx.core.view.View"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/adapter/UpFetchAdapter.kt",
    "chars": 1383,
    "preview": "package com.chad.baserecyclerviewadapterhelper.activity.upfetch.adapter\n\nimport android.content.Context\nimport android.v"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation1.java",
    "chars": 1038,
    "preview": "package com.chad.baserecyclerviewadapterhelper.animator;\n\nimport android.animation.Animator;\nimport android.animation.An"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation2.java",
    "chars": 1123,
    "preview": "package com.chad.baserecyclerviewadapterhelper.animator;\n\nimport android.animation.Animator;\nimport android.animation.Ob"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation3.java",
    "chars": 944,
    "preview": "package com.chad.baserecyclerviewadapterhelper.animator;\n\nimport android.animation.Animator;\nimport android.animation.An"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.kt",
    "chars": 935,
    "preview": "package com.chad.baserecyclerviewadapterhelper.base\n\nimport android.os.Build\nimport android.os.Bundle\nimport android.vie"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseViewBindingActivity.kt",
    "chars": 664,
    "preview": "package com.chad.baserecyclerviewadapterhelper.base\n\nimport android.view.View\nimport androidx.viewbinding.ViewBinding\n\na"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.kt",
    "chars": 3283,
    "preview": "package com.chad.baserecyclerviewadapterhelper.data\n\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.bas"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridItemDecoration.java",
    "chars": 2761,
    "preview": "package com.chad.baserecyclerviewadapterhelper.decoration;\n\nimport android.content.Context;\nimport android.graphics.Canv"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridSectionAverageGapItemDecoration.java",
    "chars": 9553,
    "preview": "//package com.chad.baserecyclerviewadapterhelper.decoration;\n//\n//import android.graphics.Rect;\n//import android.os.Buil"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/ClickEntity.java",
    "chars": 1098,
    "preview": "/*\n******************************* Copyright (c)*********************************\\\n**\n**                 (c) Copyright 2"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/DiffEntity.java",
    "chars": 1365,
    "preview": "package com.chad.baserecyclerviewadapterhelper.entity;\n\nimport java.util.Objects;\n\npublic class DiffEntity {\n\n    privat"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/GroupDemoEntity.kt",
    "chars": 498,
    "preview": "package com.chad.baserecyclerviewadapterhelper.entity\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClas"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeEntity.kt",
    "chars": 348,
    "preview": "package com.chad.baserecyclerviewadapterhelper.entity\n\n/**\n * @author: limuyang\n * @date: 2019-12-06\n * @Description:\n *"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Movie.java",
    "chars": 416,
    "preview": "package com.chad.baserecyclerviewadapterhelper.entity;\n\n/**\n * Created by luoxiongwen on 16/10/24.\n */\n\npublic class Mov"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MoviePresenter.java",
    "chars": 328,
    "preview": "package com.chad.baserecyclerviewadapterhelper.entity;\n\nimport android.view.View;\n\nimport com.chad.baserecyclerviewadapt"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/NodeEntity.kt",
    "chars": 414,
    "preview": "package com.chad.baserecyclerviewadapterhelper.entity\n\n/**\n * @author LiMuYang\n * @date 2025/9/5\n * @description\n */\ndat"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Status.java",
    "chars": 1388,
    "preview": "package com.chad.baserecyclerviewadapterhelper.entity;\n\n/**\n * https://github.com/CymChad/BaseRecyclerViewAdapterHelper\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/AppUtils.kt",
    "chars": 287,
    "preview": "package com.chad.baserecyclerviewadapterhelper.utils\n\nimport android.app.Application\n\nobject AppUtils {\n    private late"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/ClickableMovementMethod.java",
    "chars": 1937,
    "preview": "package com.chad.baserecyclerviewadapterhelper.utils;\n\nimport android.text.Layout;\nimport android.text.Selection;\nimport"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/Ext.kt",
    "chars": 563,
    "preview": "package com.chad.baserecyclerviewadapterhelper.utils\n\nimport android.view.Window\nimport androidx.core.view.WindowCompat\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/Tips.java",
    "chars": 2600,
    "preview": "package com.chad.baserecyclerviewadapterhelper.utils;\n\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimp"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/VibratorUtils.kt",
    "chars": 1032,
    "preview": "package com.chad.baserecyclerviewadapterhelper.utils\n\nimport android.app.Service\nimport android.content.Context\nimport a"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/widget/BRVAHToolbar.kt",
    "chars": 1608,
    "preview": "package com.chad.baserecyclerviewadapterhelper.widget\n\nimport android.content.Context\nimport android.os.Build\nimport and"
  },
  {
    "path": "app/src/main/res/anim/item_animation_from_bottom.xml",
    "chars": 450,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:durat"
  },
  {
    "path": "app/src/main/res/anim/layout_animation_from_bottom.xml",
    "chars": 234,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layoutAnimation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    a"
  },
  {
    "path": "app/src/main/res/drawable/actionbar_bottom_bg.xml",
    "chars": 312,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android = \"http://schemas.android.com/apk/res/android\" >\n\n    <"
  },
  {
    "path": "app/src/main/res/drawable/brvah_sample_footer_loading_progress.xml",
    "chars": 418,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <ite"
  },
  {
    "path": "app/src/main/res/drawable/custom_text_state_color.xml",
    "chars": 256,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\t<item andr"
  },
  {
    "path": "app/src/main/res/drawable/gv_up_fetch.xml",
    "chars": 271,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<rotate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:dr"
  },
  {
    "path": "app/src/main/res/drawable/ic_node_down.xml",
    "chars": 439,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"48dp\"\n    android:height=\"48dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/ic_node_right.xml",
    "chars": 422,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"48dp\"\n    android:height=\"48dp\"\n  "
  },
  {
    "path": "app/src/main/res/drawable/selector_item_child.xml",
    "chars": 594,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item a"
  },
  {
    "path": "app/src/main/res/drawable/shape_right_top_float_bg.xml",
    "chars": 292,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <solid an"
  },
  {
    "path": "app/src/main/res/drawable/thumb_drawable.xml",
    "chars": 879,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\t<item andr"
  },
  {
    "path": "app/src/main/res/drawable/touch_bg.xml",
    "chars": 323,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item a"
  },
  {
    "path": "app/src/main/res/drawable-v21/touch_bg.xml",
    "chars": 511,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:co"
  },
  {
    "path": "app/src/main/res/layout/activity_animation_use.xml",
    "chars": 2524,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/activity_choose_multiple_item_use_type.xml",
    "chars": 7028,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.core.widget.NestedScrollView xmlns:android=\"http://schemas.android.com/"
  },
  {
    "path": "app/src/main/res/layout/activity_choose_node_use_type.xml",
    "chars": 3100,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/activity_diffutil.xml",
    "chars": 2338,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/activity_empty_view_use.xml",
    "chars": 1418,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/activity_home.xml",
    "chars": 733,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/activity_load_more.xml",
    "chars": 1006,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/activity_node.xml",
    "chars": 2535,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/activity_universal_recycler.xml",
    "chars": 646,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/activity_welcome.xml",
    "chars": 434,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    android:id=\"@+id/activity_welcome\"\n    xmlns:android=\"http://"
  },
  {
    "path": "app/src/main/res/layout/def_section_head.xml",
    "chars": 1612,
    "preview": "<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:card_view=\"http:"
  },
  {
    "path": "app/src/main/res/layout/empty_view.xml",
    "chars": 543,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    styl"
  },
  {
    "path": "app/src/main/res/layout/error_view.xml",
    "chars": 549,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    styl"
  },
  {
    "path": "app/src/main/res/layout/footer_view.xml",
    "chars": 769,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/head_view.xml",
    "chars": 866,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/home_item_view.xml",
    "chars": 1650,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/item_click_childview.xml",
    "chars": 2718,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  "
  },
  {
    "path": "app/src/main/res/layout/item_click_view.xml",
    "chars": 2144,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    android:id=\"@+id/card_view\"\n    xmlns:android=\"http://schemas"
  },
  {
    "path": "app/src/main/res/layout/item_draggable_view.xml",
    "chars": 1821,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/item_group_type.xml",
    "chars": 1206,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/item_header_and_footer.xml",
    "chars": 1092,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/"
  },
  {
    "path": "app/src/main/res/layout/item_image_view.xml",
    "chars": 847,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView\n    xmlns:android=\"http://schemas.android.com/"
  },
  {
    "path": "app/src/main/res/layout/item_img_text_view.xml",
    "chars": 1409,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/"
  },
  {
    "path": "app/src/main/res/layout/item_long_click_childview.xml",
    "chars": 2720,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<RelativeLayout\n    android:id=\"@+id/card_view\"\n    xmlns:android=\"http://schema"
  },
  {
    "path": "app/src/main/res/layout/item_long_click_view.xml",
    "chars": 2151,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n\n    android:id=\"@+id/card_view\"\n    xmlns:android=\"http://schema"
  },
  {
    "path": "app/src/main/res/layout/item_movie.xml",
    "chars": 4786,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tool"
  },
  {
    "path": "app/src/main/res/layout/item_node_level_1.xml",
    "chars": 1303,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/item_node_level_2.xml",
    "chars": 930,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/item_node_level_3.xml",
    "chars": 689,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "app/src/main/res/layout/item_section_content.xml",
    "chars": 1410,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/"
  },
  {
    "path": "app/src/main/res/layout/layout_animation.xml",
    "chars": 2876,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/"
  },
  {
    "path": "app/src/main/res/layout/layout_title_bar.xml",
    "chars": 1346,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    an"
  },
  {
    "path": "app/src/main/res/layout/layout_tool_bar.xml",
    "chars": 1851,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools"
  },
  {
    "path": "app/src/main/res/layout/loading_view.xml",
    "chars": 997,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    styl"
  },
  {
    "path": "app/src/main/res/layout/node_footer.xml",
    "chars": 523,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/toolbar_layout.xml",
    "chars": 594,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.appcompat.widget.Toolbar xmlns:android=\"http://schemas.android.com/apk/"
  },
  {
    "path": "app/src/main/res/layout/top_view.xml",
    "chars": 568,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n         "
  },
  {
    "path": "app/src/main/res/layout/view_load_more.xml",
    "chars": 2645,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    a"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "chars": 666,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#333244</color>\n    <color name=\"color"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "chars": 287,
    "preview": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"def_height\">80dp</d"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 369,
    "preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"network_e"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "chars": 1992,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">"
  },
  {
    "path": "app/src/main/res/values-v21/styles.xml",
    "chars": 575,
    "preview": "<resources>\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <!-- Customize your theme her"
  },
  {
    "path": "app/src/main/res/values-zh/strings.xml",
    "chars": 266,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"see_more\">查看更多 ...</string>\n    <string name=\"netwo"
  },
  {
    "path": "build.gradle",
    "chars": 339,
    "preview": "\nplugins {\n    id 'com.android.application' version '8.12.2' apply false\n    id 'com.android.library' version '8.12.2' a"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 233,
    "preview": "#Mon May 29 14:19:55 CST 2023\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://"
  },
  {
    "path": "gradle.properties",
    "chars": 937,
    "preview": "## For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/buil"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "library/.gitignore",
    "chars": 106,
    "preview": ".gradle/\n.DS_Store\nlocal.properties\n\n# build files\nbuild/\nbin/\ngen/\noutput/\n\n# android studio\n*.iml\n.idea\n"
  },
  {
    "path": "library/build.gradle.kts",
    "chars": 4645,
    "preview": "import java.io.FileInputStream\nimport java.io.InputStreamReader\nimport java.util.*\n\nplugins {\n    id(\"com.android.librar"
  },
  {
    "path": "library/proguard-rules.pro",
    "chars": 744,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "library/src/main/AndroidManifest.xml",
    "chars": 82,
    "preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n</manifest>\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseDifferAdapter.kt",
    "chars": 857,
    "preview": "package com.chad.library.adapter4\n\nimport androidx.recyclerview.widget.*\nimport androidx.recyclerview.widget.AsyncListDi"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseMultiItemAdapter.kt",
    "chars": 5870,
    "preview": "package com.chad.library.adapter4\n\nimport android.content.Context\nimport android.util.SparseArray\nimport android.view.Vi"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseNodeAdapter.kt",
    "chars": 11829,
    "preview": "package com.chad.library.adapter4\n\nimport androidx.recyclerview.widget.AsyncDifferConfig\nimport androidx.recyclerview.wi"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseQuickAdapter.kt",
    "chars": 32007,
    "preview": "package com.chad.library.adapter4\n\nimport android.animation.Animator\nimport android.content.Context\nimport android.util."
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseSingleItemAdapter.kt",
    "chars": 2684,
    "preview": "package com.chad.library.adapter4\n\nimport androidx.recyclerview.widget.RecyclerView\n\n/**\n * Adapter for single item\n * 只"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/QuickAdapterHelper.kt",
    "chars": 14117,
    "preview": "package com.chad.library.adapter4\n\nimport androidx.recyclerview.widget.ConcatAdapter\nimport androidx.recyclerview.widget"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/AlphaInAnimation.kt",
    "chars": 856,
    "preview": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator\ni"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/ItemAnimator.kt",
    "chars": 238,
    "preview": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.view.View\n\n/**\n * https://"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/ScaleInAnimation.kt",
    "chars": 1123,
    "preview": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.AnimatorSet\nimpo"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/SlideInBottomAnimation.kt",
    "chars": 798,
    "preview": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator\ni"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/SlideInLeftAnimation.kt",
    "chars": 795,
    "preview": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator\ni"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/SlideInRightAnimation.kt",
    "chars": 795,
    "preview": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator\ni"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/DragSwipeExt.kt",
    "chars": 3031,
    "preview": "package com.chad.library.adapter4.dragswipe\n\nimport android.graphics.Canvas\nimport androidx.recyclerview.widget.Recycler"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/QuickDragAndSwipe.kt",
    "chars": 8667,
    "preview": "package com.chad.library.adapter4.dragswipe\n\nimport android.graphics.Canvas\nimport androidx.recyclerview.widget.ItemTouc"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/listener/DragAndSwipeDataCallback.kt",
    "chars": 302,
    "preview": "package com.chad.library.adapter4.dragswipe.listener\n\n/**\n * 由外部实现的数据操作\n */\ninterface DragAndSwipeDataCallback {\n\n    /*"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/listener/OnItemDragListener.java",
    "chars": 549,
    "preview": "package com.chad.library.adapter4.dragswipe.listener;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nu"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/listener/OnItemSwipeListener.java",
    "chars": 1832,
    "preview": "package com.chad.library.adapter4.dragswipe.listener;\n\nimport android.graphics.Canvas;\n\nimport androidx.annotation.NonNu"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/fullspan/FullSpanAdapterType.kt",
    "chars": 446,
    "preview": "package com.chad.library.adapter4.fullspan\n\nimport androidx.recyclerview.widget.GridLayoutManager\n\n/**\n * If Adapter nee"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/layoutmanager/QuickGridLayoutManager.kt",
    "chars": 3711,
    "preview": "package com.chad.library.adapter4.layoutmanager\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport "
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/LoadState.kt",
    "chars": 2904,
    "preview": "package com.chad.library.adapter4.loadState\n\n/**\n * Load state\n *\n * 加载状态\n *\n * @property endOfPaginationReached 是否已到达分页"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/LoadStateAdapter.kt",
    "chars": 4497,
    "preview": "package com.chad.library.adapter4.loadState\n\nimport android.view.ViewGroup\nimport androidx.annotation.CallSuper\nimport a"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/leading/DefaultLeadingLoadStateAdapter.kt",
    "chars": 1414,
    "preview": "package com.chad.library.adapter4.loadState.leading\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport "
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/leading/LeadingLoadStateAdapter.kt",
    "chars": 2824,
    "preview": "package com.chad.library.adapter4.loadState.leading\n\nimport androidx.annotation.CallSuper\nimport androidx.recyclerview.w"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/trailing/DefaultTrailingLoadStateAdapter.kt",
    "chars": 3560,
    "preview": "package com.chad.library.adapter4.loadState.trailing\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/trailing/TrailingLoadStateAdapter.kt",
    "chars": 6109,
    "preview": "package com.chad.library.adapter4.loadState.trailing\n\nimport androidx.annotation.CallSuper\nimport androidx.recyclerview."
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/util/AdapterUtils.kt",
    "chars": 954,
    "preview": "package com.chad.library.adapter4.util\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view."
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/util/ItemClickUtils.kt",
    "chars": 2328,
    "preview": "package com.chad.library.adapter4.util\n\nimport android.view.View\nimport androidx.annotation.IdRes\nimport androidx.recycl"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/viewholder/DataBindingHolder.java",
    "chars": 1276,
    "preview": "package com.chad.library.adapter4.viewholder;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport andr"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/viewholder/QuickViewHolder.kt",
    "chars": 3453,
    "preview": "package com.chad.library.adapter4.viewholder\n\nimport android.graphics.Bitmap\nimport android.graphics.drawable.Drawable\ni"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/viewholder/StateLayoutVH.kt",
    "chars": 2339,
    "preview": "package com.chad.library.adapter4.viewholder\n\nimport android.view.Gravity\nimport android.view.View\nimport android.view.V"
  },
  {
    "path": "library/src/main/res/layout/brvah_leading_load_more.xml",
    "chars": 448,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    a"
  },
  {
    "path": "library/src/main/res/layout/brvah_trailing_load_more.xml",
    "chars": 2469,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    a"
  },
  {
    "path": "library/src/main/res/values/ids.xml",
    "chars": 434,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <item name=\"BaseQuickAdapter_viewholder_support\" type=\"id\"/>\n    "
  },
  {
    "path": "library/src/main/res/values/strings.xml",
    "chars": 235,
    "preview": "<resources>\n    <string name=\"brvah_loading\">加载中...</string>\n    <string name=\"brvah_load_failed\">加载失败,点击重试</string>\n   "
  },
  {
    "path": "library/src/main/res/values-en/strings.xml",
    "chars": 272,
    "preview": "<resources>\n    <string name=\"brvah_loading\">Loading...</string>\n    <string name=\"brvah_load_failed\">Load failed, click"
  },
  {
    "path": "library/src/main/res/values-zh-rHK/strings.xml",
    "chars": 273,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"brvah_loading\">加載中...</string>\n    <string name=\"br"
  },
  {
    "path": "library/src/main/res/values-zh-rTW/strings.xml",
    "chars": 273,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"brvah_loading\">加載中...</string>\n    <string name=\"br"
  },
  {
    "path": "settings.gradle",
    "chars": 309,
    "preview": "pluginManagement {\n    repositories {\n        gradlePluginPortal()\n        google()\n        mavenCentral()\n    }\n}\n\ndepe"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the CymChad/BaseRecyclerViewAdapterHelper GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 177 files (379.3 KB), approximately 95.2k tokens, and a symbol index with 119 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!