[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2\njobs:\n  build:\n    working_directory: ~/code\n    docker:\n      - image: cimg/android:2023.04\n    environment:\n      JVM_OPTS: -Xmx3200m\n    steps:\n      - checkout\n      - restore_cache:\n          key: jars-{{ checksum \"build.gradle\" }}-{{ checksum  \"app/build.gradle\" }}\n      - run:\n          name: Download Dependencies\n          command: ./gradlew androidDependencies\n      - save_cache:\n          paths:\n            - ~/.gradle\n          key: jars-{{ checksum \"build.gradle\" }}-{{ checksum  \"app/build.gradle\" }}\n      - run:\n          name: Run Tests\n          command: ./gradlew lint test\n      - store_artifacts:\n          path: app/build/reports\n          destination: reports\n      - store_test_results:\n          path: app/build/test-results\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Additional context**\nAdd any other context about the problem here.\n\n1. 尝试在[历史问题](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues?q=is%3Aissue+is%3Aclosed)搜索答案。\n2. 尝试阅读[文档](http://www.jianshu.com/p/b343fcff51b0)找到答案。\n3. 尝试阅读[Demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)找到答案。\n4. 尝试自己检查或试验以找到答案。\n5. 尝试阅读源代码以找到答案。\n6. 请勿将产品的一些特殊交互需求 和 该库暂不支持作为bug混为一谈，请您仔细甄别\n\n如果以上都尝试过了请提一个新的[issues](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues/new)   \n参考[提問的智慧](https://github.com/FredWe/How-To-Ask-Questions-The-Smart-Way)\n\n如果还是没有找到答案，提问请带上这几个必要信息\n1. 当前使用的版本号\n2. 复现操作描述\n3. 使用代码\n3. crash日志\n4. gif复现效果\n5. 抽取demo\n       **将你出现的问题代码抽出来成一个可直接运行的项目。（最好fork[本库](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)修改）**\n       **在本地修改demo，然后把commit push到github上，在issue里贴下demo的地址。**\n\n**有详细的描述才能使得我们更快速的定位问题并解决问题，感谢配合！**\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "Thank you for contributing to BaseRecyclerViewAdapterHelper. Before pressing the \"Create Pull Request\" button, please consider the following points:\n\n  - [1] Please give a description about what and why you are contributing, even if it's trivial.\n\n  - [2] Please include the issue list number(s) or other PR numbers in the description if you are contributing in response to those.\n\n  - [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.\n"
  },
  {
    "path": ".gitignore",
    "content": "#/////////////////////////////////////////////////////////////////////////////\n# OS generated files\n#/////////////////////////////////////////////////////////////////////////////\n\n.DS_Store\nehthumbs.db\nThumbs.db\n\n# Built application files\n*.apk\n*.ap_\n\n# Files for the Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n\n# Android Studio project files\n*.iml\n.gradle\n.idea\nbuild\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: android\ndist: trusty\njdk: oraclejdk11\nsudo: false\n\nandroid:\ncomponents:\n    - tools\n    - platform-tools\n    - build-tools-33.0.0\n    - android-32\n    - extra-android-m2repository\nbefore_install:\n  - chmod +x gradlew\n  - mkdir \"$ANDROID_HOME/licenses\" || true\n  # Hack to accept Android licenses\n  - yes | sdkmanager \"platforms;android-32\"\n\nscript:\n  - ./gradlew assembleRelease\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2023 陈宇明\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "![](https://user-images.githubusercontent.com/7698209/33198075-ef8f2230-d123-11e7-85a3-4cb9b22f877d.png)\n[![](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)  \n# BRVAH\n\nPowerful and flexible RecyclerView Adapter,\nPlease feel free to use this. (Welcome to **Star** and **Fork**)  \n\n强大而灵活的RecyclerView Adapter（欢迎 **Star** 和 **Fork**）\n\n​    \n新版4.x.x已发布，完美兼容`ConcatAdapter`，解决了许多遗留问题，拆分了功能模块，BaseAdapter更加简洁干净。“多类型布局”更加灵活。向上、向下加载得到极大加强。\nv4版本已经上传 maven 中央仓库，不需要再引入三方仓库配置了。欢迎尝试。\n\n\n\nOf course, you can continue to use the [2.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/2.x) version.\n\n当然，你也可以继续使用[2.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/2.x) 版本、[3.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/3.x/readme/0-BaseRecyclerViewAdapterHelper.md)版本。\n\n# Document\n- English Writing ...\n- [3.0版本 中文](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/3.x/readme/0-BaseRecyclerViewAdapterHelper.md)\n- [4.0版本 中文](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki)\n\n\n(由于各位项目成员工作较为繁忙，请各位同学谅解)\n\n## v4 版本\n[wiki](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki)\n```\nimplementation(\"io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.3.4\")\n```\n\n## [demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/master/demo)\n\n# proguard-rules.pro\n> 此资源库自带混淆规则，并且会自动导入，正常情况下无需手动导入。\n\n> The library comes with `proguard-rules.pro` rules and is automatically imported. Normally no manual import is required.\n> You can also go here to view [proguard-rules](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/library/proguard-rules.pro)\n\n\n\n\n# Thanks  \n[JoanZapata / base-adapter-helper](https://github.com/JoanZapata/base-adapter-helper)\n\n# [License](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/LICENSE)\n"
  },
  {
    "path": "app/.gitignore",
    "content": ".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",
    "content": "plugins {\n    id 'com.android.application'\n    id 'kotlin-android'\n    id 'kotlin-kapt'\n    id 'com.google.devtools.ksp'\n}\n\nandroid {\n    compileSdk 36\n\n    defaultConfig {\n        applicationId \"com.chad.baserecyclerviewadapterhelper\"\n        minSdk 23\n        targetSdk 36\n        versionCode 21\n        versionName \"4.3.2\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled true\n            zipAlignEnabled true\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n        debug {\n            minifyEnabled false\n            zipAlignEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_17\n        targetCompatibility JavaVersion.VERSION_17\n    }\n    kotlinOptions {\n        jvmTarget = \"17\"\n    }\n\n    buildFeatures {\n        viewBinding = true\n        dataBinding = true\n    }\n    namespace 'com.chad.baserecyclerviewadapterhelper'\n}\n\ndependencies {\n    implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')\n    implementation project(path: ':library')\n    implementation 'com.google.android.material:material:1.13.0'\n    implementation 'androidx.cardview:cardview:1.0.0'\n    implementation 'androidx.appcompat:appcompat:1.7.1'\n    implementation \"androidx.core:core-ktx:1.17.0\"\n\n    implementation 'com.kyleduo.switchbutton:library:2.1.0'\n    implementation 'androidx.recyclerview:recyclerview:1.4.0'\n    implementation \"androidx.swiperefreshlayout:swiperefreshlayout:1.1.0\"\n\n    implementation(\"com.squareup.moshi:moshi:1.15.2\")\n    ksp(\"com.squareup.moshi:moshi-kotlin-codegen:1.15.2\")\n\n    implementation 'com.jaredrummler:material-spinner:1.3.1'\n}\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/huasheng/Desktop/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n#BaseRecyclerViewAdapterHelper\n"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.VIBRATE\" />\n\n    <application\n        android:name=\".MyApplication\"\n        android:icon=\"@mipmap/logo\"\n        android:label=\"BRVAH\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n\n        <activity\n            android:name=\".activity.WelcomeActivity\"\n            android:exported=\"true\"\n            android:theme=\"@style/WelcomeTheme\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n\n        <activity\n            android:name=\".activity.home.HomeActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.animation.AnimationUseActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.headerfooter.HeaderAndFooterUseActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.loadmore.AutoLoadMoreRefreshUseActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.emptyview.EmptyViewUseActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.itemclick.ItemClickActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.databinding.DataBindingUseActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.dragswipe.ManualDragAndSwipeUseActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.upfetch.UpFetchUseActivity\"\n            android:exported=\"false\" /> <!-- <activity android:name=\".activity.node.NodeSectionUseActivity\" /> -->\n        <activity\n            android:name=\".activity.differ.DifferActivity\"\n            android:exported=\"false\" /> <!-- <activity android:name=\".activity.node.ChooseNodeUseTypeActivity\" /> -->\n        <activity\n            android:name=\".activity.loadmore.NoAutoAutoLoadMoreRefreshUseActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.dragswipe.DragAndSwipeDifferActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.dragswipe.HeaderDragAndSwipeActivity\"\n            android:exported=\"false\" />\n\n        <activity\n            android:name=\".activity.dragswipe.DragAndSwipeUseActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\".activity.dragswipe.DefaultDragAndSwipeActivity\"\n            android:exported=\"false\" />\n        <activity android:name=\".activity.scene.GroupDemoActivity\" />\n        <activity android:name=\"com.chad.baserecyclerviewadapterhelper.activity.node.NodeActivity\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.kt",
    "content": "/*\n******************************* Copyright (c)*********************************\\\n**\n**                 (c) Copyright 2015, Allen, china, shanghai\n**                          All Rights Reserved\n**\n**                          \n**                         \n**-----------------------------------版本信息------------------------------------\n** 版    本: V0.1\n**\n**------------------------------------------------------------------------------\n********************************End of Head************************************\\\n*/\npackage com.chad.baserecyclerviewadapterhelper\n\nimport android.app.Application\nimport com.chad.baserecyclerviewadapterhelper.utils.AppUtils\n\n/**\n * 文 件 名: MyApplication\n * 创 建 人: Allen\n * 创建日期: 16/12/24 15:33\n * 邮   箱: AllenCoder@126.com\n * 修改时间：\n * 修改备注：\n */\nclass MyApplication : Application() {\n    override fun onCreate() {\n        super.onCreate()\n        AppUtils.init(this)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/WelcomeActivity.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.os.Handler;\n\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport com.chad.baserecyclerviewadapterhelper.R;\nimport com.chad.baserecyclerviewadapterhelper.activity.home.HomeActivity;\n\npublic class WelcomeActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_welcome);\n        new Handler().postDelayed(new Runnable() {\n            @Override\n            public void run() {\n                Intent intent = new Intent(WelcomeActivity.this, HomeActivity.class);\n                startActivity(intent);\n                finish();\n            }\n        }, 1000);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/AnimationUseActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.animation\n\nimport android.os.Bundle\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport com.chad.baserecyclerviewadapterhelper.activity.animation.adapter.AnimationAdapter\nimport com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation1\nimport com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation2\nimport com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation3\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityAnimationUseBinding\nimport com.chad.library.adapter4.BaseQuickAdapter\n\n/**\n * https://github.com/CymChad/BaseRecyclerViewAdapterHelper\n *\n *\n * modify by AllenCoder\n */\nclass AnimationUseActivity : BaseViewBindingActivity<ActivityAnimationUseBinding>() {\n\n    private val mAnimationAdapter: AnimationAdapter = AnimationAdapter().apply {\n        // 打开 Adapter 的动画\n        animationEnable = true\n        // 是否是首次显示时候加载动画\n        isAnimationFirstOnly = false\n    }\n\n    override fun initBinding(): ActivityAnimationUseBinding {\n        return ActivityAnimationUseBinding.inflate(layoutInflater)\n    }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"Animation Use\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n        viewBinding.rv.adapter = mAnimationAdapter\n\n        initMenu()\n    }\n\n    /**\n     * Init menu\n     * 初始化下拉菜单\n     */\n    private fun initMenu() {\n        viewBinding.spinner.setItems(\n            \"AlphaIn\",\n            \"ScaleIn\",\n            \"SlideInBottom\",\n            \"SlideInLeft\",\n            \"SlideInRight\",\n            \"Custom1\",\n            \"Custom2\",\n            \"Custom3\"\n        )\n        viewBinding.spinner.setOnItemSelectedListener { _, position, _, _ ->\n            when (position) {\n                0 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.AlphaIn)\n                1 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.ScaleIn)\n                2 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInBottom)\n                3 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInLeft)\n                4 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInRight)\n                5 -> mAnimationAdapter.itemAnimation = CustomAnimation1()\n                6 -> mAnimationAdapter.itemAnimation = CustomAnimation2()\n                7 -> mAnimationAdapter.itemAnimation = CustomAnimation3()\n                else -> {}\n            }\n            mAnimationAdapter.notifyDataSetChanged()\n\n        }\n\n        //init firstOnly state\n        viewBinding.switchButton.setOnCheckedChangeListener { _, isChecked ->\n            mAnimationAdapter.isAnimationFirstOnly = isChecked\n            mAnimationAdapter.notifyDataSetChanged()\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/adapter/AnimationAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.animation.adapter\n\nimport android.content.Context\nimport android.text.TextPaint\nimport android.text.style.ClickableSpan\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.TextView\nimport androidx.core.content.ContextCompat\nimport androidx.core.text.buildSpannedString\nimport androidx.core.text.inSpans\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.data.DataServer\nimport com.chad.baserecyclerviewadapterhelper.entity.Status\nimport com.chad.baserecyclerviewadapterhelper.utils.ClickableMovementMethod\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips\nimport com.chad.library.adapter4.BaseQuickAdapter\nimport com.chad.library.adapter4.viewholder.QuickViewHolder\n\n/**\n * 文 件 名: AnimationAdapter\n * 创 建 人: Allen\n * 创建日期: 16/12/24 15:33\n * 邮   箱: AllenCoder@126.com\n * 修改时间：\n * 修改备注：\n */\nclass AnimationAdapter :\n    BaseQuickAdapter<Status, QuickViewHolder>(DataServer.getSampleData(100)) {\n    override fun onCreateViewHolder(\n        context: Context,\n        parent: ViewGroup,\n        viewType: Int\n    ): QuickViewHolder {\n        return QuickViewHolder(R.layout.layout_animation, parent)\n    }\n\n    override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: Status?) {\n        when (holder.layoutPosition % 3) {\n            0 -> holder.setImageResource(R.id.img, R.mipmap.animation_img1)\n            1 -> holder.setImageResource(R.id.img, R.mipmap.animation_img2)\n            2 -> holder.setImageResource(R.id.img, R.mipmap.animation_img3)\n            else -> {}\n        }\n        holder.setText(R.id.tweetName, \"Hoteis in Rio de Janeiro\")\n        val msg =\n            \"\\\"He was one of Australia's most of distinguished artistes, renowned for his portraits\\\"\"\n\n\n\n        holder.getView<TextView>(R.id.tweetText).text = buildSpannedString {\n            append(msg)\n            inSpans(clickableSpan) {\n                append(\"landscapes and nedes\")\n            }\n        }\n        holder.getView<TextView>(R.id.tweetText).movementMethod = ClickableMovementMethod.getInstance()\n        holder.getView<TextView>(R.id.tweetText).isFocusable = false\n        holder.getView<TextView>(R.id.tweetText).isClickable = false\n        holder.getView<TextView>(R.id.tweetText).isLongClickable = false\n    }\n\n    private val clickableSpan: ClickableSpan = object : ClickableSpan() {\n        override fun onClick(widget: View) {\n            Tips.show(\"事件触发了 landscapes and nedes\")\n        }\n\n        override fun updateDrawState(ds: TextPaint) {\n            ds.color = ContextCompat.getColor(context, R.color.clickspan_color)\n            ds.isUnderlineText = true\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/DataBindingUseActivity.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.databinding;\n\nimport android.os.Bundle;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\nimport androidx.core.graphics.Insets;\nimport androidx.core.view.OnApplyWindowInsetsListener;\nimport androidx.core.view.ViewCompat;\nimport androidx.core.view.WindowInsetsCompat;\nimport androidx.recyclerview.widget.LinearLayoutManager;\n\nimport com.chad.baserecyclerviewadapterhelper.activity.databinding.adapter.DataBindingAdapter;\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity;\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding;\nimport com.chad.baserecyclerviewadapterhelper.entity.Movie;\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Random;\n\n/**\n * @author  limuyang\n * @date  2019-12-05\n * @description\n */\npublic final class DataBindingUseActivity extends BaseViewBindingActivity<ActivityUniversalRecyclerBinding> {\n\n    private final DataBindingAdapter adapter = new DataBindingAdapter();\n\n    @NonNull\n    @Override\n    public ActivityUniversalRecyclerBinding initBinding() {\n        return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater());\n    }\n\n    @Override\n    public void onPointerCaptureChanged(boolean hasCapture) {\n        super.onPointerCaptureChanged(hasCapture);\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n\n        ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() {\n            @Override\n            public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {\n                Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars());\n                getViewBinding().titleBar.updateFakeBarHeight(bar.top);\n                return insets;\n            }\n        });\n\n        getViewBinding().titleBar.setTitle(\"DataBinding Use\");\n        getViewBinding().titleBar.setOnBackListener(v -> finish());\n\n\n        getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this));\n        getViewBinding().rv.setAdapter(adapter);\n\n\n        //item 点击事件\n        adapter.setOnItemClickListener((movieBaseQuickAdapter, view, position) -> {\n            Tips.show(\"onItemClick: \" + position);\n        });\n\n        //设置数据\n        adapter.submitList(genData());\n    }\n\n    private List<Movie> genData() {\n        ArrayList<Movie> list = new ArrayList<>();\n        Random random = new Random();\n        for (int i = 0; i < 10; i++) {\n            String name = \"Chad \" + i;\n            int price = random.nextInt(10) + 10;\n            int len = random.nextInt(80) + 60;\n            Movie movie = new Movie(name, len, price, \"He was one of Australia's most distinguished artistes\");\n            list.add(movie);\n        }\n        return list;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/adapter/DataBindingAdapter.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.databinding.adapter;\n\nimport android.content.Context;\nimport android.view.ViewGroup;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.chad.baserecyclerviewadapterhelper.R;\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemMovieBinding;\nimport com.chad.baserecyclerviewadapterhelper.entity.Movie;\nimport com.chad.baserecyclerviewadapterhelper.entity.MoviePresenter;\nimport com.chad.library.adapter4.BaseQuickAdapter;\nimport com.chad.library.adapter4.viewholder.DataBindingHolder;\n\n/**\n * @author: limuyang\n * @date: 2019-12-05\n * @Description: DataBinding Adapter\n *\n */\npublic class DataBindingAdapter extends BaseQuickAdapter<Movie, DataBindingHolder<ItemMovieBinding>> {\n\n    private final MoviePresenter mPresenter = new MoviePresenter();\n\n    @NonNull\n    @Override\n    protected DataBindingHolder<ItemMovieBinding> onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {\n        return new DataBindingHolder<>(R.layout.item_movie, parent);\n    }\n\n    @Override\n    protected void onBindViewHolder(@NonNull DataBindingHolder<ItemMovieBinding> holder, int position, @Nullable Movie item) {\n        if (item == null) return;\n\n        // 获取 Binding\n        ItemMovieBinding binding = holder.getBinding();\n        binding.setMovie(item);\n        binding.setPresenter(mPresenter);\n        binding.executePendingBindings();\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/DifferActivity.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.differ;\n\nimport android.os.Bundle;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\nimport androidx.core.graphics.Insets;\nimport androidx.core.view.OnApplyWindowInsetsListener;\nimport androidx.core.view.ViewCompat;\nimport androidx.core.view.WindowInsetsCompat;\n\nimport com.chad.baserecyclerviewadapterhelper.R;\nimport com.chad.baserecyclerviewadapterhelper.activity.differ.adapter.DiffUtilAdapter;\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity;\nimport com.chad.baserecyclerviewadapterhelper.data.DataServer;\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityDiffutilBinding;\nimport com.chad.baserecyclerviewadapterhelper.entity.DiffEntity;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Created by limuyang\n * Date: 2019/7/14O\n */\npublic final class DifferActivity extends BaseViewBindingActivity<ActivityDiffutilBinding> {\n\n    private final DiffUtilAdapter mAdapter = new DiffUtilAdapter();\n\n    @NonNull\n    @Override\n    public ActivityDiffutilBinding initBinding() {\n        return ActivityDiffutilBinding.inflate(getLayoutInflater());\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() {\n            @Override\n            public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {\n                Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars());\n                getViewBinding().titleBar.updateFakeBarHeight(bar.top);\n                return insets;\n            }\n        });\n\n        getViewBinding().titleBar.setTitle(\"DiffUtil Use\");\n        getViewBinding().titleBar.setOnBackListener(v -> finish());\n\n        initRv();\n        initClick();\n    }\n\n    @Override\n    protected void onStart() {\n        super.onStart();\n\n        // 增加延迟，模拟网络加载\n        getViewBinding().diffRv.postDelayed(() -> mAdapter.submitList(DataServer.getDiffUtilDemoEntities()), 1500);\n    }\n\n\n    private void initRv() {\n        // 打开空布局功能\n        mAdapter.setStateViewEnable(true);\n        // 传入 空布局 layout id\n        mAdapter.setStateViewLayout(this, R.layout.loading_view);\n\n        getViewBinding().diffRv.setAdapter(mAdapter);\n    }\n\n    private int idAdd = 0;\n\n    private void initClick() {\n        getViewBinding().btnChange.setOnClickListener(v -> {\n            List<DiffEntity> newData = getNewList();\n            mAdapter.submitList(newData);\n        });\n\n        getViewBinding().btnAdd.setOnClickListener(v -> {\n            mAdapter.add(2, new DiffEntity(\n                    1000 + idAdd,\n                    \"add - 😊😊Item \" + 1000 + idAdd,\n                    \"Item \" + 0 + \" content have change (notifyItemChanged)\",\n                    \"06-12\"));\n            idAdd++;\n        });\n\n        getViewBinding().btnRemove.setOnClickListener(v -> {\n            if (2 >= mAdapter.getItems().size()) {\n                return;\n            }\n            mAdapter.removeAt(2);\n        });\n    }\n\n\n    /**\n     * get new data\n     */\n    private List<DiffEntity> getNewList() {\n        List<DiffEntity> list = new ArrayList<>();\n        for (int i = 0; i < 10; i++) {\n            /*\n            Simulate deletion of data No. 1 and No. 3\n            模拟删除1号和3号数据\n             */\n            if (i == 1 || i == 3) {\n                continue;\n            }\n\n            /*\n            Simulate modification title of data No. 0\n            模拟修改0号数据的title\n             */\n            if (i == 0) {\n                list.add(new DiffEntity(\n                        i,\n                        \"😊Item \" + i,\n                        \"This item \" + i + \" content\",\n                        \"06-12\")\n                );\n                continue;\n            }\n\n            /*\n            Simulate modification content of data No. 4\n            模拟修改4号数据的content发生变化\n             */\n            if (i == 4) {\n                list.add(new DiffEntity(\n                        i,\n                        \"Item \" + i,\n                        \"Oh~~~~~~, Item \" + i + \" content have change\",\n                        \"06-12\")\n                );\n                continue;\n            }\n\n            list.add(new DiffEntity(\n                    i,\n                    \"Item \" + i,\n                    \"This item \" + i + \" content\",\n                    \"06-12\")\n            );\n        }\n        return list;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffEntityCallback.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter;\n\nimport androidx.annotation.NonNull;\nimport androidx.recyclerview.widget.DiffUtil;\n\nimport com.chad.baserecyclerviewadapterhelper.entity.DiffEntity;\n\n/**\n * Create DiffCallback\n */\npublic class DiffEntityCallback extends DiffUtil.ItemCallback<DiffEntity> {\n\n    /**\n     * Determine if it is the same item\n     * <p>\n     * 判断是否是同一个item\n     *\n     * @param oldItem New data\n     * @param newItem old Data\n     * @return\n     */\n    @Override\n    public boolean areItemsTheSame(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) {\n        return oldItem.getId() == newItem.getId();\n    }\n\n    /**\n     * When it is the same item, judge whether the content has changed.\n     * <p>\n     * 当是同一个item时，再判断内容是否发生改变\n     *\n     * @param oldItem New data\n     * @param newItem old Data\n     * @return\n     */\n    @Override\n    public boolean areContentsTheSame(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) {\n        return oldItem.getTitle().equals(newItem.getTitle())\n                && oldItem.getContent().equals(newItem.getContent())\n                && oldItem.getDate().equals(newItem.getDate());\n    }\n\n    /**\n     * Optional implementation\n     * Implement this method if you need to precisely modify the content of a view.\n     * If this method is not implemented, or if null is returned, the entire item will be refreshed.\n     *\n     * 可选实现\n     * 如果需要精确修改某一个view中的内容，请实现此方法。\n     * 如果不实现此方法，或者返回null，将会直接刷新整个item。\n     *\n     * @param oldItem Old data\n     * @param newItem New data\n     * @return Payload info. if return null, the entire item will be refreshed.\n     */\n    @Override\n    public Object getChangePayload(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) {\n        return null;\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffUtilAdapter.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter;\n\nimport android.content.Context;\nimport android.view.ViewGroup;\n\nimport androidx.annotation.NonNull;\n\nimport com.chad.baserecyclerviewadapterhelper.R;\nimport com.chad.baserecyclerviewadapterhelper.entity.DiffEntity;\nimport com.chad.library.adapter4.BaseQuickAdapter;\nimport com.chad.library.adapter4.viewholder.QuickViewHolder;\n\n/**\n * Create adapter\n */\npublic class DiffUtilAdapter extends BaseQuickAdapter<DiffEntity, QuickViewHolder> {\n\n    public DiffUtilAdapter() {\n        super(new DiffEntityCallback());\n    }\n\n\n    @NonNull\n    @Override\n    protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {\n        return new QuickViewHolder(R.layout.layout_animation, parent);\n    }\n\n    @Override\n    protected void onBindViewHolder(@NonNull QuickViewHolder holder, int position, DiffEntity item) {\n        holder.setText(R.id.tweetName, item.getTitle())\n                .setText(R.id.tweetText, item.getContent())\n                .setText(R.id.tweetDate, item.getDate());\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DefaultDragAndSwipeActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe\n\nimport android.animation.ValueAnimator\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport android.os.Build\nimport android.os.Bundle\nimport android.util.Log\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.DragAndSwipeAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips\nimport com.chad.baserecyclerviewadapterhelper.utils.vibrate\nimport com.chad.library.adapter4.dragswipe.QuickDragAndSwipe\nimport com.chad.library.adapter4.dragswipe.listener.OnItemDragListener\nimport com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener\nimport com.chad.library.adapter4.viewholder.QuickViewHolder\n\n/**\n * 默认实现拖动与侧滑效果\n * Drag and Drag effects are implemented by default\n */\nclass DefaultDragAndSwipeActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {\n\n    private val mAdapter: DragAndSwipeAdapter = DragAndSwipeAdapter()\n\n    private val quickDragAndSwipe = QuickDragAndSwipe()\n        .setDragMoveFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN or\n                ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)\n        .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)\n\n    override fun initBinding(): ActivityUniversalRecyclerBinding =\n        ActivityUniversalRecyclerBinding.inflate(layoutInflater)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"Default Drag And Swipe\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n        viewBinding.rv.layoutManager = GridLayoutManager(this,3)\n        viewBinding.rv.adapter = mAdapter\n\n        val mData = generateData(50)\n        mAdapter.submitList(mData)\n\n        // 拖拽监听\n        val listener: OnItemDragListener = object : OnItemDragListener {\n            override fun onItemDragStart(viewHolder: RecyclerView.ViewHolder?, pos: Int) {\n                vibrate()\n                Log.d(TAG, \"drag start\")\n                val holder = viewHolder as QuickViewHolder? ?: return\n                // 开始时，item背景色变化，demo这里使用了一个动画渐变，使得自然\n                val startColor = Color.WHITE\n                val endColor = Color.rgb(245, 245, 245)\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n                    val v = ValueAnimator.ofArgb(startColor, endColor)\n                    v.addUpdateListener { animation: ValueAnimator ->\n                        holder.itemView.setBackgroundColor(\n                            animation.animatedValue as Int\n                        )\n                    }\n                    v.duration = 300\n                    v.start()\n                }\n            }\n\n            override fun onItemDragMoving(\n                source: RecyclerView.ViewHolder,\n                from: Int,\n                target: RecyclerView.ViewHolder,\n                to: Int\n            ) {\n                Log.d(\n                    TAG,\n                    \"move from: \" + source.bindingAdapterPosition + \" to: \" + target.bindingAdapterPosition\n                )\n            }\n\n            override fun onItemDragEnd(viewHolder: RecyclerView.ViewHolder, pos: Int) {\n                Log.d(TAG, \"drag end\")\n                val holder = viewHolder as QuickViewHolder\n                // 结束时，item背景色变化，demo这里使用了一个动画渐变，使得自然\n                val startColor = Color.rgb(245, 245, 245)\n                val endColor = Color.WHITE\n                // 动画\n                val v = ValueAnimator.ofArgb(startColor, endColor)\n                v.addUpdateListener { animation: ValueAnimator ->\n                    holder.itemView.setBackgroundColor(\n                        animation.animatedValue as Int\n                    )\n                }\n                v.duration = 300\n                v.start()\n\n                mAdapter.items.forEach {\n                    Log.d(\n                        TAG,\n                        \"-------->> w 顺序 ${it} \"\n                    )\n                }\n\n            }\n        }\n        val swipeListener: OnItemSwipeListener = object : OnItemSwipeListener {\n            override fun onItemSwipeStart(viewHolder: RecyclerView.ViewHolder?, bindingAdapterPosition: Int) {\n                Log.d(TAG, \"onItemSwipeStart\")\n            }\n\n            override fun onItemSwipeEnd(viewHolder: RecyclerView.ViewHolder, bindingAdapterPosition: Int) {\n                Log.d(TAG, \"onItemSwipeEnd: \" + bindingAdapterPosition)\n            }\n\n            override fun onItemSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int, bindingAdapterPosition: Int) {\n                Log.d(TAG, \"onItemSwiped\")\n            }\n\n            override fun onItemSwipeMoving(\n                canvas: Canvas,\n                viewHolder: RecyclerView.ViewHolder,\n                dX: Float,\n                dY: Float,\n                isCurrentlyActive: Boolean\n            ) {\n                Log.d(TAG, \"onItemSwipeMoving\")\n            }\n        }\n\n        // 滑动事件\n        quickDragAndSwipe.attachToRecyclerView(viewBinding.rv)\n            .setDataCallback(mAdapter)\n            .setItemDragListener(listener)\n            .setItemSwipeListener(swipeListener)\n\n        // 点击事件\n        mAdapter.setOnItemClickListener { adapter, view, position ->\n            Tips.show(\"点击了：$position\")\n        }\n    }\n\n    private fun generateData(size: Int): List<String> {\n        val data = ArrayList<String>(size)\n        for (i in 0 until size) {\n            data.add(\"item $i\")\n        }\n        return data\n    }\n\n    companion object {\n        private const val TAG = \"Default Drag And Swipe\"\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeDifferActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe\n\nimport android.animation.ValueAnimator\nimport android.graphics.Canvas\nimport android.graphics.Color\nimport android.os.Build\nimport android.os.Bundle\nimport android.util.Log\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.DiffDragAndSwipeAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.data.DataServer\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding\nimport com.chad.baserecyclerviewadapterhelper.utils.vibrate\nimport com.chad.library.adapter4.dragswipe.QuickDragAndSwipe\nimport com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback\nimport com.chad.library.adapter4.dragswipe.listener.OnItemDragListener\nimport com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener\nimport com.chad.library.adapter4.viewholder.QuickViewHolder\n\n/**\n * Created by limuyang\n * Date: 2019/7/14O\n *\n * DiffAdapter DragAndSwipe\n */\nclass DragAndSwipeDifferActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {\n\n    private var mAdapter: DiffDragAndSwipeAdapter = DiffDragAndSwipeAdapter()\n\n    private var quickDragAndSwipe = QuickDragAndSwipe()\n        .setDragMoveFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN)\n        .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)\n\n    override fun initBinding(): ActivityUniversalRecyclerBinding =\n        ActivityUniversalRecyclerBinding.inflate(layoutInflater)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"Diff Drag Swipe Use\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n        viewBinding.rv.layoutManager = LinearLayoutManager(this)\n        initRv()\n\n        initDrag()\n    }\n\n    private fun initRv() {\n        viewBinding.rv.adapter = mAdapter\n\n        mAdapter.submitList(DataServer.diffUtilDemoEntities)\n    }\n\n\n    private fun initDrag() {\n        // 拖拽监听\n        val listener: OnItemDragListener = object :\n            OnItemDragListener {\n            override fun onItemDragStart(viewHolder: RecyclerView.ViewHolder?, pos: Int) {\n                vibrate()\n                Log.d(TAG, \"drag start\")\n                val holder = viewHolder as QuickViewHolder\n                // 开始时，item背景色变化，demo这里使用了一个动画渐变，使得自然\n                val startColor = Color.WHITE\n                val endColor = Color.rgb(245, 245, 245)\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n                    val v = ValueAnimator.ofArgb(startColor, endColor)\n                    v.addUpdateListener { animation: ValueAnimator ->\n                        holder.itemView.setBackgroundColor(\n                            animation.animatedValue as Int\n                        )\n                    }\n                    v.duration = 300\n                    v.start()\n                }\n            }\n\n            override fun onItemDragMoving(\n                source: RecyclerView.ViewHolder,\n                from: Int,\n                target: RecyclerView.ViewHolder,\n                to: Int\n            ) {\n                Log.d(\n                    TAG, \"move from: \" + source.bindingAdapterPosition + \" to: \" + target.bindingAdapterPosition\n                )\n            }\n\n            override fun onItemDragEnd(viewHolder: RecyclerView.ViewHolder, pos: Int) {\n                Log.d(TAG, \"drag end\")\n                val holder = viewHolder as QuickViewHolder\n                // 结束时，item背景色变化，demo这里使用了一个动画渐变，使得自然\n                val startColor = Color.rgb(245, 245, 245)\n                val endColor = Color.WHITE\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n                    val v = ValueAnimator.ofArgb(startColor, endColor)\n                    v.addUpdateListener { animation: ValueAnimator ->\n                        holder.itemView.setBackgroundColor(\n                            animation.animatedValue as Int\n                        )\n                    }\n                    v.duration = 300\n                    v.start()\n                }\n            }\n        }\n\n        val swipeListener: OnItemSwipeListener = object :\n            OnItemSwipeListener {\n            override fun onItemSwipeStart(viewHolder: RecyclerView.ViewHolder?, bindingAdapterPosition: Int) {\n                Log.d(TAG, \"onItemSwipeStart\")\n            }\n\n            override fun onItemSwipeEnd(viewHolder: RecyclerView.ViewHolder, bindingAdapterPosition: Int) {\n                Log.d(TAG, \"onItemSwipeEnd\")\n            }\n\n            override fun onItemSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int, bindingAdapterPosition: Int) {\n                Log.d(TAG, \"onItemSwiped\")\n            }\n\n            override fun onItemSwipeMoving(\n                canvas: Canvas,\n                viewHolder: RecyclerView.ViewHolder,\n                dX: Float,\n                dY: Float,\n                isCurrentlyActive: Boolean\n            ) {\n                Log.d(TAG, \"onItemSwipeMoving\")\n            }\n        }\n\n\n\n        quickDragAndSwipe.attachToRecyclerView(viewBinding.rv)\n            .setDataCallback(object : DragAndSwipeDataCallback {\n                override fun dataMove(fromPosition: Int, toPosition: Int) {\n                    mAdapter.swap(fromPosition, toPosition)\n                }\n\n                override fun dataRemoveAt(position: Int) {\n                    mAdapter.removeAt(position)\n                }\n            })\n            .setItemDragListener(listener)\n            .setItemSwipeListener(swipeListener)\n    }\n\n    companion object {\n        private const val TAG = \"Diff Drag Swipe Use\"\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeUseActivity.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe;\n\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\nimport androidx.core.graphics.Insets;\nimport androidx.core.view.OnApplyWindowInsetsListener;\nimport androidx.core.view.ViewCompat;\nimport androidx.core.view.WindowInsetsCompat;\nimport androidx.recyclerview.widget.LinearLayoutManager;\n\nimport com.chad.baserecyclerviewadapterhelper.R;\nimport com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeAdapter;\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity;\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding;\nimport com.chad.baserecyclerviewadapterhelper.entity.HomeEntity;\n\nimport java.util.ArrayList;\n\n\npublic class DragAndSwipeUseActivity extends BaseViewBindingActivity<ActivityUniversalRecyclerBinding> {\n    private final ArrayList<HomeEntity> homeItemData = new ArrayList<>();\n\n    @NonNull\n    @Override\n    public ActivityUniversalRecyclerBinding initBinding() {\n        return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater());\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() {\n            @Override\n            public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {\n                Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars());\n                getViewBinding().titleBar.updateFakeBarHeight(bar.top);\n                return insets;\n            }\n        });\n\n        getViewBinding().titleBar.setTitle(\"Drag And Swipe\");\n        getViewBinding().titleBar.setOnBackListener(v -> finish());\n\n        // 设置数据\n        homeItemData.add(new HomeEntity(\"Default Drag And Swipe\", DefaultDragAndSwipeActivity.class, R.mipmap.gv_drag_and_swipe, \"\"));\n        homeItemData.add(new HomeEntity(\"Manual Drag And Swipe\", ManualDragAndSwipeUseActivity.class, R.mipmap.gv_drag_and_swipe, \"\"));\n        homeItemData.add(new HomeEntity(\"Head Drag And Swipe\", HeaderDragAndSwipeActivity.class, R.mipmap.gv_drag_and_swipe, \"\"));\n        homeItemData.add(new HomeEntity(\"Diff Drag And Swipe\", DragAndSwipeDifferActivity.class, R.mipmap.gv_drag_and_swipe, \"\"));\n\n        /*\n         * RV适配器\n         */\n        HomeAdapter mAdapter = new HomeAdapter(homeItemData);\n\n\n        getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this));\n        getViewBinding().rv.setAdapter(mAdapter);\n\n        mAdapter.setOnItemClickListener((adapter, view, position) -> {\n            HomeEntity item = adapter.getItems().get(position);\n            if (!item.isSection()) {\n                startActivity(new Intent(DragAndSwipeUseActivity.this, item.getActivity()));\n            }\n        });\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipe.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe\n\nimport androidx.recyclerview.widget.ConcatAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.HeaderDragAndSwipeAdapter\nimport com.chad.library.adapter4.dragswipe.QuickDragAndSwipe\n\n/**\n * 重写拖拽类，根据itemType 设置某个类型的是否允许拖拽\n */\nclass HeaderDragAndSwipe : QuickDragAndSwipe() {\n\n    override fun getMovementFlags(\n        recyclerView: RecyclerView,\n        viewHolder: RecyclerView.ViewHolder\n    ): Int {\n        if (recyclerView.adapter is ConcatAdapter) {\n            val adapter = recyclerView.adapter as ConcatAdapter\n            val absoluteAdapter =\n                adapter.getWrappedAdapterAndPosition(viewHolder.absoluteAdapterPosition).first\n            if (absoluteAdapter is HeaderDragAndSwipeAdapter) {\n                return super.getMovementFlags(recyclerView, viewHolder)\n            }\n            return makeMovementFlags(0, 0)\n        }\n        return makeMovementFlags(0, 0)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipeActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe\n\nimport android.animation.ValueAnimator\nimport android.graphics.Color\nimport android.os.Build\nimport android.os.Bundle\nimport android.util.Log\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.HeaderDragAndSwipeAdapter\nimport com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeTopHeaderAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding\nimport com.chad.baserecyclerviewadapterhelper.utils.vibrate\nimport com.chad.library.adapter4.QuickAdapterHelper\nimport com.chad.library.adapter4.dragswipe.setItemDragListener\nimport com.chad.library.adapter4.dragswipe.setItemSwipeListener\nimport com.chad.library.adapter4.loadState.LoadState.NotLoading\nimport com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter\nimport com.chad.library.adapter4.viewholder.QuickViewHolder\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\n/**\n * 带头部局以及带加载下一页的，拖拽demo\n */\nclass HeaderDragAndSwipeActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {\n\n\n    private val pageInfo = PageInfo()\n\n    internal class PageInfo {\n        var page = 0\n        fun nextPage() {\n            page++\n        }\n\n        fun reset() {\n            page = 0\n        }\n\n        val isFirstPage: Boolean\n            get() = page == 0\n    }\n\n    var headerDragAndSwipe = HeaderDragAndSwipe()\n        .setDragMoveFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN)\n        .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT)\n\n    private val mAdapter: HeaderDragAndSwipeAdapter = HeaderDragAndSwipeAdapter()\n    private lateinit var helper: QuickAdapterHelper\n\n    override fun initBinding(): ActivityUniversalRecyclerBinding =\n        ActivityUniversalRecyclerBinding.inflate(layoutInflater)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"Head Drag And Swipe\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n        viewBinding.rv.layoutManager = LinearLayoutManager(this)\n\n\n        helper = QuickAdapterHelper.Builder(mAdapter)\n            .setTrailingLoadStateAdapter(\n                object : TrailingLoadStateAdapter.OnTrailingListener {\n                    override fun onLoad() {\n                        loadMore()\n                    }\n\n                    override fun onFailRetry() {\n                    }\n\n                    override fun isAllowLoading(): Boolean {\n                        return true\n                    }\n                })\n            .build()\n            .addBeforeAdapter(HomeTopHeaderAdapter())\n\n        headerDragAndSwipe.attachToRecyclerView(viewBinding.rv)\n            .setDataCallback(mAdapter)\n            .setItemDragListener(\n                onItemDragStart = { viewHolder, pos ->\n                    Log.d(TAG, \"drag start\")\n                    vibrate()\n                    val holder = viewHolder as QuickViewHolder\n                    // 开始时，item背景色变化，demo这里使用了一个动画渐变，使得自然\n                    val startColor = Color.WHITE\n                    val endColor = Color.rgb(245, 245, 245)\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n                        ValueAnimator.ofArgb(startColor, endColor).apply {\n                            addUpdateListener { animation: ValueAnimator ->\n                                holder.itemView.setBackgroundColor(\n                                    animation.animatedValue as Int\n                                )\n                            }\n                            duration = 300\n                            start()\n                        }\n                    }\n                },\n                onItemDragMoving = { source, from, target, to ->\n                    Log.d(TAG, \"move from: $from  to:  $to\")\n                },\n                onItemDragEnd = { viewHolder, pos ->\n                    Log.d(TAG, \"drag end\")\n                    val holder = viewHolder as QuickViewHolder\n                    // 结束时，item背景色变化，demo这里使用了一个动画渐变，使得自然\n                    val startColor = Color.rgb(245, 245, 245)\n                    val endColor = Color.WHITE\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\n                        ValueAnimator.ofArgb(startColor, endColor).apply {\n                            addUpdateListener { animation: ValueAnimator ->\n                                holder.itemView.setBackgroundColor(\n                                    animation.animatedValue as Int\n                                )\n                            }\n                            duration = 300\n                            start()\n                        }\n                    }\n                }\n\n            )\n            .setItemSwipeListener(\n                onItemSwipeStart = { viewHolder, pos ->\n                    Log.d(TAG, \"onItemSwipeStart\")\n                },\n                onItemSwipeMoving = { canvas, viewHolder, dX, dY, isCurrentlyActive ->\n                    Log.d(TAG, \"onItemSwipeMoving\")\n                },\n                onItemSwiped = { viewHolder, _, pos ->\n                    Log.d(TAG, \"onItemSwiped\")\n                },\n                onItemSwipeEnd = { viewHolder, pos ->\n                    Log.d(TAG, \"onItemSwipeEnd\")\n                }\n            )\n        viewBinding.rv.adapter = helper.adapter\n        loadMore()\n    }\n\n\n    private fun loadMore() {\n        Request(pageInfo.page, object : RequestCallBack {\n            override fun success(data: List<String>) {\n                if (pageInfo.page == 0) {\n                    mAdapter.submitList(data)\n                } else {\n                    mAdapter.addAll(data)\n                }\n\n                helper.trailingLoadState = NotLoading(false)\n                // page加一\n                pageInfo.nextPage()\n            }\n\n            override fun fail(e: Exception?) {\n\n            }\n\n            override fun end() {\n                helper.trailingLoadState = NotLoading(true)\n            }\n        }).loadMore()\n    }\n\n    /**\n     * 模拟加载数据的类，不用特别关注\n     */\n    internal class Request(\n        private val mPage: Int,\n        private val mCallBack: RequestCallBack\n    ) {\n\n        fun loadMore() {\n            GlobalScope.launch(Dispatchers.IO) {\n                if (mPage != 0) {\n                    delay(1500)\n                }\n                withContext(Dispatchers.Main) {\n                    val size = PAGE_SIZE\n                    if (mPage == 3) {\n                        mCallBack.end()\n                    } else {\n                        val starIndex = mPage.times(size)\n                        mCallBack.success(generateData(starIndex, size))\n                    }\n                }\n            }\n        }\n\n        private fun generateData(starIndex: Int, size: Int): List<String> {\n            val data = java.util.ArrayList<String>(size)\n            val endIndex = starIndex.plus(size)\n            for (i in starIndex until endIndex) {\n                data.add(\"item $i\")\n            }\n            return data\n        }\n\n    }\n\n    internal interface RequestCallBack {\n        /**\n         * 模拟加载成功\n         *\n         * @param data 数据\n         */\n        fun success(data: List<String>)\n\n        /**\n         * 模拟加载失败\n         *\n         * @param e 错误信息\n         */\n        fun fail(e: Exception?)\n\n        /**\n         * 模拟加载结束\n         */\n        fun end()\n    }\n\n    companion object {\n        private const val PAGE_SIZE = 20\n        private const val TAG = \"Default Drag And Swipe\"\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/ManualDragAndSwipeUseActivity.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe;\n\nimport android.animation.ValueAnimator;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.core.graphics.Insets;\nimport androidx.core.view.OnApplyWindowInsetsListener;\nimport androidx.core.view.ViewCompat;\nimport androidx.core.view.WindowInsetsCompat;\nimport androidx.recyclerview.widget.ItemTouchHelper;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.DragAndSwipeAdapter;\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity;\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding;\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips;\nimport com.chad.baserecyclerviewadapterhelper.utils.VibratorUtilsKt;\nimport com.chad.library.adapter4.QuickAdapterHelper;\nimport com.chad.library.adapter4.dragswipe.QuickDragAndSwipe;\nimport com.chad.library.adapter4.dragswipe.listener.OnItemDragListener;\nimport com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener;\nimport com.chad.library.adapter4.viewholder.QuickViewHolder;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * 手动实现拖动与侧滑效果\n * Manual drag and Drag effects\n */\npublic class ManualDragAndSwipeUseActivity extends BaseViewBindingActivity<ActivityUniversalRecyclerBinding> {\n\n    private final String TAG = \"Manual Drag And Swipe\";\n\n    private DragAndSwipeAdapter mAdapter;\n    private QuickAdapterHelper helper;\n\n    QuickDragAndSwipe quickDragAndSwipe = new QuickDragAndSwipe()\n            .setDragMoveFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN)\n            .setSwipeMoveFlags(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)\n            .setItemViewSwipeEnabled(true)\n            .setLongPressDragEnabled(false);//关闭默认的长按拖拽功能，通过自定义长按事件进行拖拽\n\n    @NonNull\n    @Override\n    public ActivityUniversalRecyclerBinding initBinding() {\n        return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater());\n    }\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() {\n            @Override\n            public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) {\n                Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars());\n                getViewBinding().titleBar.updateFakeBarHeight(bar.top);\n                return insets;\n            }\n        });\n\n        getViewBinding().titleBar.setTitle(\"Manual Drag And Swipe\");\n        getViewBinding().titleBar.setOnBackListener(v -> finish());\n\n\n        getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this));\n\n        // 拖拽监听\n        OnItemDragListener listener = new OnItemDragListener() {\n            @Override\n            public void onItemDragStart(@Nullable RecyclerView.ViewHolder viewHolder, int pos) {\n                VibratorUtilsKt.vibrate(getApplicationContext());\n                Log.d(TAG, \"drag start\");\n                final QuickViewHolder holder = ((QuickViewHolder) viewHolder);\n                if (holder == null) return;\n                // 开始时，item背景色变化，demo这里使用了一个动画渐变，使得自然\n                int startColor = Color.WHITE;\n                int endColor = Color.rgb(245, 245, 245);\n                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {\n                    ValueAnimator v = ValueAnimator.ofArgb(startColor, endColor);\n                    v.addUpdateListener(animation -> holder.itemView.setBackgroundColor((int) animation.getAnimatedValue()));\n                    v.setDuration(300);\n                    v.start();\n                }\n            }\n\n            @Override\n            public void onItemDragMoving(@NonNull RecyclerView.ViewHolder source, int from, @NonNull RecyclerView.ViewHolder target, int to) {\n                Log.d(TAG, \"move from: \" + source.getBindingAdapterPosition() + \" to: \" + target.getBindingAdapterPosition());\n            }\n\n            @Override\n            public void onItemDragEnd(@NonNull RecyclerView.ViewHolder viewHolder, int pos) {\n                Log.d(TAG, \"drag end\");\n                final QuickViewHolder holder = ((QuickViewHolder) viewHolder);\n                // 结束时，item背景色变化，demo这里使用了一个动画渐变，使得自然\n                int startColor = Color.rgb(245, 245, 245);\n                int endColor = Color.WHITE;\n                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {\n                    ValueAnimator v = ValueAnimator.ofArgb(startColor, endColor);\n                    v.addUpdateListener(animation -> holder.itemView.setBackgroundColor((int) animation.getAnimatedValue()));\n                    v.setDuration(300);\n                    v.start();\n                }\n            }\n        };\n\n        OnItemSwipeListener swipeListener = new OnItemSwipeListener() {\n            @Override\n            public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int bindingAdapterPosition) {\n                Log.d(TAG, \"onItemSwipeStart\");\n            }\n\n            @Override\n            public void onItemSwipeEnd(@NonNull RecyclerView.ViewHolder viewHolder, int bindingAdapterPosition) {\n                Log.d(TAG, \"onItemSwipeEnd \" + bindingAdapterPosition);\n            }\n\n            @Override\n            public void onItemSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction, int bindingAdapterPosition) {\n                Log.d(TAG,  \"onItemSwiped\");\n            }\n\n            @Override\n            public void onItemSwipeMoving(@NonNull Canvas canvas, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {\n                Log.d(TAG, \"onItemSwipeMoving\");\n            }\n        };\n\n        List<String> mData = generateData(50);\n        mAdapter = new DragAndSwipeAdapter();\n        helper = new QuickAdapterHelper.Builder(mAdapter)\n                .build();\n        getViewBinding().rv.setAdapter(helper.getAdapter());\n        mAdapter.submitList(mData);\n        quickDragAndSwipe.attachToRecyclerView(getViewBinding().rv)\n                .setDataCallback(mAdapter)\n                .setItemDragListener(listener)\n                .setItemSwipeListener(swipeListener);\n        mAdapter.setOnItemClickListener((adapter, view, position) -> {\n            Tips.show(\"点击了：\" + position + \"，侧滑可进行删除\" + position);\n            quickDragAndSwipe.startSwipe(position);\n        });\n        mAdapter.setOnItemLongClickListener((adapter, view, position) -> {\n            /*\n             * 长按默认可拖动，可不进行设置此方法\n             * 此方法可以做特殊使用进行调用\n             * 如：长按此条position对应的item，触发 position+1 对应的item\n             * 此处使用，关闭了默认长按拖拽功能\n             */\n            Tips.show(\"长按了：\" + position + \"，现在拖动可进行变换位置\");\n            quickDragAndSwipe.startDrag(position);\n            return false;\n        });\n    }\n\n    private List<String> generateData(int size) {\n        ArrayList<String> data = new ArrayList<>(size);\n        for (int i = 0; i < size; i++) {\n            data.add(\"item \" + i);\n        }\n        return data;\n    }\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DiffDragAndSwipeAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter\n\nimport android.content.Context\nimport android.view.ViewGroup\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.activity.differ.adapter.DiffEntityCallback\nimport com.chad.baserecyclerviewadapterhelper.entity.DiffEntity\nimport com.chad.library.adapter4.BaseQuickAdapter\nimport com.chad.library.adapter4.viewholder.QuickViewHolder\n\n/**\n * Create adapter\n */\nclass DiffDragAndSwipeAdapter :\n    BaseQuickAdapter<DiffEntity, QuickViewHolder>(DiffEntityCallback()) {\n\n    override fun onCreateViewHolder(\n        context: Context, parent: ViewGroup, viewType: Int\n    ): QuickViewHolder {\n        return QuickViewHolder(R.layout.layout_animation, parent)\n    }\n\n    override fun onBindViewHolder(\n        holder: QuickViewHolder, position: Int, item: DiffEntity?\n    ) {\n        if (item == null) return\n\n        holder.setText(R.id.tweetName, item.title)\n            .setText(R.id.tweetText, item.content)\n            .setText(R.id.tweetDate, item.date)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DragAndSwipeAdapter.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter;\n\n\nimport android.content.Context;\nimport android.view.ViewGroup;\n\nimport androidx.annotation.NonNull;\n\nimport com.chad.baserecyclerviewadapterhelper.R;\nimport com.chad.library.adapter4.BaseQuickAdapter;\nimport com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback;\nimport com.chad.library.adapter4.viewholder.QuickViewHolder;\n\npublic class DragAndSwipeAdapter extends BaseQuickAdapter<String, QuickViewHolder> implements DragAndSwipeDataCallback {\n\n    @NonNull\n    @Override\n    protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {\n        return new QuickViewHolder(R.layout.item_draggable_view, parent);\n    }\n\n    @Override\n    protected void onBindViewHolder(@NonNull QuickViewHolder holder, int position, String item) {\n        switch (holder.getLayoutPosition() % 3) {\n            case 0 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img0);\n            case 1 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img1);\n            case 2 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img2);\n            default -> {\n            }\n        }\n        holder.setText(R.id.tv, item);\n    }\n\n    @Override\n    public void dataMove(int fromPosition, int toPosition) {\n        move(fromPosition, toPosition);\n    }\n\n    @Override\n    public void dataRemoveAt(int position) {\n        removeAt(position);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/HeaderDragAndSwipeAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter\n\nimport android.content.Context\nimport android.view.ViewGroup\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.library.adapter4.BaseQuickAdapter\nimport com.chad.library.adapter4.viewholder.QuickViewHolder\nimport com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback\n\n/**\n * kotlin方式集成案例\n */\nopen class HeaderDragAndSwipeAdapter : BaseQuickAdapter<String, QuickViewHolder>(),\n    DragAndSwipeDataCallback {\n\n    override fun onCreateViewHolder(\n        context: Context,\n        parent: ViewGroup,\n        viewType: Int\n    ): QuickViewHolder {\n        return QuickViewHolder(R.layout.item_draggable_view, parent)\n    }\n\n     override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: String?) {\n        when (holder.layoutPosition % 3) {\n            0 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img0)\n            1 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img1)\n            2 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img2)\n            else -> {}\n        }\n        holder.setText(R.id.tv, item)\n    }\n\n    override fun dataMove(fromPosition: Int, toPosition: Int) {\n        move(fromPosition, toPosition)\n    }\n\n    override fun dataRemoveAt(position: Int) {\n        removeAt(position)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/EmptyViewUseActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.emptyview\n\nimport android.os.Bundle\nimport android.view.View\nimport android.widget.FrameLayout\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.StaggeredGridLayoutManager\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.activity.emptyview.adapter.EmptyViewAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.data.DataServer\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityEmptyViewUseBinding\n\nclass EmptyViewUseActivity : BaseViewBindingActivity<ActivityEmptyViewUseBinding>() {\n\n    private val mAdapter = EmptyViewAdapter()\n\n    private var mError = true\n    private var mNoData = true\n\n    override fun initBinding(): ActivityEmptyViewUseBinding =\n        ActivityEmptyViewUseBinding.inflate(layoutInflater)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"EmptyView Use\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n        viewBinding.btnReset.setOnClickListener { reset() }\n\n        viewBinding.rvList.adapter = mAdapter\n        viewBinding.rvList.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)\n\n        // 打开空布局功能\n        mAdapter.isStateViewEnable = true\n        mAdapter.isUseStateViewSize = true\n\n        onRefresh()\n    }\n\n    private fun reset() {\n        mError = true\n        mNoData = true\n        mAdapter.submitList(null)\n        onRefresh()\n    }\n\n    private val emptyDataView: View\n        get() {\n            val notDataView = layoutInflater.inflate(R.layout.empty_view, FrameLayout(this), false)\n            notDataView.setOnClickListener { onRefresh() }\n            return notDataView\n        }\n\n    private val errorView: View\n        get() {\n            val errorView = layoutInflater.inflate(R.layout.error_view, FrameLayout(this), false)\n            errorView.setOnClickListener { onRefresh() }\n            return errorView\n        }\n\n    private fun onRefresh() {\n        // 方式一：直接传入 layout id\n        mAdapter.setStateViewLayout(this, R.layout.loading_view)\n\n        viewBinding.rvList.postDelayed({\n            if (mError) { // 模拟网络错误\n                // 方式二：传入View\n                mAdapter.stateView = errorView\n\n                mError = false\n            } else {\n                if (mNoData) { // 模拟接口没有数据\n                    mAdapter.stateView = emptyDataView\n                    mNoData = false\n                } else {\n                    // 模拟正常数据返回\n                    mAdapter.submitList(DataServer.getSampleData(10))\n                }\n            }\n        }, 1000)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/adapter/EmptyViewAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.emptyview.adapter\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.databinding.LayoutAnimationBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.Status\nimport com.chad.library.adapter4.BaseQuickAdapter\n\nclass EmptyViewAdapter : BaseQuickAdapter<Status, EmptyViewAdapter.VH>() {\n\n    class VH(\n        parent: ViewGroup,\n        val binding: LayoutAnimationBinding = LayoutAnimationBinding.inflate(\n            LayoutInflater.from(parent.context), parent, false\n        ),\n    ) : RecyclerView.ViewHolder(binding.root)\n\n    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {\n        return VH(parent)\n    }\n\n    override fun onBindViewHolder(holder: VH, position: Int, item: Status?) {\n        if (item == null) return\n        holder.binding.img.setImageResource(item.userAvatar)\n        holder.binding.tweetName.text = item.userName\n        holder.binding.tweetText.text = \"O ever youthful,O ever weeping\"\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/HeaderAndFooterUseActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.headerfooter\n\nimport android.os.Bundle\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.FooterAdapter\nimport com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter\nimport com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAndFooterAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.data.DataServer\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips\nimport com.chad.library.adapter4.QuickAdapterHelper\n\n/**\n * https://github.com/CymChad/BaseRecyclerViewAdapterHelper\n */\nclass HeaderAndFooterUseActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {\n\n    private lateinit var helper: QuickAdapterHelper\n\n    override fun initBinding(): ActivityUniversalRecyclerBinding =\n        ActivityUniversalRecyclerBinding.inflate(layoutInflater)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"Header And Footer Use\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n\n        val adapter = HeaderAndFooterAdapter(DataServer.getSampleData(PAGE_SIZE))\n        adapter.setOnItemClickListener { _, _, position ->\n            Tips.show(\"position: $position\")\n        }\n\n\n        helper = QuickAdapterHelper.Builder(adapter)\n            .build()\n\n        viewBinding.rv.layoutManager = LinearLayoutManager(this)\n        viewBinding.rv.adapter = helper.adapter\n        addHeader()\n\n        helper.addAfterAdapter(\n            FooterAdapter(false).setOnItemClickListener { _, _, _ ->\n                addFooter()\n            }\n        )\n    }\n\n    private fun addHeader() {\n        helper.addBeforeAdapter(0, HeaderAdapter().apply {\n            setOnItemClickListener { _, _, _ ->\n                addHeader()\n            }\n        })\n    }\n\n    private fun addFooter() {\n        helper.addAfterAdapter(FooterAdapter(true).setOnItemClickListener{ adapter, _, _ ->\n            helper.removeAdapter(adapter)\n        })\n    }\n\n    companion object {\n        private const val PAGE_SIZE = 3\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/FooterAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter\n\nimport android.content.Context\nimport android.view.ViewGroup\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.library.adapter4.BaseSingleItemAdapter\nimport com.chad.library.adapter4.viewholder.QuickViewHolder\n\nclass FooterAdapter(\n    private val isDelete: Boolean\n) : BaseSingleItemAdapter<Any, QuickViewHolder>() {\n\n    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): QuickViewHolder {\n        return QuickViewHolder(R.layout.footer_view, parent)\n    }\n\n    override fun onBindViewHolder(holder: QuickViewHolder, item: Any?) {\n        if (isDelete) {\n            holder.setImageResource(R.id.iv, R.mipmap.rm_icon)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.library.adapter4.BaseSingleItemAdapter\n\nclass HeaderAdapter: BaseSingleItemAdapter<Any, HeaderAdapter.VH>() {\n\n    class VH(view: View): RecyclerView.ViewHolder(view)\n\n    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {\n        val view = LayoutInflater.from(parent.context).inflate(R.layout.head_view, parent, false)\n        return VH(view)\n    }\n\n    override fun onBindViewHolder(holder: VH, item: Any?) {\n\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAndFooterAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemHeaderAndFooterBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.Status\nimport com.chad.library.adapter4.BaseQuickAdapter\n\n/**\n * https://github.com/CymChad/BaseRecyclerViewAdapterHelper\n */\nclass HeaderAndFooterAdapter(list: List<Status>) :\n    BaseQuickAdapter<Status, HeaderAndFooterAdapter.VH>(list) {\n\n    class VH(var binding: ItemHeaderAndFooterBinding) : RecyclerView.ViewHolder(binding.root)\n\n    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {\n        val binding =\n            ItemHeaderAndFooterBinding.inflate(LayoutInflater.from(context), parent, false)\n        return VH(binding)\n    }\n\n    override fun onBindViewHolder(holder: VH, position: Int, item: Status?) {\n        when (holder.layoutPosition % 3) {\n            0 -> holder.binding.iv.setImageResource(R.mipmap.animation_img1)\n            1 -> holder.binding.iv.setImageResource(R.mipmap.animation_img2)\n            2 -> holder.binding.iv.setImageResource(R.mipmap.animation_img3)\n            else -> {}\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/HomeActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.home\n\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.View\nimport androidx.appcompat.app.AppCompatActivity\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.activity.animation.AnimationUseActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.databinding.DataBindingUseActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.differ.DifferActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.dragswipe.DragAndSwipeUseActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.emptyview.EmptyViewUseActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.headerfooter.HeaderAndFooterUseActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeAdapter\nimport com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeTopHeaderAdapter\nimport com.chad.baserecyclerviewadapterhelper.activity.itemclick.ItemClickActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.loadmore.AutoLoadMoreRefreshUseActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.loadmore.NoAutoAutoLoadMoreRefreshUseActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.node.NodeActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.scene.GroupDemoActivity\nimport com.chad.baserecyclerviewadapterhelper.activity.upfetch.UpFetchUseActivity\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityHomeBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.HomeEntity\nimport com.chad.library.adapter4.BaseQuickAdapter\nimport com.chad.library.adapter4.QuickAdapterHelper\n\nclass HomeActivity : AppCompatActivity(), BaseQuickAdapter.OnItemClickListener<HomeEntity> {\n\n    private lateinit var binding: ActivityHomeBinding\n\n    /**\n     * RV适配器\n     */\n    private val homeAdapter by lazy(LazyThreadSafetyMode.NONE) {\n        HomeAdapter(homeItemData)\n    }\n\n    private val helper by lazy(LazyThreadSafetyMode.NONE) {\n        QuickAdapterHelper.Builder(homeAdapter)\n            .build()\n            .addBeforeAdapter(HomeTopHeaderAdapter())\n    }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        binding = ActivityHomeBinding.inflate(layoutInflater)\n        setContentView(binding.root)\n\n        // 从 QuickAdapterHelper 获取 adapter，设置给 RecycleView\n        binding.recyclerView.adapter = helper.adapter\n\n        // 设置点击事件\n        homeAdapter.setOnItemClickListener(this)\n    }\n\n    /**\n     * item 点击事件\n     *\n     * @param adapter\n     * @param view\n     * @param position\n     */\n    override fun onClick(\n        adapter: BaseQuickAdapter<HomeEntity, *>,\n        view: View,\n        position: Int,\n    ) {\n        val item = adapter.getItem(position)\n        if (!item.isSection) {\n            startActivity(Intent(this@HomeActivity, item.activity))\n        }\n    }\n\n    private val homeItemData: ArrayList<HomeEntity>\n        get() = arrayListOf(\n            HomeEntity(sectionTitle = \"BaseQuickAdapter 基础功能\"),\n            HomeEntity(\"Animation\", AnimationUseActivity::class.java, R.mipmap.gv_animation),\n            HomeEntity(\n                \"Header/Footer\",\n                HeaderAndFooterUseActivity::class.java,\n                R.mipmap.gv_header_and_footer\n            ),\n            HomeEntity(\"EmptyView\", EmptyViewUseActivity::class.java, R.mipmap.gv_empty),\n            HomeEntity(\"ItemClick\", ItemClickActivity::class.java, R.mipmap.gv_item_click),\n            HomeEntity(\"DataBinding\", DataBindingUseActivity::class.java, R.mipmap.gv_databinding),\n            HomeEntity(\"DiffUtil\", DifferActivity::class.java, R.mipmap.gv_databinding),\n            HomeEntity(\"Multi-node\", NodeActivity::class.java, R.mipmap.gv_databinding),\n//\n            HomeEntity(sectionTitle = \"功能模块\"),\n            HomeEntity(\"LoadMore(Auto)\", AutoLoadMoreRefreshUseActivity::class.java, R.mipmap.gv_pulltorefresh),\n            HomeEntity(\"LoadMore\", NoAutoAutoLoadMoreRefreshUseActivity::class.java, R.mipmap.gv_pulltorefresh),\n            HomeEntity(\"DragAndSwipe\", DragAndSwipeUseActivity::class.java, R.mipmap.gv_drag_and_swipe),\n            HomeEntity(\"UpFetch\", UpFetchUseActivity::class.java, R.drawable.gv_up_fetch),\n\n\n            HomeEntity(sectionTitle = \"场景演示\"),\n            HomeEntity(\"Group（ConcatAdapter）\", GroupDemoActivity::class.java, R.mipmap.gv_animation),\n        )\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.home.adapter\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.databinding.DefSectionHeadBinding\nimport com.chad.baserecyclerviewadapterhelper.databinding.HomeItemViewBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.HomeEntity\nimport com.chad.library.adapter4.BaseMultiItemAdapter\n\n/**\n * https://github.com/CymChad/BaseRecyclerViewAdapterHelper\n */\nclass HomeAdapter(data: List<HomeEntity>) : BaseMultiItemAdapter<HomeEntity>(data) {\n\n    class ItemVH(val viewBinding: HomeItemViewBinding) : RecyclerView.ViewHolder(viewBinding.root)\n\n    class HeaderVH(val viewBinding: DefSectionHeadBinding) : RecyclerView.ViewHolder(viewBinding.root)\n\n    init {\n        addItemType(ITEM_TYPE, object : OnMultiItemAdapterListener<HomeEntity, ItemVH> {\n            override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH {\n                val viewBinding =\n                    HomeItemViewBinding.inflate(LayoutInflater.from(context), parent, false)\n                return ItemVH(viewBinding)\n            }\n\n            override fun onBind(holder: ItemVH, position: Int, item: HomeEntity?) {\n                if (item == null) return\n                holder.viewBinding.textView.text = item.name\n                holder.viewBinding.icon.setImageResource(item.imageResource)\n            }\n        }).addItemType(SECTION_TYPE, object : OnMultiItemAdapterListener<HomeEntity, HeaderVH> {\n            override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): HeaderVH {\n                val viewBinding =\n                    DefSectionHeadBinding.inflate(LayoutInflater.from(context), parent, false)\n                return HeaderVH(viewBinding)\n            }\n\n            override fun onBind(holder: HeaderVH, position: Int, item: HomeEntity?) {\n                if (item == null) return\n\n                holder.viewBinding.more.visibility = View.GONE\n                holder.viewBinding.header.text = item.sectionTitle\n            }\n\n            override fun isFullSpanItem(itemType: Int): Boolean {\n                return true\n            }\n\n        }).onItemViewType { position, list ->\n            if (list[position].isSection) {\n                SECTION_TYPE\n            } else {\n                ITEM_TYPE\n            }\n        }\n    }\n\n    companion object {\n        private const val ITEM_TYPE = 10\n        private const val SECTION_TYPE = 11\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeTopHeaderAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.home.adapter\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.library.adapter4.BaseSingleItemAdapter\nimport com.chad.library.adapter4.fullspan.FullSpanAdapterType\n\nclass HomeTopHeaderAdapter : BaseSingleItemAdapter<Any, HomeTopHeaderAdapter.VH>(),\n    FullSpanAdapterType {\n\n    companion object {\n        val HEAD_VIEWTYPE = 0x10000556\n    }\n\n    class VH(view: View) : RecyclerView.ViewHolder(view)\n\n    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {\n        return VH(LayoutInflater.from(parent.context).inflate(R.layout.top_view, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: VH, item: Any?) {\n    }\n\n    override fun getItemViewType(position: Int, list: List<Any>): Int {\n        return HEAD_VIEWTYPE\n    }\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/ItemClickActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.itemclick\n\nimport android.os.Bundle\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.activity.itemclick.adapter.ItemClickAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.ClickEntity\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips\nimport com.chad.library.adapter4.util.addOnDebouncedChildClick\nimport com.chad.library.adapter4.util.setOnDebouncedItemClick\n\n/**\n * @author Allen\n */\nclass ItemClickActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {\n\n    private val adapter: ItemClickAdapter by lazy(LazyThreadSafetyMode.NONE) {\n        // 创建数据\n        val data = ArrayList<ClickEntity>().apply {\n            add(ClickEntity(ClickEntity.CLICK_ITEM_VIEW))\n            add(ClickEntity(ClickEntity.CLICK_ITEM_CHILD_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))\n            add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW))\n        }\n        // 创建Adapter\n        ItemClickAdapter(data)\n    }\n\n    override fun initBinding(): ActivityUniversalRecyclerBinding =\n        ActivityUniversalRecyclerBinding.inflate(layoutInflater)\n\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"Item Click Use\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n        viewBinding.rv.layoutManager = LinearLayoutManager(this)\n        viewBinding.rv.adapter = adapter\n\n        // 设置点击事件\n        adapter.setOnItemClickListener { _, _, position ->\n            Tips.show(\"onItemClick $position\")\n        }\n        // 去除点击抖动的扩展方法\n        adapter.setOnDebouncedItemClick {adapter, view, position ->\n            Tips.show(\"onItemClick $position\")\n        }\n\n        // 设置item 长按事件\n        adapter.setOnItemLongClickListener { _, _, position ->\n            Tips.show(\"onItemLongClick $position\")\n            true\n        }\n\n        // 添加子 view 的点击事件\n        adapter.addOnItemChildClickListener(R.id.btn) { adapter, view, position ->\n            Tips.show(\"onItemChildClick: $position\")\n        }\n        adapter.addOnItemChildClickListener(R.id.iv_num_reduce) { adapter, view, position ->\n            Tips.show(\"onItemChildClick:  reduce $position\")\n        }\n        adapter.addOnItemChildClickListener(R.id.iv_num_add) { adapter, view, position ->\n            Tips.show(\"onItemChildClick:  add $position\")\n            adapter.removeAt(position)\n        }\n\n        // 添加子 view 的点击事件(去除点击抖动的扩展方法)\n        adapter.addOnDebouncedChildClick(R.id.btn) { adapter, view, position ->\n            Tips.show(\"onItemChildClick: $position\")\n        }\n\n        // 设置子 view 长按事件\n        adapter.addOnItemChildLongClickListener(R.id.btn_long) { adapter, view, position ->\n            Tips.show(\"onItemChildLongClick $position\")\n            true\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/adapter/ItemClickAdapter.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.itemclick.adapter;\n\nimport android.content.Context;\nimport android.view.LayoutInflater;\nimport android.view.ViewGroup;\n\nimport androidx.annotation.NonNull;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemClickChildviewBinding;\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemClickViewBinding;\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemLongClickChildviewBinding;\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemLongClickViewBinding;\nimport com.chad.baserecyclerviewadapterhelper.entity.ClickEntity;\nimport com.chad.library.adapter4.BaseMultiItemAdapter;\n\nimport java.util.List;\n\n/**\n *\n */\npublic class ItemClickAdapter extends BaseMultiItemAdapter<ClickEntity> {\n\n    static class ItemViewVH extends RecyclerView.ViewHolder {\n\n        ItemClickViewBinding viewBinding;\n\n        public ItemViewVH(@NonNull ItemClickViewBinding viewBinding) {\n            super(viewBinding.getRoot());\n            this.viewBinding = viewBinding;\n        }\n\n        public ItemViewVH(@NonNull ViewGroup parent) {\n            this(ItemClickViewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));\n        }\n    }\n\n    static class ItemChildVH extends RecyclerView.ViewHolder {\n\n        ItemClickChildviewBinding viewBinding;\n\n        public ItemChildVH(@NonNull ItemClickChildviewBinding viewBinding) {\n            super(viewBinding.getRoot());\n            this.viewBinding = viewBinding;\n        }\n\n        public ItemChildVH(@NonNull ViewGroup parent) {\n            this(ItemClickChildviewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));\n        }\n    }\n\n    static class ItemLongClickVH extends RecyclerView.ViewHolder {\n\n        ItemLongClickViewBinding viewBinding;\n\n        public ItemLongClickVH(@NonNull ItemLongClickViewBinding viewBinding) {\n            super(viewBinding.getRoot());\n            this.viewBinding = viewBinding;\n        }\n\n        public ItemLongClickVH(@NonNull ViewGroup parent) {\n            this(ItemLongClickViewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));\n        }\n    }\n\n    static class ItemChildLongClickVH extends RecyclerView.ViewHolder {\n\n        ItemLongClickChildviewBinding viewBinding;\n\n        public ItemChildLongClickVH(@NonNull ItemLongClickChildviewBinding viewBinding) {\n            super(viewBinding.getRoot());\n            this.viewBinding = viewBinding;\n        }\n\n        public ItemChildLongClickVH(@NonNull ViewGroup parent) {\n            this(ItemLongClickChildviewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));\n        }\n    }\n\n    /**\n     * 构造方法\n     */\n    public ItemClickAdapter(List<ClickEntity> data) {\n        super(data);\n\n        addItemType(ClickEntity.CLICK_ITEM_VIEW, new OnMultiItemAdapterListener<ClickEntity, ItemViewVH>() {\n\n            @NonNull\n            @Override\n            public ItemViewVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {\n                return new ItemViewVH(parent);\n            }\n\n            @Override\n            public void onBind(@NonNull ItemViewVH holder, int position, ClickEntity item) {\n            }\n\n            @Override\n            public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {\n                if (holder instanceof ItemViewVH) {\n                    System.out.println(\"---------------------- >> onViewDetachedFromWindow ItemViewVH\");\n                }\n            }\n        }).addItemType(ClickEntity.CLICK_ITEM_CHILD_VIEW, new OnMultiItemAdapterListener<ClickEntity, ItemChildVH>() {\n\n            @NonNull\n            @Override\n            public ItemChildVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {\n                return new ItemChildVH(parent);\n            }\n\n            @Override\n            public void onBind(@NonNull ItemChildVH holder, int position, ClickEntity item) {\n            }\n        }).addItemType(ClickEntity.LONG_CLICK_ITEM_VIEW, new OnMultiItemAdapterListener<ClickEntity, ItemLongClickVH>() {\n\n            @NonNull\n            @Override\n            public ItemLongClickVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {\n                return new ItemLongClickVH(parent);\n            }\n\n            @Override\n            public void onBind(@NonNull ItemLongClickVH holder, int position, ClickEntity item) {\n            }\n        }).addItemType(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW, new OnMultiItemAdapterListener<ClickEntity, ItemChildLongClickVH>() {\n\n            @NonNull\n            @Override\n            public ItemChildLongClickVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) {\n                return new ItemChildLongClickVH(parent);\n            }\n\n            @Override\n            public void onBind(@NonNull ItemChildLongClickVH holder, int position, ClickEntity item) {\n            }\n        }).onItemViewType(new OnItemViewTypeListener<ClickEntity>() {\n            @Override\n            public int onItemViewType(int position, @NonNull List<? extends ClickEntity> list) {\n                return list.get(position).getItemType();\n            }\n        });\n\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/AutoLoadMoreRefreshUseActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.loadmore\n\nimport android.graphics.Color\nimport android.os.Bundle\nimport android.os.Handler\nimport android.os.Looper\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter\nimport com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter.RecyclerViewAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.data.DataServer\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityLoadMoreBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.Status\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips\nimport com.chad.library.adapter4.QuickAdapterHelper\nimport com.chad.library.adapter4.loadState.LoadState\nimport com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter.OnTrailingListener\n\n/**\n * 自动加载更多\n */\nclass AutoLoadMoreRefreshUseActivity : BaseViewBindingActivity<ActivityLoadMoreBinding>() {\n    internal class PageInfo {\n        var page = 0\n        fun nextPage() {\n            page++\n        }\n\n        fun reset() {\n            page = 0\n        }\n\n        val isFirstPage: Boolean\n            get() = page == 0\n    }\n\n    private val pageInfo = PageInfo()\n\n    private val mAdapter: RecyclerViewAdapter = RecyclerViewAdapter()\n    private lateinit var helper: QuickAdapterHelper\n\n    override fun initBinding(): ActivityLoadMoreBinding =\n        ActivityLoadMoreBinding.inflate(layoutInflater)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            viewBinding.rvList.updatePadding(bottom = bar.bottom)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"Auto LoadMore Use\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n\n        viewBinding.rvList.layoutManager = LinearLayoutManager(this)\n        initAdapter()\n        addHeadView()\n        initRefreshLayout()\n    }\n\n    override fun onStart() {\n        super.onStart()\n        // 进入页面，先显示加载状态布局\n        mAdapter.setEmptyViewLayout(this, R.layout.loading_view)\n        viewBinding.refreshLayout.isRefreshing = true\n        refresh()\n    }\n\n    private fun initAdapter() {\n        // 使用默认的\"加载更多\"的样式\n        helper = QuickAdapterHelper.Builder(mAdapter)\n            .setTrailingLoadStateAdapter(object : OnTrailingListener {\n                override fun onLoad() {\n                    request()\n                }\n\n                override fun onFailRetry() {\n                    request()\n                }\n\n                override fun isAllowLoading(): Boolean {\n                    return !viewBinding.refreshLayout.isRefreshing\n                }\n            })\n            .setTrailPreloadSize(0) // 预加载（默认值为0）\n            .isTrailAutoLoadMore(true) // 是否自动加载更多（默认为true）\n            .build()\n\n        // 设置预加载，请调用以下方法\n        // helper.trailingLoadStateAdapter?.preloadSize = 1\n        viewBinding.rvList.adapter = helper.adapter\n    }\n\n    private fun addHeadView() {\n        val headerAdapter = HeaderAdapter()\n        headerAdapter.setOnItemClickListener { _, _, _ ->\n            addHeadView()\n        }\n        helper.addBeforeAdapter(0, headerAdapter)\n    }\n\n    private fun initRefreshLayout() {\n        viewBinding.refreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189))\n        viewBinding.refreshLayout.setOnRefreshListener { refresh() }\n    }\n\n    /**\n     * 刷新\n     */\n    private fun refresh() {\n        // 下拉刷新，需要重置页数\n        pageInfo.reset()\n        // 重置“加载更多”时状态\n        helper.trailingLoadState = LoadState.None\n        request()\n    }\n\n    /**\n     * 请求数据\n     */\n    private fun request() {\n\n        Request(pageInfo.page, object : RequestCallBack {\n            override fun success(data: List<Status>) {\n                viewBinding.refreshLayout.isRefreshing = false\n                if (pageInfo.isFirstPage) {\n                    // 如果是加载的第一页数据，用 submitList()\n                    // If it is the first page of data loaded, use submitList().\n                    mAdapter.submitList(data)\n                } else {\n                    //不是第一页，则用add\n                    mAdapter.addAll(data)\n                }\n\n                // 如果在数据不满足一屏时，暂停加载更多，请调用下面方法\n                // helper.trailingLoadStateAdapter?.checkDisableLoadMoreIfNotFullPage()\n\n                if (pageInfo.page >= PAGE_SIZE) {\n                    /*\n                    Set the status to not loaded, and there is no paging data.\n                    设置状态为未加载，并且没有分页数据了\n                     */\n                    helper.trailingLoadState = LoadState.NotLoading(true)\n                    Tips.show(\"no more data\")\n                } else {\n                    /*\n                    Set the state to not loaded, and there is also paginated data\n                    设置状态为未加载，并且还有分页数据\n                     */\n                    helper.trailingLoadState = LoadState.NotLoading(false)\n                }\n\n                // page加一\n                pageInfo.nextPage()\n            }\n\n            override fun fail(e: Exception) {\n                Tips.show(resources.getString(R.string.network_err))\n                viewBinding.refreshLayout.isRefreshing = false\n                helper.trailingLoadState = LoadState.Error(e)\n            }\n        }).start()\n    }\n\n    /**\n     * 模拟加载数据的类，不用特别关注\n     */\n    internal class Request(private val mPage: Int, private val mCallBack: RequestCallBack) : Thread() {\n        private val mHandler: Handler = Handler(Looper.getMainLooper())\n\n        override fun run() {\n            try {\n                sleep(800) // 模拟网络延迟\n            } catch (ignored: InterruptedException) {\n            }\n            if (mPage == 2 && mFirstError) {\n                mFirstError = false\n                mHandler.post { mCallBack.fail(RuntimeException(\"load fail\")) }\n            } else {\n                var size = PAGE_SIZE\n                if (mPage == 1) {\n                    if (mFirstPageNoMore) {\n                        size = 1\n                    }\n                    mFirstPageNoMore = !mFirstPageNoMore\n                    if (!mFirstError) {\n                        mFirstError = true\n                    }\n                } else if (mPage == 4) {\n                    size = 1\n                }\n                val dataSize = size\n                mHandler.post { mCallBack.success(DataServer.getSampleData(dataSize)) }\n            }\n        }\n\n        companion object {\n            private var mFirstPageNoMore = false\n            private var mFirstError = true\n        }\n    }\n\n    internal interface RequestCallBack {\n        /**\n         * 模拟加载成功\n         *\n         * @param data 数据\n         */\n        fun success(data: List<Status>)\n\n        /**\n         * 模拟加载失败\n         *\n         * @param e 错误信息\n         */\n        fun fail(e: Exception)\n    }\n\n    companion object {\n        private const val PAGE_SIZE = 5\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/NoAutoAutoLoadMoreRefreshUseActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.loadmore\n\nimport android.graphics.Color\nimport android.os.Bundle\nimport android.os.Handler\nimport android.os.Looper\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter\nimport com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter.CustomLoadMoreAdapter\nimport com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter.RecyclerViewAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.data.DataServer\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityLoadMoreBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.Status\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips\nimport com.chad.library.adapter4.QuickAdapterHelper\nimport com.chad.library.adapter4.loadState.LoadState\nimport com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter.OnTrailingListener\n\n/**\n * 不进行自动加载更多\n */\nclass NoAutoAutoLoadMoreRefreshUseActivity : BaseViewBindingActivity<ActivityLoadMoreBinding>() {\n    internal class PageInfo {\n        var page = 0\n        fun nextPage() {\n            page++\n        }\n\n        fun reset() {\n            page = 0\n        }\n\n        val isFirstPage: Boolean\n            get() = page == 0\n    }\n\n    private val pageInfo = AutoLoadMoreRefreshUseActivity.PageInfo()\n\n    private val mAdapter: RecyclerViewAdapter = RecyclerViewAdapter()\n    private lateinit var helper: QuickAdapterHelper\n\n    override fun initBinding(): ActivityLoadMoreBinding =\n        ActivityLoadMoreBinding.inflate(layoutInflater)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            viewBinding.rvList.updatePadding(bottom = bar.bottom)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"No Auto LoadMore Use\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n\n        viewBinding.rvList.layoutManager = LinearLayoutManager(this)\n        initAdapter()\n        addHeadView()\n        initRefreshLayout()\n    }\n\n    override fun onStart() {\n        super.onStart()\n        // 进入页面，刷新数据\n        mAdapter.setEmptyViewLayout(this, R.layout.loading_view)\n        viewBinding.refreshLayout.isRefreshing = true\n        refresh()\n    }\n\n    private fun initAdapter() {\n        // 自定义\"加载更多\"的样式\n        val loadMoreAdapter = CustomLoadMoreAdapter()\n        loadMoreAdapter.setOnLoadMoreListener(object : OnTrailingListener {\n            override fun onLoad() {\n                request()\n            }\n\n            override fun onFailRetry() {\n                request()\n            }\n\n            override fun isAllowLoading(): Boolean {\n                // 下拉刷新的适合，不允许进行\"加载更多\"\n                return !viewBinding.refreshLayout.isRefreshing\n            }\n        })\n\n        //——————————————————————————————————————————————————————————\n        // 可选，监听加载状态的变化。\n        //——————————————————————————————————————————————————————————\n        loadMoreAdapter.addLoadStateListener { previousState, currentState ->\n            // 你的业务逻辑\n            println(\"----------- previousState: $previousState   -   currentState: $currentState \")\n        }\n\n        //——————————————————————————————————————————————————————————\n        // 关闭\"自动加载更多\"\n        //——————————————————————————————————————————————————————————\n        loadMoreAdapter.isAutoLoadMore = false\n        helper = QuickAdapterHelper.Builder(mAdapter)\n            .setTrailingLoadStateAdapter(loadMoreAdapter)\n            .build()\n        viewBinding.rvList.adapter = helper.adapter\n    }\n\n    private fun addHeadView() {\n        val headerAdapter = HeaderAdapter()\n        headerAdapter.setOnItemClickListener { _, _, _ ->\n            addHeadView()\n        }\n        helper.addBeforeAdapter(headerAdapter)\n    }\n\n    private fun initRefreshLayout() {\n        viewBinding.refreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189))\n        viewBinding.refreshLayout.setOnRefreshListener { refresh() }\n    }\n\n    /**\n     * 刷新\n     */\n    private fun refresh() {\n        // 下拉刷新，需要重置页数\n        pageInfo.reset()\n        request()\n    }\n\n    /**\n     * 请求数据\n     */\n    private fun request() {\n\n        Request(pageInfo.page, object : RequestCallBack {\n            override fun success(data: List<Status>) {\n                viewBinding.refreshLayout.isRefreshing = false\n                if (pageInfo.isFirstPage) {\n                    // 如果是加载的第一页数据，用 submitList()\n                    // If it is the first page of data loaded, use submitList().\n                    mAdapter.submitList(data)\n                } else {\n                    //不是第一页，则用add\n                    mAdapter.addAll(data)\n                }\n                if (pageInfo.page >= PAGE_SIZE) {\n                    /*\n                    Set the status to not loaded, and there is no paging data.\n                    设置状态为未加载，并且没有分页数据了\n                     */\n                    helper.trailingLoadState = LoadState.NotLoading(true)\n                    Tips.show(\"no more data\")\n                } else {\n                    /*\n                    Set the state to not loaded, and there is also paginated data\n                    设置状态为未加载，并且还有分页数据\n                    */\n                    helper.trailingLoadState = LoadState.NotLoading(false)\n                }\n\n                // page加一\n                pageInfo.nextPage()\n            }\n\n            override fun fail(e: Exception) {\n                Tips.show(resources.getString(R.string.network_err))\n                viewBinding.refreshLayout.isRefreshing = false\n                helper.trailingLoadState = LoadState.Error(e)\n            }\n        }).start()\n    }\n\n    /**\n     * 模拟加载数据的类，不用特别关注\n     */\n    internal class Request(private val mPage: Int, private val mCallBack: RequestCallBack) :\n        Thread() {\n        private val mHandler: Handler = Handler(Looper.getMainLooper())\n\n        override fun run() {\n            try {\n                sleep(1000) // 模拟网络延迟\n            } catch (ignored: InterruptedException) {\n            }\n            if (mPage == 2 && mFirstError) {\n                mFirstError = false\n                mHandler.post { mCallBack.fail(RuntimeException(\"load fail\")) }\n            } else {\n                var size = PAGE_SIZE\n                if (mPage == 1) {\n                    if (mFirstPageNoMore) {\n                        size = 1\n                    }\n                    mFirstPageNoMore = !mFirstPageNoMore\n                    if (!mFirstError) {\n                        mFirstError = true\n                    }\n                } else if (mPage == 4) {\n                    size = 1\n                }\n                val dataSize = size\n                mHandler.post { mCallBack.success(DataServer.getSampleData(dataSize)) }\n            }\n        }\n\n        companion object {\n            private var mFirstPageNoMore = false\n            private var mFirstError = true\n        }\n    }\n\n    internal interface RequestCallBack {\n        /**\n         * 模拟加载成功\n         *\n         * @param data 数据\n         */\n        fun success(data: List<Status>)\n\n        /**\n         * 模拟加载失败\n         *\n         * @param e 错误信息\n         */\n        fun fail(e: Exception)\n    }\n\n    companion object {\n        private const val PAGE_SIZE = 5\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/CustomLoadMoreAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.databinding.ViewLoadMoreBinding\nimport com.chad.library.adapter4.loadState.LoadState\nimport com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter\n\n/**\n * 自定义的\"加载更多\"。\n * 这里可以做很多事情，这里仅展示了更改自定义布局的使用。\n *\n * There are many things that can be done here, only the use of changing custom layouts is shown here.\n */\nclass CustomLoadMoreAdapter : TrailingLoadStateAdapter<CustomLoadMoreAdapter.CustomVH>() {\n\n    override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): CustomVH {\n        val viewBinding = ViewLoadMoreBinding.inflate(LayoutInflater.from(parent.context), parent, false)\n        return CustomVH(viewBinding).apply {\n            viewBinding.loadMoreLoadFailView.setOnClickListener {\n                // 失败重试点击事件\n                invokeFailRetry()\n            }\n            viewBinding.loadMoreLoadCompleteView.setOnClickListener {\n                // 加载更多，手动点击事件\n                invokeLoadMore()\n            }\n        }\n    }\n\n    override fun onBindViewHolder(holder: CustomVH, loadState: LoadState) {\n        when (loadState) {\n            is LoadState.NotLoading -> {\n                if (loadState.endOfPaginationReached) {\n                    holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE\n                    holder.viewBinding.loadMoreLoadingView.visibility = View.GONE\n                    holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE\n                    holder.viewBinding.loadMoreLoadEndView.visibility = View.VISIBLE\n                } else {\n                    holder.viewBinding.loadMoreLoadCompleteView.visibility = View.VISIBLE\n                    holder.viewBinding.loadMoreLoadingView.visibility = View.GONE\n                    holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE\n                    holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE\n                }\n            }\n            is LoadState.Loading -> {\n                holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE\n                holder.viewBinding.loadMoreLoadingView.visibility = View.VISIBLE\n                holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE\n                holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE\n            }\n            is LoadState.Error -> {\n                holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE\n                holder.viewBinding.loadMoreLoadingView.visibility = View.GONE\n                holder.viewBinding.loadMoreLoadFailView.visibility = View.VISIBLE\n                holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE\n            }\n            is LoadState.None -> {\n                holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE\n                holder.viewBinding.loadMoreLoadingView.visibility = View.GONE\n                holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE\n                holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE\n            }\n        }\n    }\n\n\n    class CustomVH(val viewBinding: ViewLoadMoreBinding) : RecyclerView.ViewHolder(viewBinding.root)\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/RecyclerViewAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter\n\nimport android.content.Context\nimport android.text.TextPaint\nimport android.text.method.LinkMovementMethod\nimport android.text.style.ClickableSpan\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.core.content.ContextCompat\nimport androidx.core.text.buildSpannedString\nimport androidx.core.text.inSpans\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.databinding.LayoutAnimationBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.Status\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips\nimport com.chad.library.adapter4.BaseQuickAdapter\n\n/**\n * @author: limuyang\n * @date: 2019-12-04\n * @Description:\n */\nclass RecyclerViewAdapter : BaseQuickAdapter<Status, RecyclerViewAdapter.VH>() {\n    class VH(\n        parent: ViewGroup,\n        val viewBinding: LayoutAnimationBinding = LayoutAnimationBinding.inflate(\n            LayoutInflater.from(parent.context), parent, false\n        )\n    ) : RecyclerView.ViewHolder(viewBinding.root)\n\n    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {\n        return VH(parent)\n    }\n\n    protected override fun onBindViewHolder(holder: VH, position: Int, item: Status?) {\n        when (holder.layoutPosition % 3) {\n            0 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img1)\n            1 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img2)\n            2 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img3)\n            else -> {}\n        }\n        holder.viewBinding.tweetName.text =\n            \"Hoteis in Rio de Janeiro \" + position + \"  \" + item!!.userName\n        val msg =\n            \"\\\"He was one of Australia's most of distinguished artistes, renowned for his portraits\\\"\"\n        holder.viewBinding.tweetText.text = buildSpannedString {\n            append(msg)\n            inSpans(clickableSpan) {\n                append(\"landscapes and nedes\")\n            }\n        }\n        holder.viewBinding.tweetText.movementMethod = LinkMovementMethod.getInstance()\n    }\n\n    private val clickableSpan: ClickableSpan = object : ClickableSpan() {\n        override fun onClick(widget: View) {\n            Tips.show(\"事件触发了 landscapes and nedes\")\n        }\n\n        override fun updateDrawState(ds: TextPaint) {\n            ds.color = ContextCompat.getColor(context, R.color.clickspan_color)\n            ds.isUnderlineText = true\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/NodeActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.node\n\nimport android.os.Bundle\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport com.chad.baserecyclerviewadapterhelper.activity.node.adapter.NodeAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.data.DataServer\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityNodeBinding\n\n/**\n * @author LiMuYang\n * @date 2025/9/5\n * @description 多节点demo\n */\nclass NodeActivity : BaseViewBindingActivity<ActivityNodeBinding>() {\n\n    private val adapter = NodeAdapter()\n\n    override fun initBinding(): ActivityNodeBinding {\n        return ActivityNodeBinding.inflate(layoutInflater)\n    }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"Multi-node Use\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n        viewBinding.rv.adapter = adapter\n\n        adapter.submitList(DataServer.getNodeData())\n\n\n        viewBinding.btnCloseAll.setOnClickListener {\n            adapter.closeAll()\n        }\n        viewBinding.btnRef.setOnClickListener {\n            adapter.submitList(DataServer.getNodeData())\n        }\n        viewBinding.btnRefOnSave.setOnClickListener {\n            adapter.submitList(DataServer.getNodeData(),  clearOpenStates = true)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/adapter/NodeAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.node.adapter\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.ViewGroup\nimport android.widget.Toast\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemNodeLevel1Binding\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemNodeLevel2Binding\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemNodeLevel3Binding\nimport com.chad.baserecyclerviewadapterhelper.entity.NodeEntity\nimport com.chad.library.adapter4.BaseNodeAdapter\n\n/**\n * @author LiMuYang\n * @date 2025/9/5\n * @description\n */\nclass NodeAdapter : BaseNodeAdapter() {\n\n    override fun getChildNodeList(position: Int, parent: Any): List<Any>? {\n        when (parent) {\n            is NodeEntity -> {\n                // 一级\n                return parent.childNode\n            }\n\n            is NodeEntity.Level2NodeEntity -> {\n                // 二级\n                return parent.childNode\n            }\n\n            is NodeEntity.Level2NodeEntity.Level3NodeEntity -> {\n                // 三级 没有子node\n                return null\n            }\n\n            else -> return null\n        }\n    }\n\n    override fun isInitialOpen(position: Int, item: Any): Boolean {\n        // 哪些数据需要默认展开\n        if (item is NodeEntity) {\n            return item.title == \"Item 1\"\n        } else if (item is NodeEntity.Level2NodeEntity) {\n            // 二级\n            return item.title.startsWith(\"Item 1\", ignoreCase = true)\n        }\n        return false\n    }\n\n    override fun isSameNode(item1: Any, item2: Any): Boolean {\n        return when (item1) {\n            is NodeEntity if item2 is NodeEntity -> {\n                item1.title == item2.title\n            }\n\n            is NodeEntity.Level2NodeEntity if item2 is NodeEntity.Level2NodeEntity -> {\n                // 二级\n                item1.title == item2.title\n            }\n\n            is NodeEntity.Level2NodeEntity.Level3NodeEntity if item2 is NodeEntity.Level2NodeEntity.Level3NodeEntity -> {\n                // 三级\n                item1.title == item2.title\n            }\n\n            else -> {\n                false\n            }\n        }\n    }\n\n    override fun getItemViewType(position: Int, list: List<Any>): Int {\n        val item = list[position]\n        when (item) {\n            is NodeEntity -> {\n                // 一级\n                return 1\n            }\n\n            is NodeEntity.Level2NodeEntity -> {\n                // 二级\n                return 2\n            }\n\n            is NodeEntity.Level2NodeEntity.Level3NodeEntity -> {\n                // 三级\n                return 3\n            }\n\n            else -> return 0\n        }\n    }\n\n    override fun onCreateViewHolder(\n        context: Context, parent: ViewGroup, viewType: Int,\n    ): RecyclerView.ViewHolder {\n        return when (viewType) {\n            1 -> {\n                Level1Hodler(parent).apply {\n                    itemView.setOnClickListener {\n                        openOrClose(bindingAdapterPosition)\n                    }\n                }\n            }\n\n            2 -> {\n                Level2Hodler(parent).apply {\n                    itemView.setOnClickListener {\n                        openOrClose(bindingAdapterPosition)\n                    }\n                }\n            }\n\n            3 -> {\n                Level3Hodler(parent).apply {\n                    itemView.setOnClickListener {\n                        Toast.makeText(\n                            it.context,\n                            \"Level 3 _ index $bindingAdapterPosition\",\n                            Toast.LENGTH_SHORT\n                        ).show()\n                    }\n                }\n            }\n\n            else -> {\n                Level1Hodler(parent)\n            }\n        }\n    }\n\n    override fun onBindViewHolder(\n        holder: RecyclerView.ViewHolder, position: Int, item: Any?,\n    ) {\n        when (holder) {\n            is Level1Hodler -> {\n                // 一级\n                val nodeEntity = item as NodeEntity\n\n                holder.viewBinding.tvTitle.text = nodeEntity.title\n\n                // 设置箭头图标\n                if (nodeEntity.childNode.isNullOrEmpty()) {\n                    holder.viewBinding.ivArrow.setBackgroundResource(0)\n                } else {\n                    if (isOpened(item)) {\n                        holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_down)\n                    } else {\n                        holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_right)\n                    }\n                }\n            }\n\n            is Level2Hodler -> {\n                // 二级\n                val nodeEntity = item as NodeEntity.Level2NodeEntity\n                holder.viewBinding.tvTitle.text = nodeEntity.title\n\n                // 设置箭头图标\n                if (nodeEntity.childNode.isNullOrEmpty()) {\n                    holder.viewBinding.ivArrow.setBackgroundResource(0)\n                } else {\n                    if (isOpened(item)) {\n                        holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_down)\n                    } else {\n                        holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_right)\n                    }\n                }\n            }\n\n            is Level3Hodler -> {\n                // 三级\n                val nodeEntity = item as NodeEntity.Level2NodeEntity.Level3NodeEntity\n                holder.viewBinding.tvTitle.text = nodeEntity.title\n            }\n        }\n    }\n}\n\n\nclass Level1Hodler(\n    parent: ViewGroup,\n    val viewBinding: ItemNodeLevel1Binding = ItemNodeLevel1Binding.inflate(\n        LayoutInflater.from(parent.context), parent, false\n    ),\n) : RecyclerView.ViewHolder(viewBinding.root)\n\nclass Level2Hodler(\n    parent: ViewGroup,\n    val viewBinding: ItemNodeLevel2Binding = ItemNodeLevel2Binding.inflate(\n        LayoutInflater.from(parent.context), parent, false\n    ),\n) : RecyclerView.ViewHolder(viewBinding.root)\n\nclass Level3Hodler(\n    parent: ViewGroup,\n    val viewBinding: ItemNodeLevel3Binding = ItemNodeLevel3Binding.inflate(\n        LayoutInflater.from(parent.context), parent, false\n    ),\n) : RecyclerView.ViewHolder(viewBinding.root)"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/GroupDemoActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.scene\n\nimport android.graphics.drawable.ColorDrawable\nimport android.os.Bundle\nimport androidx.core.content.ContextCompat\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.ConcatAdapter\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.activity.scene.adapter.GroupAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.GroupDemoEntity\nimport com.squareup.moshi.JsonAdapter\nimport com.squareup.moshi.Moshi\nimport com.squareup.moshi.Types\nimport androidx.core.graphics.drawable.toDrawable\n\n\nclass GroupDemoActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {\n\n    // 创建一个 ConcatAdapter，用来包裹 GroupAdapter\n    private val concatAdapter = ConcatAdapter()\n\n\n    override fun initBinding(): ActivityUniversalRecyclerBinding =\n        ActivityUniversalRecyclerBinding.inflate(layoutInflater)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        window.setBackgroundDrawable(ContextCompat.getColor(this, R.color.bg).toDrawable())\n\n        viewBinding.titleBar.title = \"Group Scene（ConcatAdapter）\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n        viewBinding.rv.layoutManager = LinearLayoutManager(this)\n        viewBinding.rv.adapter = concatAdapter\n\n        /*\n        往常，我们获得这样一个 List 嵌套 List 的结构时，需要展平数据成一个 List<Any>，\n        然后用一个 Adapter 通过不同的ItemViewType 去做，非常繁琐，容易出错，而且不方便数据刷新\n\n        现在我们不需要去对数据做处理了，直接使用！\n         */\n        val list: List<GroupDemoEntity> = jsonToList()\n\n\n        // 循环 list，有多少个数组，就创建多少个 GroupAdapter，就这么简单\n        list.forEach {\n            val adapter = GroupAdapter()\n            adapter.submitList(it.groupList)\n\n            // 创建好以后，直接扔进 ConcatAdapter\n            concatAdapter.addAdapter(adapter)\n        }\n    }\n\n    /**\n     * 解析 Json，不用关注\n     */\n    private fun jsonToList(): List<GroupDemoEntity> {\n        val moshi = Moshi.Builder().build()\n        val type = Types.newParameterizedType(List::class.java, GroupDemoEntity::class.java)\n        val jsonAdapter: JsonAdapter<List<GroupDemoEntity>> = moshi.adapter(type)\n        return jsonAdapter.fromJson(JSON) ?: throw IllegalStateException(\"json 解析出错\")\n    }\n\n    companion object {\n        // 此种格式的json，在业务场景中比较常见\n        private const val JSON = \"\"\"\n[{\n\t\t\"group_name\": \"1\",\n\t\t\"group_list\": [{\n\t\t\t\t\"title\": \"patton\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"nicole\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"anthony\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\t\"group_name\": \"2\",\n\t\t\"group_list\": [{\n\t\t\t\t\"title\": \"zane\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"venus\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"yahya\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"starlight\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"twinkle\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\t\"group_name\": \"3\",\n\t\t\"group_list\": [{\n\t\t\t\t\"title\": \"esther\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"asta\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"gary\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\t\"group_name\": \"4\",\n\t\t\"group_list\": [{\n\t\t\t\t\"title\": \"peter\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"aldrich\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t}\n\t\t]\n\t},\n\t{\n\t\t\"group_name\": \"5\",\n\t\t\"group_list\": [{\n\t\t\t\t\"title\": \"edgar\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"danika\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"title\": \"clement\",\n\t\t\t\t\"content\": \"this is content\"\n\t\t\t}\n\t\t]\n\t}\n]\n        \"\"\"\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/adapter/GroupAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.scene.adapter\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.ViewGroup\nimport android.view.ViewGroup.MarginLayoutParams\nimport androidx.core.view.isVisible\nimport androidx.core.view.updateLayoutParams\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemGroupTypeBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.GroupDemoEntity\nimport com.chad.baserecyclerviewadapterhelper.utils.dp\nimport com.chad.library.adapter4.BaseQuickAdapter\n\n/**\n * 每一组的Adapter\n *\n */\nclass GroupAdapter : BaseQuickAdapter<GroupDemoEntity.Group, GroupAdapter.VH>(){\n\n    class VH(\n        parent: ViewGroup,\n        val binding: ItemGroupTypeBinding = ItemGroupTypeBinding.inflate(LayoutInflater.from(parent.context), parent ,false)\n    ):RecyclerView.ViewHolder(binding.root)\n\n    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {\n        return VH(parent)\n    }\n\n    override fun onBindViewHolder(holder: VH, position: Int, item: GroupDemoEntity.Group?) {\n        if (item == null) return\n\n        holder.binding.tvTitle.text = item.title\n        holder.binding.tvContent.text = item.content\n\n        holder.binding.lineView.isVisible = position > 0\n\n        when (position) {\n            0 -> {\n                // 第一个item，设置上圆角背景\n                holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_top_bg)\n\n                // 设置点间距\n                holder.binding.root.updateLayoutParams<MarginLayoutParams> {\n                    topMargin = 15.dp\n                }\n            }\n            items.size - 1 -> {\n                // 最后一个item，设置下圆角背景\n                holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_bottom_bg)\n            }\n            else -> {\n                // 其他的，没有圆角的背景\n                holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_mid_bg)\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/UpFetchUseActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.upfetch\n\nimport android.os.Bundle\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updatePadding\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport com.chad.baserecyclerviewadapterhelper.activity.upfetch.adapter.UpFetchAdapter\nimport com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity\nimport com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.Movie\nimport com.chad.library.adapter4.QuickAdapterHelper\nimport com.chad.library.adapter4.loadState.LoadState\nimport com.chad.library.adapter4.loadState.LoadState.NotLoading\nimport com.chad.library.adapter4.loadState.leading.LeadingLoadStateAdapter.OnLeadingListener\nimport java.util.*\n\n/**\n * @author limuyang\n * 2019-12-06\n */\nclass UpFetchUseActivity : BaseViewBindingActivity<ActivityUniversalRecyclerBinding>() {\n\n    private val mAdapter = UpFetchAdapter()\n    private lateinit var helper: QuickAdapterHelper\n\n    override fun initBinding(): ActivityUniversalRecyclerBinding =\n        ActivityUniversalRecyclerBinding.inflate(layoutInflater)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets ->\n            val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars())\n            viewBinding.titleBar.updateFakeBarHeight(bar.top)\n            insets\n        }\n\n        viewBinding.titleBar.title = \"UpFetch Use\"\n        viewBinding.titleBar.setOnBackListener { finish() }\n\n\n        viewBinding.rv.layoutManager = LinearLayoutManager(this)\n\n        helper = QuickAdapterHelper.Builder(mAdapter)\n            .setLeadingLoadStateAdapter(object : OnLeadingListener {\n                override fun onLoad() {\n                    requestUoFetch()\n                }\n\n                override fun isAllowLoading(): Boolean {\n                    return true\n                }\n            })\n            .setLeadPreloadSize(0) // 预加载（默认值为0）\n            .build()\n        viewBinding.rv.adapter = helper.adapter\n    }\n\n    override fun onStart() {\n        super.onStart()\n        requestUoFetch()\n    }\n\n    private var count = 0\n    private fun requestUoFetch() {\n        if (count == 0) {\n            count++\n            // 首次进入页面，设置数据\n            mAdapter.submitList(genData())\n            scrollToBottom()\n            helper.leadingLoadState = NotLoading(false)\n            return\n        }\n        count++\n\n        /**\n         * When starting to request data from the network, set the status to loading.\n         * 当开始网络请求数据的时候，设置状态为加载中\n         */\n        helper.leadingLoadState = LoadState.Loading\n\n        /*\n         * get data from internet.\n         * 从网络获取数据\n         */\n        viewBinding.rv.postDelayed({\n            mAdapter.addAll(0, genData())\n            if (count > 5) {\n                /*\n                 * Set the status to not loaded, and there is no paging data.\n                 * 设置状态为未加载，并且没有分页数据了\n                 */\n                helper.leadingLoadState = NotLoading(true)\n            } else {\n                /**\n                 * Set the state to not loaded, and there is also paginated data\n                 * 设置状态为未加载，并且还有分页数据\n                 */\n                helper.leadingLoadState = NotLoading(false)\n            }\n        }, 600)\n    }\n\n    /**\n     * 滚动到底部（不带动画）\n     */\n    private fun scrollToBottom() {\n        val ll = viewBinding.rv.layoutManager as LinearLayoutManager\n        ll.scrollToPositionWithOffset(bottomDataPosition, 0)\n    }\n\n    private val bottomDataPosition: Int\n        get() = mAdapter.items.size - 1\n\n    private fun genData(): List<Movie> {\n        val list = ArrayList<Movie>()\n        val random = Random()\n        for (i in 0..9) {\n            val name = \"Chad\"\n            val price = random.nextInt(10) + 10\n            val len = random.nextInt(80) + 60\n            val movie =\n                Movie(name, len, price, \"He was one of Australia's most distinguished artistes\")\n            list.add(movie)\n        }\n        return list\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/adapter/UpFetchAdapter.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.activity.upfetch.adapter\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.databinding.ItemHeaderAndFooterBinding\nimport com.chad.baserecyclerviewadapterhelper.entity.Movie\nimport com.chad.library.adapter4.BaseQuickAdapter\n\n/**\n * @author: limuyang\n * @date: 2019-12-06\n * @Description:\n */\nclass UpFetchAdapter : BaseQuickAdapter<Movie, UpFetchAdapter.VH>() {\n    class VH(\n        parent: ViewGroup,\n        val viewBinding: ItemHeaderAndFooterBinding = ItemHeaderAndFooterBinding.inflate(\n            LayoutInflater.from(parent.context), parent, false\n        )\n    ) : RecyclerView.ViewHolder(viewBinding.root)\n\n    override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {\n        return VH(parent)\n    }\n\n    override fun onBindViewHolder(holder: VH, position: Int, item: Movie?) {\n        when (holder.layoutPosition % 3) {\n            0 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img1)\n            1 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img2)\n            2 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img3)\n            else -> {}\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation1.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.animator;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorSet;\nimport android.animation.ObjectAnimator;\nimport android.view.View;\nimport android.view.animation.DecelerateInterpolator;\nimport com.chad.library.adapter4.animation.ItemAnimator;\nimport org.jetbrains.annotations.NotNull;\n\n/**\n * 自定义动画1\n */\npublic class CustomAnimation1 implements ItemAnimator {\n    @NotNull\n    @Override\n    public Animator animator(@NotNull View view) {\n        Animator alpha = ObjectAnimator.ofFloat(view, \"alpha\", 0, 1f);\n\n        Animator scaleY = ObjectAnimator.ofFloat(view, \"scaleY\", 1.3f, 1);\n        Animator scaleX = ObjectAnimator.ofFloat(view, \"scaleX\", 1.3f, 1);\n\n        scaleY.setInterpolator(new DecelerateInterpolator());\n        scaleX.setInterpolator(new DecelerateInterpolator());\n\n        AnimatorSet animatorSet = new AnimatorSet();\n        animatorSet.setDuration(350);\n        animatorSet.play(alpha).with(scaleX).with(scaleY);\n\n        return animatorSet;\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation2.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.animator;\n\nimport android.animation.Animator;\nimport android.animation.ObjectAnimator;\nimport android.view.View;\nimport android.view.animation.Interpolator;\n\nimport com.chad.library.adapter4.animation.ItemAnimator;\n\nimport org.jetbrains.annotations.NotNull;\n\nimport static java.lang.Math.PI;\nimport static java.lang.Math.pow;\nimport static java.lang.Math.sin;\n\n\n/**\n * 自定义动画2\n */\npublic class CustomAnimation2 implements ItemAnimator {\n    @NotNull\n    @Override\n    public Animator animator(@NotNull View view) {\n        Animator translationX =\n                ObjectAnimator.ofFloat(view, \"translationX\", -view.getRootView().getWidth(), 0f);\n\n        translationX.setDuration(800);\n        translationX.setInterpolator(new MyInterpolator2());\n\n        return translationX;\n    }\n\n    private static class MyInterpolator2 implements Interpolator {\n        @Override\n        public float getInterpolation(float input) {\n            float factor = 0.7f;\n            return (float) (pow(2.0, -10.0 * input) * sin((input - factor / 4) * (2 * PI) / factor) + 1);\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation3.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.animator;\n\nimport android.animation.Animator;\nimport android.animation.AnimatorSet;\nimport android.animation.ObjectAnimator;\nimport android.view.View;\nimport android.view.animation.DecelerateInterpolator;\n\nimport com.chad.library.adapter4.animation.ItemAnimator;\n\nimport org.jetbrains.annotations.NotNull;\n\npublic class CustomAnimation3 implements ItemAnimator {\n\n    @NotNull\n    @Override\n    public Animator animator(@NotNull View view) {\n        Animator alpha = ObjectAnimator.ofFloat(view, \"alpha\", 0, 1f);\n\n        Animator translationY =\n                ObjectAnimator.ofFloat(view, \"translationY\", view.getRootView().getHeight(), 0f);\n        translationY.setInterpolator(new DecelerateInterpolator(1.2f));\n\n        AnimatorSet animatorSet = new AnimatorSet();\n        animatorSet.setDuration(450);\n        animatorSet.play(alpha).with(translationY);\n\n        return animatorSet;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.base\n\nimport android.os.Build\nimport android.os.Bundle\nimport android.view.View\nimport androidx.activity.enableEdgeToEdge\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.core.content.ContextCompat\nimport androidx.core.view.ViewCompat\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.utils.statusBarLightMode\n\nabstract class BaseActivity(@LayoutRes layoutRes: Int = 0) : AppCompatActivity(layoutRes) {\n\n\n    protected open val contentView: View? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        enableEdgeToEdge()\n\n        contentView?.let {\n            setContentView(it)\n        }\n\n\n\n\n\n        window.statusBarColor = ContextCompat.getColor(this, R.color.spinner_bg)\n        window.statusBarLightMode = false\n\n\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseViewBindingActivity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.base\n\nimport android.view.View\nimport androidx.viewbinding.ViewBinding\n\nabstract class BaseViewBindingActivity<V : ViewBinding> : BaseActivity() {\n\n    private var _viewBinding: V? = null\n\n    protected val viewBinding: V\n        get() {\n            return _viewBinding ?: throw IllegalStateException(\n                \"Should be called initBinding()\"\n            )\n        }\n\n    /**\n     * 初始化 [viewBinding]\n     */\n    abstract fun initBinding(): V\n\n    final override val contentView: View\n        get() {\n            return initBinding().apply {\n                _viewBinding = this\n            }.root\n        }\n\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.data\n\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.entity.DiffEntity\nimport com.chad.baserecyclerviewadapterhelper.entity.NodeEntity\nimport com.chad.baserecyclerviewadapterhelper.entity.Status\n\n/**\n * https://github.com/CymChad/BaseRecyclerViewAdapterHelper\n */\nobject DataServer {\n    const val HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK =\n        \"https://avatars1.githubusercontent.com/u/7698209?v=3&s=460\"\n    const val CYM_CHAD = \"CymChad\"\n    const val CHAY_CHAN = \"ChayChan\"\n\n    fun getSampleData(lenth: Int): MutableList<Status> {\n        val list: MutableList<Status> = ArrayList()\n        for (i in 0 until lenth) {\n            val status = Status()\n            status.userName = \"Chad$i\"\n            status.createdAt = \"04/05/$i\"\n            status.isRetweet = i % 2 == 0\n\n\n            status.userAvatar = when (i % 3) {\n                0 -> R.mipmap.animation_img1\n                1 -> R.mipmap.animation_img2\n                else -> R.mipmap.animation_img3\n            }\n            status.text = \"BaseRecyclerViewAdpaterHelper https://www.recyclerview.org\"\n            list.add(status)\n        }\n        return list\n    }\n\n\n    val strData: List<String>\n        get() {\n            val list: MutableList<String> = ArrayList()\n            for (i in 0..19) {\n                var str = HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK\n                if (i % 2 == 0) {\n                    str = CYM_CHAD\n                }\n                list.add(str)\n            }\n            return list\n        }\n\n    @JvmStatic\n    val diffUtilDemoEntities: List<DiffEntity>\n        get() {\n            val list: MutableList<DiffEntity> = ArrayList()\n            for (i in 0..9) {\n                list.add(\n                    DiffEntity(\n                        i,\n                        \"Item $i\",\n                        \"This item $i content\",\n                        \"06-12\"\n                    )\n                )\n            }\n            return list\n        }\n\n\n    fun getNodeData(): List<NodeEntity> {\n        val list = ArrayList<NodeEntity>()\n        for (i in 0..9) {\n            val node = if (i % 2 == 0) {\n                NodeEntity(\"Item $i\", null)\n            } else {\n                val level2list = ArrayList<NodeEntity.Level2NodeEntity>()\n                for (n in 0..4) {\n                    val leve2Node = if (n % 2 != 0) {\n                        NodeEntity.Level2NodeEntity(\"Item ${i} - Level 2 - Index $n\", null)\n                    } else {\n                        val level3list = ArrayList<NodeEntity.Level2NodeEntity.Level3NodeEntity>()\n\n                        for (m in 0..4) {\n                            val level3Node =\n                                NodeEntity.Level2NodeEntity.Level3NodeEntity(\"Item${i} - Level2-index:${n} - Level 3 - Index $m\")\n                            level3list.add(level3Node)\n                        }\n\n                        NodeEntity.Level2NodeEntity(\"Item ${i} - Level 2 - Index $n with Child\", level3list)\n                    }\n                    level2list.add(leve2Node)\n                }\n\n                NodeEntity(\"Item $i\", level2list)\n            }\n            list.add(node)\n        }\n\n        return list\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridItemDecoration.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.decoration;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Rect;\nimport android.graphics.drawable.Drawable;\nimport android.view.View;\n\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\n/**\n * https://github.com/CymChad/BaseRecyclerViewAdapterHelper\n */\npublic class GridItemDecoration extends RecyclerView.ItemDecoration {\n\n    private Drawable dividerDrawable;\n    private int orientation = LinearLayoutManager.VERTICAL;\n\n    public GridItemDecoration(Drawable divider) {\n        dividerDrawable = divider;\n    }\n\n    public GridItemDecoration(Context context, int resId) {\n        dividerDrawable = context.getResources().getDrawable(resId);\n    }\n\n    public GridItemDecoration(Context context, int resId, int orientation) {\n        dividerDrawable = context.getResources().getDrawable(resId);\n        this.orientation = orientation;\n    }\n\n    @Override\n    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {\n        if (dividerDrawable == null) {\n            return;\n        }\n\n        if (parent.getChildLayoutPosition(view) < 1) {\n            return;\n        }\n\n        if (orientation == LinearLayoutManager.VERTICAL) {\n            outRect.top = dividerDrawable.getIntrinsicHeight();\n        } else if (orientation == LinearLayoutManager.HORIZONTAL) {\n            outRect.left = dividerDrawable.getIntrinsicWidth();\n        }\n    }\n\n    /**\n     * @param c\n     * @param parent\n     * @param state\n     */\n    @Override\n    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {\n        if (dividerDrawable == null) {\n            return;\n        }\n\n        int childCount = parent.getChildCount();\n        int rightV = parent.getWidth();\n        for (int i = 0; i < childCount; i++) {\n            View child = parent.getChildAt(i);\n            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();\n\n            int leftV = parent.getPaddingLeft() + child.getPaddingLeft();\n            int bottomV = child.getTop() - params.topMargin;\n            int topV = bottomV - dividerDrawable.getIntrinsicHeight();\n\n            int topH = child.getTop() + params.topMargin;\n            int bottomH = child.getBottom() + params.bottomMargin;\n            int rightH = child.getLeft() - params.leftMargin;\n            int leftH = rightH - dividerDrawable.getIntrinsicWidth();\n            dividerDrawable.setBounds(leftH, topH, rightH, bottomH);\n            dividerDrawable.draw(c);\n            dividerDrawable.setBounds(leftV, topV, rightV, bottomV);\n            dividerDrawable.draw(c);\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridSectionAverageGapItemDecoration.java",
    "content": "//package com.chad.baserecyclerviewadapterhelper.decoration;\n//\n//import android.graphics.Rect;\n//import android.os.Build;\n//import android.util.DisplayMetrics;\n//import android.util.TypedValue;\n//import android.view.View;\n//\n//import androidx.annotation.Nullable;\n//import androidx.recyclerview.widget.GridLayoutManager;\n//import androidx.recyclerview.widget.RecyclerView;\n//\n//import com.chad.library.adapter.base.BaseSectionQuickAdapter;\n//import com.chad.library.adapter.base.viewholder.BaseViewHolder;\n//import com.chad.library.adapter.base.entity.SectionEntity;\n//\n//import java.util.ArrayList;\n//import java.util.List;\n//\n///**\n// * 应用于RecyclerView的GridLayoutManager，水平方向上固定间距大小，从而使条目宽度自适应。<br>\n// * 配合Brvah的Section使用，不对Head生效，仅对每个Head的子Grid列表生效<br>\n// * Section Grid中Item的宽度应设为MATCH_PARAENT\n// *\n// * @author : renpeng\n// * @since : 2018/9/29\n// */\n//public class GridSectionAverageGapItemDecoration extends RecyclerView.ItemDecoration {\n//\n//    private class Section {\n//        public int startPos = 0;\n//        public int endPos = 0;\n//\n//        public int getCount() {\n//            return endPos - startPos + 1;\n//        }\n//\n//        public boolean contains(int pos) {\n//            return pos >= startPos && pos <= endPos;\n//        }\n//\n//        @Override\n//        public String toString() {\n//            return \"Section{\" +\n//                    \"startPos=\" + startPos +\n//                    \", endPos=\" + endPos +\n//                    '}';\n//        }\n//    }\n//\n//    private float                            gapHorizontalDp;\n//    private float                            gapVerticalDp;\n//    private float                            sectionEdgeHPaddingDp;\n//    private float                            sectionEdgeVPaddingDp;\n//    private int                              gapHSizePx = -1;\n//    private int                              gapVSizePx = -1;\n//    private int                              sectionEdgeHPaddingPx;\n//    private int                              eachItemHPaddingPx; //每个条目应该在水平方向上加的padding 总大小，即=paddingLeft+paddingRight\n//    private int                              sectionEdgeVPaddingPx;\n//    private List<Section>                    mSectionList = new ArrayList<>();\n//    private BaseSectionQuickAdapter          mAdapter;\n//    private RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() {\n//        @Override\n//        public void onChanged() {\n//            markSections();\n//        }\n//\n//        @Override\n//        public void onItemRangeChanged(int positionStart, int itemCount) {\n//            markSections();\n//        }\n//\n//        @Override\n//        public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {\n//            markSections();\n//        }\n//\n//        @Override\n//        public void onItemRangeInserted(int positionStart, int itemCount) {\n//            markSections();\n//        }\n//\n//        @Override\n//        public void onItemRangeRemoved(int positionStart, int itemCount) {\n//            markSections();\n//        }\n//\n//        @Override\n//        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {\n//            markSections();\n//        }\n//    };\n//\n//\n//    /**\n//     * @param gapHorizontalDp       item之间的水平间距\n//     * @param gapVerticalDp         item之间的垂直间距\n//     * @param sectionEdgeHPaddingDp section左右两端的padding大小\n//     * @param sectionEdgeVPaddingDp section上下两端的padding大小\n//     */\n//    public GridSectionAverageGapItemDecoration(float gapHorizontalDp, float gapVerticalDp, float sectionEdgeHPaddingDp, float sectionEdgeVPaddingDp) {\n//        this.gapHorizontalDp = gapHorizontalDp;\n//        this.gapVerticalDp = gapVerticalDp;\n//        this.sectionEdgeHPaddingDp = sectionEdgeHPaddingDp;\n//        this.sectionEdgeVPaddingDp = sectionEdgeVPaddingDp;\n//    }\n//\n//    @Override\n//    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {\n//        if (parent.getLayoutManager() instanceof GridLayoutManager && parent.getAdapter() instanceof BaseSectionQuickAdapter) {\n//            GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();\n//            BaseSectionQuickAdapter<SectionEntity, BaseViewHolder> adapter = (BaseSectionQuickAdapter) parent.getAdapter();\n//            if (mAdapter != adapter) {\n//                setUpWithAdapter(adapter);\n//            }\n//            int spanCount = layoutManager.getSpanCount();\n//            int position = parent.getChildAdapterPosition(view);\n//            SectionEntity entity = adapter.getItem(position);\n//\n//            if (entity == null || entity.isHeader()) {\n//                //不处理header\n//                outRect.set(0, 0, 0, 0);\n////                Log.w(\"GridAverageGapItem\", \"pos=\" + position + \",\" + outRect.toShortString());\n//                return;\n//            }\n//\n//            Section section = findSectionLastItemPos(position);\n//\n//            if (gapHSizePx < 0 || gapVSizePx < 0) {\n//                transformGapDefinition(parent, spanCount);\n//            }\n//            outRect.top = gapVSizePx;\n//            outRect.bottom = 0;\n//\n//            //下面的visualPos为单个Section内的视觉Pos\n//            int visualPos = position + 1 - section.startPos;\n//            if (visualPos % spanCount == 1) {\n//                //第一列\n//                outRect.left = sectionEdgeHPaddingPx;\n//                outRect.right = eachItemHPaddingPx - sectionEdgeHPaddingPx;\n//            } else if (visualPos % spanCount == 0) {\n//                //最后一列\n//                outRect.left = eachItemHPaddingPx - sectionEdgeHPaddingPx;\n//                outRect.right = sectionEdgeHPaddingPx;\n//            } else {\n//                outRect.left = gapHSizePx - (eachItemHPaddingPx - sectionEdgeHPaddingPx);\n//                outRect.right = eachItemHPaddingPx - outRect.left;\n//            }\n//\n//            if (visualPos - spanCount <= 0) {\n//                //第一行\n//                outRect.top = sectionEdgeVPaddingPx;\n//            }\n//\n//            if (isLastRow(visualPos, spanCount, section.getCount())) {\n//                //最后一行\n//                outRect.bottom = sectionEdgeVPaddingPx;\n////                Log.w(\"GridAverageGapItem\", \"last row pos=\" + position);\n//            }\n////            Log.w(\"GridAverageGapItem\", \"pos=\" + position + \",vPos=\" + visualPos + \",\" + outRect.toShortString());\n//        } else {\n//            super.getItemOffsets(outRect, view, parent, state);\n//        }\n//    }\n//\n//    private void setUpWithAdapter(BaseSectionQuickAdapter<SectionEntity, BaseViewHolder> adapter) {\n//        if (mAdapter != null) {\n//            mAdapter.unregisterAdapterDataObserver(mDataObserver);\n//        }\n//        mAdapter = adapter;\n//        mAdapter.registerAdapterDataObserver(mDataObserver);\n//        markSections();\n//    }\n//\n//    private void markSections() {\n//        if (mAdapter != null) {\n//            BaseSectionQuickAdapter<SectionEntity, BaseViewHolder> adapter = mAdapter;\n//            mSectionList.clear();\n//            SectionEntity sectionEntity = null;\n//            Section section = new Section();\n//            for (int i = 0, size = adapter.getItemCount(); i < size; i++) {\n//                sectionEntity = adapter.getItem(i);\n//                if (sectionEntity != null && sectionEntity.isHeader()) {\n//                    //找到新Section起点\n//                    if (section != null && i != 0) {\n//                        //已经有待添加的section\n//                        section.endPos = i - 1;\n//                        mSectionList.add(section);\n//                    }\n//                    section = new Section();\n//                    section.startPos = i + 1;\n//                } else {\n//                    section.endPos = i;\n//                }\n//            }\n//            //处理末尾情况\n//            if (!mSectionList.contains(section)) {\n//                mSectionList.add(section);\n//            }\n//\n////            Log.w(\"GridAverageGapItem\", \"section list=\" + mSectionList);\n//        }\n//    }\n//\n//    private void transformGapDefinition(RecyclerView parent, int spanCount) {\n//        DisplayMetrics displayMetrics = new DisplayMetrics();\n//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {\n//            parent.getDisplay().getMetrics(displayMetrics);\n//        }\n//        gapHSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapHorizontalDp, displayMetrics);\n//        gapVSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapVerticalDp, displayMetrics);\n//        sectionEdgeHPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeHPaddingDp, displayMetrics);\n//        sectionEdgeVPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeVPaddingDp, displayMetrics);\n//        eachItemHPaddingPx = (sectionEdgeHPaddingPx * 2 + gapHSizePx * (spanCount - 1)) / spanCount;\n//    }\n//\n//    private Section findSectionLastItemPos(int curPos) {\n//        for (Section section : mSectionList) {\n//            if (section.contains(curPos)) {\n//                return section;\n//            }\n//        }\n//        return null;\n//    }\n//\n//    private boolean isLastRow(int visualPos, int spanCount, int sectionItemCount) {\n//        int lastRowCount = sectionItemCount % spanCount;\n//        lastRowCount = lastRowCount == 0 ? spanCount : lastRowCount;\n//        return visualPos > sectionItemCount - lastRowCount;\n//    }\n//}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/ClickEntity.java",
    "content": "/*\n******************************* Copyright (c)*********************************\\\n**\n**                 (c) Copyright 2015, Allen, china, shanghai\n**                          All Rights Reserved\n**\n**                          \n**                         \n**-----------------------------------版本信息------------------------------------\n** 版    本: V0.1\n**\n**------------------------------------------------------------------------------\n********************************End of Head************************************\\\n*/\npackage com.chad.baserecyclerviewadapterhelper.entity;\n\n/**\n * 文 件 名: ClickEntity\n * 创 建 人: Allen\n * 创建日期: 16/11/1 22:16\n * 邮   箱: AllenCoder@126.com\n * 修改时间：\n * 修改备注：\n */\npublic class ClickEntity {\n    public static final int CLICK_ITEM_VIEW = 1;\n    public static final int CLICK_ITEM_CHILD_VIEW = 2;\n    public static final int LONG_CLICK_ITEM_VIEW = 3;\n    public static final int LONG_CLICK_ITEM_CHILD_VIEW = 4;\n    private final int type;\n\n    public ClickEntity(final int type) {\n        this.type = type;\n    }\n\n    public int getItemType() {\n        return type;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/DiffEntity.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.entity;\n\nimport java.util.Objects;\n\npublic class DiffEntity {\n\n    private int id;\n    private String title;\n    private String content;\n    private String date;\n\n    public DiffEntity(int id, String title, String content, String date) {\n        this.id = id;\n        this.title = title;\n        this.content = content;\n        this.date = date;\n    }\n\n    public int getId() {\n        return id;\n    }\n\n    public void setId(int id) {\n        this.id = id;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    public void setTitle(String title) {\n        this.title = title;\n    }\n\n    public String getContent() {\n        return content;\n    }\n\n    public void setContent(String content) {\n        this.content = content;\n    }\n\n    public String getDate() {\n        return date;\n    }\n\n    public void setDate(String date) {\n        this.date = date;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (!(o instanceof DiffEntity)) return false;\n        DiffEntity that = (DiffEntity) o;\n        return id == that.id && Objects.equals(title, that.title) && Objects.equals(content, that.content) && Objects.equals(date, that.date);\n    }\n\n    @Override\n    public int hashCode() {\n        return Objects.hash(id, title, content, date);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/GroupDemoEntity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.entity\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@JsonClass(generateAdapter = true)\ndata class GroupDemoEntity(\n    @Json(name = \"group_name\")\n    val groupName: String,\n    @Json(name = \"group_list\")\n    val groupList: List<Group>,\n) {\n\n    @JsonClass(generateAdapter = true)\n    data class Group(\n        @Json(name = \"title\")\n        val title: String,\n        @Json(name = \"content\")\n        val content: String,\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeEntity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.entity\n\n/**\n * @author: limuyang\n * @date: 2019-12-06\n * @Description:\n */\ndata class HomeEntity(\n    val name: String = \"\",\n    val activity: Class<*>? = null,\n    val imageResource: Int = 0,\n    val sectionTitle: String = \"\"\n) {\n    val isSection: Boolean\n        get() = sectionTitle.isNotBlank()\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Movie.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.entity;\n\n/**\n * Created by luoxiongwen on 16/10/24.\n */\n\npublic class Movie {\n\n    public String name;\n    public int length;\n    public int price;\n    public String content;\n\n    public Movie(String name, int length, int price, String content) {\n        this.length = length;\n        this.name = name;\n        this.price = price;\n        this.content=content;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MoviePresenter.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.entity;\n\nimport android.view.View;\n\nimport com.chad.baserecyclerviewadapterhelper.utils.Tips;\n\n/**\n * Created by luoxiongwen on 16/10/24.\n */\n\npublic class MoviePresenter {\n    public void buyTicket(View view, Movie movie) {\n        Tips.show(\"buy ticket: \" + movie.name);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/NodeEntity.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.entity\n\n/**\n * @author LiMuYang\n * @date 2025/9/5\n * @description\n */\ndata class NodeEntity(\n    val title: String,\n    val childNode: List<Level2NodeEntity>?,\n) {\n\n    data class Level2NodeEntity(\n        val title: String,\n        val childNode: List<Level3NodeEntity>?,\n    ) {\n\n        data class Level3NodeEntity(\n            val title: String,\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Status.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.entity;\n\n/**\n * https://github.com/CymChad/BaseRecyclerViewAdapterHelper\n */\npublic class Status {\n    private boolean isRetweet;\n    private String text;\n    private String userName;\n    private int userAvatar;\n    private String createdAt;\n\n    public boolean isRetweet() {\n        return isRetweet;\n    }\n\n    public void setRetweet(boolean retweet) {\n        isRetweet = retweet;\n    }\n\n    public String getText() {\n        return text;\n    }\n\n    public void setText(String text) {\n        this.text = text;\n    }\n\n    public String getUserName() {\n        return userName;\n    }\n\n    public void setUserName(String userName) {\n        this.userName = userName;\n    }\n\n    public int getUserAvatar() {\n        return userAvatar;\n    }\n\n    public void setUserAvatar(int userAvatar) {\n        this.userAvatar = userAvatar;\n    }\n\n    public String getCreatedAt() {\n        return createdAt;\n    }\n\n    public void setCreatedAt(String createdAt) {\n        this.createdAt = createdAt;\n    }\n\n    @Override\n    public String toString() {\n        return \"Status{\" +\n                \"isRetweet=\" + isRetweet +\n                \", text='\" + text + '\\'' +\n                \", userName='\" + userName + '\\'' +\n                \", userAvatar='\" + userAvatar + '\\'' +\n                \", createdAt='\" + createdAt + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/AppUtils.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.utils\n\nimport android.app.Application\n\nobject AppUtils {\n    private lateinit var mApplication: Application\n\n    val app: Application get() = mApplication\n\n    fun init(application: Application) {\n        mApplication = application\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/ClickableMovementMethod.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.utils;\n\nimport android.text.Layout;\nimport android.text.Selection;\nimport android.text.Spannable;\nimport android.text.method.BaseMovementMethod;\nimport android.text.style.ClickableSpan;\nimport android.view.MotionEvent;\nimport android.widget.TextView;\n\npublic class ClickableMovementMethod extends BaseMovementMethod {\n\n    private static ClickableMovementMethod sInstance;\n\n    public static ClickableMovementMethod getInstance() {\n        if (sInstance == null) {\n            sInstance = new ClickableMovementMethod();\n        }\n        return sInstance;\n    }\n\n    @Override\n    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {\n\n        int action = event.getActionMasked();\n        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {\n\n            int x = (int) event.getX();\n            int y = (int) event.getY();\n            x -= widget.getTotalPaddingLeft();\n            y -= widget.getTotalPaddingTop();\n            x += widget.getScrollX();\n            y += widget.getScrollY();\n\n            Layout layout = widget.getLayout();\n            int line = layout.getLineForVertical(y);\n            int off = layout.getOffsetForHorizontal(line, x);\n\n            ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);\n            if (link.length > 0) {\n                if (action == MotionEvent.ACTION_UP) {\n                    link[0].onClick(widget);\n                } else {\n                    Selection.setSelection(buffer, buffer.getSpanStart(link[0]),\n                            buffer.getSpanEnd(link[0]));\n                }\n                return true;\n            } else {\n                Selection.removeSelection(buffer);\n            }\n        }\n\n        return false;\n    }\n\n    @Override\n    public void initialize(TextView widget, Spannable text) {\n        Selection.removeSelection(text);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/Ext.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.utils\n\nimport android.view.Window\nimport androidx.core.view.WindowCompat\n\n\n/**\n * 设置状态栏高亮模式\n */\ninline var Window.statusBarLightMode: Boolean\n    set(value) {\n        WindowCompat.getInsetsController(this, decorView).isAppearanceLightStatusBars = value\n    }\n    get() {\n        return WindowCompat.getInsetsController(this, decorView).isAppearanceLightStatusBars\n    }\n\n\n/**\n * dp 转 px\n */\ninline val Int.dp: Int\n    get() {\n        return (this * AppUtils.app.resources.displayMetrics.density + 0.5f).toInt()\n    }"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/Tips.java",
    "content": "package com.chad.baserecyclerviewadapterhelper.utils;\n\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.drawable.ShapeDrawable;\nimport android.graphics.drawable.shapes.RoundRectShape;\nimport android.view.Gravity;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.FrameLayout;\nimport android.widget.TextView;\nimport android.widget.Toast;\n\npublic class Tips {\n\n    /**\n     * 显示 Toast\n     * @param message 提示信息\n     */\n    public static void show(String message) {\n        show(message, Toast.LENGTH_SHORT);\n    }\n\n    /**\n     * 显示 Toast\n     * @param message 提示信息\n     * @param duration 显示时间长短\n     */\n    public static void show(String message, int duration) {\n        Toast toast = new Toast(AppUtils.INSTANCE.getApp());\n        toast.setDuration(duration);\n        toast.setGravity(Gravity.CENTER, 0, 0);\n        toast.setView(createTextToastView(message));\n        toast.show();\n    }\n\n    /**\n     * 创建自定义 Toast View\n     *\n     * @param message 文本消息\n     * @return View\n     */\n    private static View createTextToastView(String message) {\n        // 画圆角矩形背景\n        float rc = dp2px(6);\n        RoundRectShape shape = new RoundRectShape(new float[]{rc, rc, rc, rc, rc, rc, rc, rc}, null, null);\n        ShapeDrawable drawable = new ShapeDrawable(shape);\n        drawable.getPaint().setColor(Color.argb(225, 240, 240, 240));\n        drawable.getPaint().setStyle(Paint.Style.FILL);\n        drawable.getPaint().setAntiAlias(true);\n        drawable.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);\n\n        // 创建View\n        FrameLayout layout = new FrameLayout(AppUtils.INSTANCE.getApp());\n        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);\n        layout.setLayoutParams(layoutParams);\n        layout.setPadding(dp2px(16), dp2px(12), dp2px(16), dp2px(12));\n        layout.setBackground(drawable);\n\n        TextView textView = new TextView(AppUtils.INSTANCE.getApp());\n        textView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));\n        textView.setTextSize(15);\n        textView.setText(message);\n        textView.setLineSpacing(dp2px(4), 1f);\n        textView.setTextColor(Color.BLACK);\n\n        layout.addView(textView);\n\n        return layout;\n    }\n\n    private static int dp2px(float dpValue) {\n        final float scale = AppUtils.INSTANCE.getApp().getResources().getDisplayMetrics().density;\n        return (int) (dpValue * scale + 0.5f);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/VibratorUtils.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.utils\n\nimport android.app.Service\nimport android.content.Context\nimport android.os.Build\nimport android.os.VibrationEffect\nimport android.os.Vibrator\nimport android.os.VibratorManager\n\n/**\n * 震动\n */\nfun Context.vibrate() {\n    if (Build.VERSION.SDK_INT >= 31) {\n        // android 12 及以上使用新的 VibratorManager，创建 EFFECT_TICK 轻微震动（需要线性震动马达硬件支持）\n        val manager: VibratorManager =\n            getSystemService(VibratorManager::class.java)\n        manager.defaultVibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))\n    } else if (Build.VERSION.SDK_INT >= 29) {\n        // android 10 及以上使用原 Vibrator，创建 EFFECT_TICK 轻微震动（需要线性震动马达硬件支持）\n        val vib = getSystemService(Vibrator::class.java) as Vibrator\n        vib.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))\n    } else {\n        // 10 以下的系统，没有系统 API 驱动线性震动马达，只能创建普通震动\n        val vib = getSystemService(Service.VIBRATOR_SERVICE) as Vibrator //震动70毫秒\n        vib.vibrate(70)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/chad/baserecyclerviewadapterhelper/widget/BRVAHToolbar.kt",
    "content": "package com.chad.baserecyclerviewadapterhelper.widget\n\nimport android.content.Context\nimport android.os.Build\nimport android.util.AttributeSet\nimport android.view.LayoutInflater\nimport android.widget.LinearLayout\nimport android.widget.RelativeLayout\nimport androidx.core.content.ContextCompat\nimport androidx.core.view.updateLayoutParams\nimport androidx.core.view.updatePadding\nimport com.chad.baserecyclerviewadapterhelper.R\nimport com.chad.baserecyclerviewadapterhelper.databinding.LayoutToolBarBinding\n\nclass BRVAHToolbar @JvmOverloads constructor(\n    context: Context,\n    attrs: AttributeSet? = null,\n    defStyleAttr: Int = 0\n) : LinearLayout(context, attrs, defStyleAttr) {\n\n    private val binding = LayoutToolBarBinding.inflate(LayoutInflater.from(context), this)\n\n    var title: String?\n        get() = binding.tvTitle.text.toString()\n        set(value) {\n            binding.tvTitle.text = value\n        }\n\n    init {\n        orientation = VERTICAL\n        setBackgroundColor(ContextCompat.getColor(context, R.color.spinner_bg))\n        elevation = context.dpF(10)\n    }\n\n\n    fun updateFakeBarHeight(h: Int) {\n        binding.fakeBar.updateLayoutParams { this.height = h }\n    }\n\n    fun setOnBackListener(listener: OnClickListener) {\n        binding.ivBack.setOnClickListener(listener)\n    }\n\n    private companion object {\n        fun Context.dp(value: Int): Int {\n            return (value * this.resources.displayMetrics.density + 0.5f).toInt()\n        }\n\n        fun Context.dpF(value: Int): Float {\n            return value * this.resources.displayMetrics.density + 0.5f\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/res/anim/item_animation_from_bottom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:duration=\"400\">\n    <translate\n        android:fromYDelta=\"50%p\"\n        android:interpolator=\"@android:anim/accelerate_decelerate_interpolator\"\n        android:toYDelta=\"0\" />\n    <alpha\n        android:fromAlpha=\"0\"\n        android:interpolator=\"@android:anim/accelerate_decelerate_interpolator\"\n        android:toAlpha=\"1\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/layout_animation_from_bottom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layoutAnimation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:animation=\"@anim/item_animation_from_bottom\"\n    android:animationOrder=\"normal\"\n    android:delay=\"15%\" />"
  },
  {
    "path": "app/src/main/res/drawable/actionbar_bottom_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android = \"http://schemas.android.com/apk/res/android\" >\n\n    <!-- 红色背景 -->\n    <item>\n        <color android:color=\"@color/spinner_bg\" />\n    </item>\n    <!-- 白色背景 -->\n    <item android:bottom=\"1px\" android:drawable=\"@color/spinner_bg\" />\n</layer-list >\n"
  },
  {
    "path": "app/src/main/res/drawable/brvah_sample_footer_loading_progress.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item>\n        <rotate\n            android:drawable=\"@drawable/brvah_sample_footer_loading\"\n            android:duration=\"500\"\n            android:fromDegrees=\"0.0\"\n            android:pivotX=\"50.0%\"\n            android:pivotY=\"50.0%\"\n            android:toDegrees=\"360.0\" />\n    </item>\n\n</layer-list>"
  },
  {
    "path": "app/src/main/res/drawable/custom_text_state_color.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\t<item android:color=\"#ffffff\" android:state_checked=\"true\"/>\n\t<item android:color=\"@color/gray_color\" android:state_checked=\"false\"/>\n</selector>\n"
  },
  {
    "path": "app/src/main/res/drawable/gv_up_fetch.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<rotate xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:drawable=\"@drawable/gv_animation\"\n    android:fromDegrees=\"180\"\n    android:toDegrees=\"180\"\n    android:pivotX=\"50%\"\n    android:pivotY=\"50%\">\n\n</rotate>"
  },
  {
    "path": "app/src/main/res/drawable/ic_node_down.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"48dp\"\n    android:height=\"48dp\"\n    android:viewportWidth=\"1024\"\n    android:viewportHeight=\"1024\">\n  <path\n      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\"\n      android:fillColor=\"#444444\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_node_right.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"48dp\"\n    android:height=\"48dp\"\n    android:viewportWidth=\"1024\"\n    android:viewportHeight=\"1024\">\n  <path\n      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\"\n      android:fillColor=\"#444444\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/selector_item_child.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:drawable=\"@android:color/holo_orange_light\" android:state_pressed=\"true\" />\n    <item android:drawable=\"@android:color/holo_red_light\" android:state_pressed=\"true\"/>\n    <item android:state_active=\"false\">\n        <shape android:shape=\"rectangle\">\n            <corners android:radius=\"4dp\"/>\n            <solid android:color=\"@color/item_bg\"/>\n            <stroke android:color=\"@color/color_light_blue\" android:width=\"1dp\"/>\n        </shape>\n    </item>\n</selector>\n"
  },
  {
    "path": "app/src/main/res/drawable/shape_right_top_float_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <solid android:color=\"@color/bg\" />\n    <corners android:bottomLeftRadius=\"16dp\" />\n\n    <stroke\n        android:width=\"2dp\"\n        android:color=\"@color/colorPrimary\" />\n\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/thumb_drawable.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\t<item android:state_enabled=\"false\" android:state_checked=\"true\">\n\t\t<shape android:shape=\"oval\">\n\t\t\t<solid android:color=\"#E1E1E1\"/>\n\t\t\t<stroke\n\t\t\t\tandroid:width=\"1px\"\n\t\t\t\tandroid:color=\"#ECECEC\"/>\n\t\t</shape>\n\t</item>\n\t<item android:state_enabled=\"false\">\n\t\t<shape android:shape=\"oval\">\n\t\t\t<solid android:color=\"#555771\"/>\n\t\t\t<stroke\n\t\t\t\tandroid:width=\"1px\"\n\t\t\t\tandroid:color=\"#55577E\"/>\n\t\t</shape>\n\t</item>\n\t<item android:state_checked=\"true\">\n\t\t<shape android:shape=\"oval\">\n\t\t\t<solid android:color=\"#E1E1E1\"/>\n\t\t\t<stroke\n\t\t\t\tandroid:width=\"1px\"\n\t\t\t\tandroid:color=\"#D0D0D0\"/>\n\t\t</shape>\n\t</item>\n\t<item>\n\t\t<shape android:shape=\"oval\">\n\t\t\t<solid android:color=\"#555771\"/>\n\t\t\t<stroke\n\t\t\t\tandroid:width=\"1px\"\n\t\t\t\tandroid:color=\"#55577E\"/>\n\t\t</shape>\n\t</item>\n</selector>\n"
  },
  {
    "path": "app/src/main/res/drawable/touch_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:drawable=\"@color/gray_color\" android:state_pressed=\"true\"/>\n    <item android:drawable=\"@color/gray_color\" android:state_focused=\"true\"/>\n    <item android:drawable=\"@color/item_bg\"/>\n</selector>\n"
  },
  {
    "path": "app/src/main/res/drawable-v21/touch_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:color=\"@color/gray_color\">\n    <item android:id=\"@android:id/mask\"\n          android:drawable=\"@android:color/white\" />\n    <item>\n        <shape android:shape=\"rectangle\" >\n            <corners android:radius=\"@dimen/dp_4\"/>\n            <solid android:color=\"@color/item_bg\"/>\n            <stroke android:color=\"@color/gray_color\" android:width=\"1px\"/>\n        </shape>\n    </item>\n</ripple>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_animation_use.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    style=\"@style/bg\">\n\n    <com.chad.baserecyclerviewadapterhelper.widget.BRVAHToolbar\n        android:id=\"@+id/title_bar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"48dp\"\n        android:background=\"@color/spinner_bg\"\n        android:gravity=\"center\"\n        android:orientation=\"horizontal\"\n        android:paddingLeft=\"@dimen/dp_10\"\n        android:paddingRight=\"@dimen/dp_10\">\n\n\n        <com.jaredrummler.materialspinner.MaterialSpinner\n            android:id=\"@+id/spinner\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_weight=\"1\"\n            android:background=\"@null\"\n            app:ms_background_color=\"@color/spinner_bg\"\n            app:ms_hide_arrow=\"false\"\n            app:ms_text_color=\"#ffffff\" />\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            android:background=\"@color/spinner_bg\"\n            android:gravity=\"center|right\">\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"IsFirstOnly\"\n                android:textColor=\"@color/new_text_color\"\n                android:textSize=\"16sp\" />\n\n            <com.kyleduo.switchbutton.SwitchButton\n                android:id=\"@+id/switch_button\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginLeft=\"12dp\"\n                android:textColor=\"@drawable/custom_text_state_color\"\n                app:kswTextOff=\"false\"\n                app:kswTextOn=\"true\"\n                app:kswThumbColor=\"#555771\"\n                app:kswThumbDrawable=\"@drawable/thumb_drawable\"\n                app:kswTintColor=\"#00ddB6\" />\n\n        </LinearLayout>\n    </LinearLayout>\n\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/rv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:fadingEdge=\"none\"\n        app:layoutManager=\"androidx.recyclerview.widget.LinearLayoutManager\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_choose_multiple_item_use_type.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.core.widget.NestedScrollView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:gravity=\"center_vertical\"\n        android:orientation=\"vertical\">\n\n        <androidx.cardview.widget.CardView\n            android:id=\"@+id/card_view0\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:layout_marginLeft=\"5dp\"\n            android:layout_marginTop=\"20dp\"\n            android:layout_marginRight=\"5dp\"\n            android:foreground=\"?android:attr/selectableItemBackground\"\n            card_view:cardBackgroundColor=\"@color/item_bg\"\n            card_view:cardCornerRadius=\"4dp\"\n            card_view:cardElevation=\"2dp\"\n            card_view:cardUseCompatPadding=\"true\">\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:orientation=\"vertical\">\n\n                <ImageView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:scaleType=\"centerCrop\"\n                    android:src=\"@mipmap/animation_img1\" />\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"\n                    android:gravity=\"center\"\n                    android:text=\"BaseBinderAdapter\"\n                    android:textColor=\"@android:color/black\"\n                    android:textSize=\"18sp\"\n                    android:textStyle=\"bold\" />\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"\n                    android:layout_marginTop=\"8dp\"\n                    android:gravity=\"center\"\n                    android:text=\"更高灵活度，推荐优先使用\"\n                    android:textColor=\"@android:color/black\"\n                    android:textSize=\"16sp\" />\n\n            </LinearLayout>\n\n        </androidx.cardview.widget.CardView>\n\n        <androidx.cardview.widget.CardView\n            android:id=\"@+id/card_view1\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"150dp\"\n            android:layout_gravity=\"center\"\n            android:layout_marginLeft=\"5dp\"\n            android:layout_marginTop=\"20dp\"\n            android:layout_marginRight=\"5dp\"\n            android:foreground=\"?android:attr/selectableItemBackground\"\n            card_view:cardBackgroundColor=\"@color/item_bg\"\n            card_view:cardCornerRadius=\"4dp\"\n            card_view:cardElevation=\"2dp\"\n            card_view:cardUseCompatPadding=\"true\">\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:orientation=\"vertical\">\n\n                <ImageView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:scaleType=\"centerCrop\"\n                    android:src=\"@mipmap/animation_img1\" />\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"\n                    android:gravity=\"center\"\n                    android:text=\"BaseMultiItemQuickAdapter\"\n                    android:textColor=\"@android:color/black\"\n                    android:textSize=\"18sp\"\n                    android:textStyle=\"bold\" />\n\n            </LinearLayout>\n\n        </androidx.cardview.widget.CardView>\n\n        <androidx.cardview.widget.CardView\n            android:id=\"@+id/card_view2\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"150dp\"\n            android:layout_gravity=\"center\"\n            android:layout_marginLeft=\"5dp\"\n            android:layout_marginTop=\"20dp\"\n            android:layout_marginRight=\"5dp\"\n            android:foreground=\"?android:attr/selectableItemBackground\"\n            card_view:cardBackgroundColor=\"@color/item_bg\"\n            card_view:cardCornerRadius=\"4dp\"\n            card_view:cardElevation=\"2dp\"\n            card_view:cardUseCompatPadding=\"true\">\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:orientation=\"vertical\">\n\n                <ImageView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:scaleType=\"centerCrop\"\n                    android:src=\"@mipmap/animation_img1\" />\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"\n                    android:gravity=\"center\"\n                    android:text=\"BaseDelegateMultiAdapter\"\n                    android:textColor=\"@android:color/black\"\n                    android:textSize=\"18sp\"\n                    android:textStyle=\"bold\" />\n\n            </LinearLayout>\n        </androidx.cardview.widget.CardView>\n\n        <androidx.cardview.widget.CardView\n            android:id=\"@+id/card_view3\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"150dp\"\n            android:layout_gravity=\"center\"\n            android:layout_marginLeft=\"5dp\"\n            android:layout_marginTop=\"20dp\"\n            android:layout_marginRight=\"5dp\"\n            android:foreground=\"?android:attr/selectableItemBackground\"\n            card_view:cardBackgroundColor=\"@color/item_bg\"\n            card_view:cardCornerRadius=\"4dp\"\n            card_view:cardElevation=\"2dp\"\n            card_view:cardUseCompatPadding=\"true\">\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:orientation=\"vertical\">\n\n                <ImageView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:scaleType=\"centerCrop\"\n                    android:src=\"@mipmap/animation_img1\" />\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"\n                    android:gravity=\"center\"\n                    android:text=\"BaseProviderMultiAdapter\"\n                    android:textColor=\"@android:color/black\"\n                    android:textSize=\"18sp\"\n                    android:textStyle=\"bold\" />\n\n            </LinearLayout>\n        </androidx.cardview.widget.CardView>\n\n    </LinearLayout>\n</androidx.core.widget.NestedScrollView>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_choose_node_use_type.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:gravity=\"center_vertical\"\n    android:orientation=\"vertical\">\n\n    <androidx.cardview.widget.CardView\n        android:id=\"@+id/card_view1\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"150dp\"\n        android:layout_gravity=\"center\"\n        android:layout_marginLeft=\"5dp\"\n        android:layout_marginRight=\"5dp\"\n        android:foreground=\"?android:attr/selectableItemBackground\"\n        card_view:cardBackgroundColor=\"@color/item_bg\"\n        card_view:cardCornerRadius=\"4dp\"\n        card_view:cardElevation=\"2dp\"\n        card_view:cardUseCompatPadding=\"true\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <ImageView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:scaleType=\"centerCrop\"\n                android:src=\"@mipmap/animation_img1\" />\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:gravity=\"center\"\n                android:text=\"BaseNodeAdapter (Section)\"\n                android:textColor=\"@android:color/black\"\n                android:textSize=\"18sp\"\n                android:textStyle=\"bold\" />\n\n        </LinearLayout>\n\n    </androidx.cardview.widget.CardView>\n\n    <androidx.cardview.widget.CardView\n        android:id=\"@+id/card_view2\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"150dp\"\n        android:layout_gravity=\"center\"\n        android:layout_marginLeft=\"5dp\"\n        android:layout_marginTop=\"20dp\"\n        android:layout_marginRight=\"5dp\"\n        android:foreground=\"?android:attr/selectableItemBackground\"\n        card_view:cardBackgroundColor=\"@color/item_bg\"\n        card_view:cardCornerRadius=\"4dp\"\n        card_view:cardElevation=\"2dp\"\n        card_view:cardUseCompatPadding=\"true\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <ImageView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:scaleType=\"centerCrop\"\n                android:src=\"@mipmap/animation_img1\" />\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:gravity=\"center\"\n                android:text=\"BaseNodeAdapter (Tree)\"\n                android:textColor=\"@android:color/black\"\n                android:textSize=\"18sp\"\n                android:textStyle=\"bold\" />\n\n        </LinearLayout>\n    </androidx.cardview.widget.CardView>\n\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_diffutil.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <com.chad.baserecyclerviewadapterhelper.widget.BRVAHToolbar\n        android:id=\"@+id/title_bar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/diff_rv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        app:layoutManager=\"androidx.recyclerview.widget.LinearLayoutManager\"/>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginBottom=\"4dp\"\n        android:gravity=\"center_horizontal\"\n        android:paddingTop=\"4dp\">\n\n        <Button\n            android:id=\"@+id/btn_change\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"40dp\"\n            android:background=\"@drawable/touch_bg\"\n            android:textColor=\"@color/new_text_color\"\n            android:paddingLeft=\"6dp\"\n            android:paddingRight=\"6dp\"\n            android:text=\"Change Item\"\n            android:textAllCaps=\"false\" />\n\n        <Button\n            android:id=\"@+id/btn_add\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"40dp\"\n            android:layout_marginLeft=\"16dp\"\n            android:textColor=\"@color/new_text_color\"\n            android:background=\"@drawable/touch_bg\"\n            android:paddingLeft=\"6dp\"\n            android:paddingRight=\"6dp\"\n            android:text=\"Item add\"\n            android:textAllCaps=\"false\" />\n\n        <Button\n            android:id=\"@+id/btn_remove\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"40dp\"\n            android:layout_marginLeft=\"16dp\"\n            android:textColor=\"@color/new_text_color\"\n            android:background=\"@drawable/touch_bg\"\n            android:paddingLeft=\"6dp\"\n            android:paddingRight=\"6dp\"\n            android:text=\"Item remove\"\n            android:textAllCaps=\"false\" />\n\n    </LinearLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_empty_view_use.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    tools:context=\".activity.emptyview.EmptyViewUseActivity\">\n\n    <com.chad.baserecyclerviewadapterhelper.widget.BRVAHToolbar\n        android:id=\"@+id/title_bar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n    <FrameLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <com.google.android.material.floatingactionbutton.FloatingActionButton\n            android:id=\"@+id/btn_reset\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"end|bottom\"\n            android:layout_margin=\"20dp\"\n            android:contentDescription=\"刷新\"\n            android:src=\"@mipmap/reset_icon\"\n            app:backgroundTint=\"@color/color_light_blue\" />\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/rv_list\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:fadingEdge=\"none\" />\n    </FrameLayout>\n\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_home.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@color/bg\"\n    android:orientation=\"vertical\">\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recycler_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layoutManager=\"com.chad.library.adapter4.layoutmanager.QuickGridLayoutManager\"\n        app:spanCount=\"2\"\n        tools:listitem=\"@layout/home_item_view\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_load_more.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <com.chad.baserecyclerviewadapterhelper.widget.BRVAHToolbar\n        android:id=\"@+id/title_bar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout\n        android:id=\"@+id/refresh_layout\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:background=\"@color/bg\"\n        android:orientation=\"vertical\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/rv_list\"\n            android:layout_width=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:layout_height=\"match_parent\" />\n    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>\n\n\n</LinearLayout>\n\n\n\n\n"
  },
  {
    "path": "app/src/main/res/layout/activity_node.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    style=\"@style/bg\">\n\n    <com.chad.baserecyclerviewadapterhelper.widget.BRVAHToolbar\n        android:id=\"@+id/title_bar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/rv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        android:fadingEdge=\"none\"\n        app:layoutManager=\"androidx.recyclerview.widget.LinearLayoutManager\" />\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginBottom=\"4dp\"\n        android:gravity=\"center_horizontal\"\n        android:paddingTop=\"4dp\">\n\n        <Button\n            android:id=\"@+id/btn_close_all\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"40dp\"\n            android:background=\"@drawable/touch_bg\"\n            android:paddingLeft=\"6dp\"\n            android:paddingRight=\"6dp\"\n            android:text=\"关闭全部节点\"\n            android:textAllCaps=\"false\"\n            android:textColor=\"@color/new_text_color\" />\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginBottom=\"4dp\"\n        android:gravity=\"center_horizontal\"\n        android:paddingTop=\"4dp\">\n\n        <Button\n            android:id=\"@+id/btn_ref\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"40dp\"\n            android:layout_marginStart=\"12dp\"\n            android:background=\"@drawable/touch_bg\"\n            android:paddingLeft=\"6dp\"\n            android:paddingRight=\"6dp\"\n            android:text=\"刷新数据(保留打开状态)\"\n            android:textAllCaps=\"false\"\n            android:textColor=\"@color/new_text_color\" />\n\n        <Button\n            android:id=\"@+id/btn_ref_on_save\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"40dp\"\n            android:layout_marginStart=\"12dp\"\n            android:background=\"@drawable/touch_bg\"\n            android:paddingLeft=\"6dp\"\n            android:paddingRight=\"6dp\"\n            android:text=\"刷新数据(不保留打开状态)\"\n            android:textAllCaps=\"false\"\n            android:textColor=\"@color/new_text_color\" />\n\n    </LinearLayout>\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_universal_recycler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <com.chad.baserecyclerviewadapterhelper.widget.BRVAHToolbar\n        android:id=\"@+id/title_bar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/rv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:scrollbars=\"vertical\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_welcome.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    android:id=\"@+id/activity_welcome\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@mipmap/welcome\"\n    tools:context=\"com.chad.baserecyclerviewadapterhelper.activity.WelcomeActivity\">\n\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/def_section_head.xml",
    "content": "<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card_view\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"60dip\"\n    android:layout_gravity=\"center\"\n    android:layout_marginLeft=\"5dp\"\n    android:layout_marginRight=\"5dp\"\n    android:foreground=\"?android:attr/selectableItemBackground\"\n    card_view:cardBackgroundColor=\"@android:color/white\"\n    card_view:cardCornerRadius=\"4dp\"\n    card_view:cardElevation=\"2dp\"\n    card_view:cardUseCompatPadding=\"true\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"horizontal\">\n\n        <TextView\n            android:id=\"@+id/header\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"match_parent\"\n            android:layout_weight=\"1\"\n            android:gravity=\"left|center\"\n            android:paddingLeft=\"10dp\"\n            android:textColor=\"@color/txt_color\"\n            android:textSize=\"20sp\"\n            android:textStyle=\"bold\" />\n\n        <TextView\n            android:id=\"@+id/more\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"match_parent\"\n            android:layout_weight=\"1\"\n            android:gravity=\"right|center\"\n            android:paddingRight=\"10dp\"\n            android:text=\"more >\"\n            android:textColor=\"@color/color_light_blue\"\n            android:textSize=\"18sp\" />\n    </LinearLayout>\n\n</androidx.cardview.widget.CardView>\n"
  },
  {
    "path": "app/src/main/res/layout/empty_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    style=\"@style/bg\"\n    android:gravity=\"center\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        style=\"@style/empty_img\"\n        android:src=\"@mipmap/empty_icon\" />\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"5dp\"\n        android:text=\"@string/empty_no_data\"\n        android:textColor=\"@color/txt_color\" />\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/error_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    style=\"@style/bg\"\n    android:gravity=\"center\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        style=\"@style/empty_img\"\n        android:src=\"@mipmap/empty_icon\" />\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"5dp\"\n        android:text=\"@string/empty_network_error\"\n        android:textColor=\"@color/txt_color\" />\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/footer_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"50dp\"\n    android:layout_marginBottom=\"1dp\"\n    android:background=\"@color/dull_blue\"\n    android:gravity=\"center\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:id=\"@+id/iv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:src=\"@mipmap/add_icon\" />\n\n    <TextView\n        android:id=\"@+id/tv\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Footer\"\n        android:textColor=\"@android:color/white\"\n        android:textSize=\"18sp\" />\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/head_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"1dp\"\n    android:background=\"@mipmap/header_background\"\n    android:gravity=\"center\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:id=\"@+id/iv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:src=\"@mipmap/add_icon\" />\n\n    <TextView\n        android:id=\"@+id/tv\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:layout_marginTop=\"10dp\"\n        android:text=\"Header\"\n        android:textColor=\"@android:color/white\"\n        android:textSize=\"20sp\" />\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/home_item_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"180dp\"\n    android:gravity=\"center\"\n    android:orientation=\"horizontal\">\n\n    <androidx.cardview.widget.CardView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_gravity=\"center\"\n        card_view:cardBackgroundColor=\"@android:color/white\"\n        card_view:cardCornerRadius=\"8dp\"\n        card_view:cardElevation=\"3dp\"\n        card_view:cardUseCompatPadding=\"true\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:gravity=\"center\"\n            android:orientation=\"vertical\">\n\n            <ImageView\n                android:id=\"@+id/icon\"\n                android:layout_width=\"100dp\"\n                android:layout_height=\"100dp\"\n                android:src=\"@mipmap/gv_animation\" />\n\n            <TextView\n                android:id=\"@+id/text_view\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center\"\n                android:fontFamily=\"sans-serif-condensed\"\n                android:gravity=\"center\"\n                android:text=\"Animation\"\n                android:textColor=\"#48495F\"\n                android:textSize=\"18sp\"\n                android:textStyle=\"bold\" />\n        </LinearLayout>\n    </androidx.cardview.widget.CardView>\n</LinearLayout>\n\n"
  },
  {
    "path": "app/src/main/res/layout/item_click_childview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/card_view\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"120dip\"\n    android:layout_margin=\"5dp\"\n    android:layout_gravity=\"center\"\n    android:gravity=\"center_vertical\"\n    android:orientation=\"horizontal\"\n    android:background=\"@drawable/touch_bg\"\n    >\n\n    <ImageView\n        android:layout_width=\"wrap_content\"\n        android:id=\"@+id/imageView\"\n        android:layout_height=\"match_parent\"\n        android:src=\"@mipmap/click_head_img_1\"\n        android:scaleType=\"centerCrop\"\n        />\n    <TextView\n        android:id=\"@+id/tv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textColor=\"@android:color/black\"\n        android:textSize=\"18sp\"\n        android:text=\"Shooting Stars\"\n        android:layout_marginTop=\"16dp\"\n        android:textStyle=\"bold\"\n        android:layout_marginLeft=\"13dp\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_toRightOf=\"@+id/imageView\"\n        android:layout_toEndOf=\"@+id/imageView\"/>\n\n    <TextView\n        android:id=\"@+id/tv1\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textColor=\"@color/txt_color\"\n        android:textSize=\"13sp\"\n        android:text=\"O ever youthful,O ever weeping.\"\n        android:layout_below=\"@+id/tv\"\n\n        android:layout_alignLeft=\"@+id/tv\"\n        android:layout_alignStart=\"@+id/tv\"/>\n\n\n    <LinearLayout\n        android:id=\"@+id/layout_num\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginRight=\"12dp\"\n        android:gravity=\"center\"\n        android:orientation=\"horizontal\"\n        android:layout_marginEnd=\"12dp\"\n        android:layout_alignParentBottom=\"true\"\n        android:layout_marginBottom=\"8dp\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_alignParentEnd=\"true\">\n\n\n        <ImageView\n            android:id=\"@+id/iv_num_reduce\"\n            android:layout_width=\"22dp\"\n            android:layout_height=\"22dp\"\n            android:background=\"@drawable/selector_item_child\"/>\n\n        <TextView\n            android:id=\"@+id/tv_num\"\n            android:layout_width=\"35dp\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:text=\"0\"/>\n\n        <ImageView\n            android:id=\"@+id/iv_num_add\"\n            android:layout_width=\"22dp\"\n            android:layout_height=\"22dp\"\n            android:background=\"@drawable/selector_item_child\"/>\n\n    </LinearLayout>\n\n\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/item_click_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    android:id=\"@+id/card_view\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"115dip\"\n    android:layout_gravity=\"center\"\n    android:layout_margin=\"5dp\"\n    android:background=\"@drawable/touch_bg\"\n    android:gravity=\"center_vertical\"\n    android:orientation=\"horizontal\"\n    >\n\n    <ImageView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:scaleType=\"centerCrop\"\n        android:src=\"@mipmap/click_head_img_0\"\n        android:id=\"@+id/imageView\"/>\n\n    <Button\n        android:id=\"@+id/btn\"\n        android:layout_width=\"85dp\"\n        android:layout_height=\"33dp\"\n        android:background=\"@drawable/touch_bg\"\n        android:gravity=\"center\"\n        android:text=\"点击我\"\n        android:textColor=\"@color/txt_color\"\n        android:layout_marginBottom=\"15dp\"\n        android:layout_alignParentBottom=\"true\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_alignParentEnd=\"true\"\n        android:layout_marginRight=\"20dp\"\n\n        android:layout_marginEnd=\"20dp\"/>\n\n    <TextView\n        android:id=\"@+id/tv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textColor=\"@android:color/black\"\n        android:textSize=\"18sp\"\n        android:text=\"Shooting Stars\"\n        android:layout_marginTop=\"16dp\"\n        android:textStyle=\"bold\"\n        android:layout_marginLeft=\"13dp\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_toRightOf=\"@+id/imageView\"\n        android:layout_toEndOf=\"@+id/imageView\"/>\n\n    <TextView\n        android:id=\"@+id/tv1\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:textColor=\"@color/txt_color\"\n        android:textSize=\"13sp\"\n        android:text=\"O ever youthful,O ever weeping.\"\n        android:layout_below=\"@+id/tv\"\n\n        android:layout_alignLeft=\"@+id/tv\"\n        android:layout_alignStart=\"@+id/tv\"/>\n\n\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/item_draggable_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"80dp\"\n    android:layout_marginBottom=\"1dp\"\n    android:background=\"@android:color/white\"\n    android:orientation=\"horizontal\">\n\n    <ImageView\n        android:id=\"@+id/iv_head\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:layout_gravity=\"center_vertical\"\n        android:layout_marginLeft=\"16dp\"\n        android:src=\"@mipmap/head_img\" />\n\n    <LinearLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginLeft=\"13dp\"\n        android:layout_weight=\"1\"\n        android:gravity=\"center\"\n        android:orientation=\"vertical\">\n\n        <TextView\n            android:id=\"@+id/tv\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center_vertical\"\n            android:text=\"item 1\"\n            android:textColor=\"@android:color/black\"\n            android:textSize=\"18sp\"\n            android:textStyle=\"bold\" />\n\n        <TextView\n            android:id=\"@+id/email\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginTop=\"10dp\"\n            android:gravity=\"center_vertical\"\n            android:text=\"allencoder2013@gmail.com\"\n            android:textColor=\"@color/txt_color\" />\n    </LinearLayout>\n\n    <ImageView\n        android:id=\"@+id/iv\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginRight=\"27dp\"\n        android:scaleType=\"center\"\n        android:src=\"@mipmap/drag_icon\" />\n\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/item_group_type.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginStart=\"15dp\"\n    android:layout_marginEnd=\"15dp\"\n    android:background=\"#ffffff\"\n    android:orientation=\"vertical\"\n    android:paddingHorizontal=\"10dp\">\n\n    <View\n        android:id=\"@+id/line_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1px\"\n        android:background=\"#E0E0E0\" />\n\n    <TextView\n        android:id=\"@+id/tv_title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"10dp\"\n        android:textColor=\"#333333\"\n        android:textSize=\"15sp\"\n        android:textStyle=\"bold\"\n        tools:text=\"title\" />\n\n    <TextView\n        android:id=\"@+id/tv_content\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"5dp\"\n        android:layout_marginBottom=\"10dp\"\n        android:textSize=\"13sp\"\n        tools:text=\"content\" />\n\n\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_header_and_footer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card_view\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"120dp\"\n    android:layout_gravity=\"center\"\n    android:layout_marginLeft=\"5dp\"\n    android:layout_marginRight=\"5dp\"\n    android:foreground=\"?android:attr/selectableItemBackground\"\n    card_view:cardBackgroundColor=\"@color/item_bg\"\n    card_view:cardCornerRadius=\"4dp\"\n    card_view:cardElevation=\"2dp\"\n    card_view:cardUseCompatPadding=\"true\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:id=\"@+id/iv\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:scaleType=\"fitXY\"\n            android:src=\"@mipmap/headerandfooter_img1\" />\n    </LinearLayout>\n\n</androidx.cardview.widget.CardView>\n\n"
  },
  {
    "path": "app/src/main/res/layout/item_image_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card_view\"\n    android:layout_width=\"90dp\"\n    android:layout_height=\"90dp\"\n    android:layout_marginLeft=\"5dp\"\n    android:layout_marginRight=\"5dp\"\n    android:layout_gravity=\"center\"\n    android:foreground=\"?android:attr/selectableItemBackground\"\n    app:cardBackgroundColor=\"@color/item_bg\"\n    app:cardCornerRadius=\"4dp\"\n    app:cardElevation=\"2dp\"\n    app:cardUseCompatPadding=\"true\">\n\n    <ImageView\n        android:id=\"@+id/iv\"\n        android:layout_gravity=\"center\"\n        android:layout_width=\"90dp\"\n        android:layout_height=\"90dp\"\n        android:src=\"@mipmap/click_head_img_0\"/>\n</androidx.cardview.widget.CardView>"
  },
  {
    "path": "app/src/main/res/layout/item_img_text_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card_view\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"150dp\"\n    android:layout_gravity=\"center\"\n    android:layout_marginLeft=\"5dp\"\n    android:layout_marginRight=\"5dp\"\n    android:foreground=\"?android:attr/selectableItemBackground\"\n    app:cardBackgroundColor=\"@color/item_bg\"\n    app:cardCornerRadius=\"4dp\"\n    app:cardElevation=\"2dp\"\n    app:cardUseCompatPadding=\"true\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:id=\"@+id/iv\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:scaleType=\"centerCrop\"\n            android:src=\"@mipmap/animation_img1\" />\n\n        <TextView\n            android:id=\"@+id/tv\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:gravity=\"center\"\n            android:text=\"CymChad\"\n            android:textColor=\"@android:color/black\"\n            android:textSize=\"18sp\"\n            android:textStyle=\"bold\" />\n\n    </LinearLayout>\n</androidx.cardview.widget.CardView>"
  },
  {
    "path": "app/src/main/res/layout/item_long_click_childview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<RelativeLayout\n    android:id=\"@+id/card_view\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"120dip\"\n    android:layout_gravity=\"center\"\n    android:layout_margin=\"5dp\"\n    android:background=\"@drawable/touch_bg\"\n    android:gravity=\"center_vertical\"\n    android:orientation=\"horizontal\"\n    >\n\n    <ImageView\n        android:id=\"@+id/imageView\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:scaleType=\"centerCrop\"\n        android:src=\"@mipmap/click_head_img_1\"\n        />\n\n    <TextView\n        android:id=\"@+id/tv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_marginLeft=\"13dp\"\n        android:layout_marginTop=\"16dp\"\n        android:layout_toEndOf=\"@+id/imageView\"\n        android:layout_toRightOf=\"@+id/imageView\"\n        android:text=\"Shooting Stars\"\n        android:textColor=\"@android:color/black\"\n        android:textSize=\"18sp\"\n        android:textStyle=\"bold\"/>\n\n    <TextView\n        android:id=\"@+id/tv1\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignLeft=\"@+id/tv\"\n        android:layout_alignStart=\"@+id/tv\"\n        android:layout_below=\"@+id/tv\"\n        android:text=\"O ever youthful,O ever weeping.\"\n\n        android:textColor=\"@color/txt_color\"\n        android:textSize=\"13sp\"/>\n\n\n    <LinearLayout\n        android:id=\"@+id/layout_num\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentBottom=\"true\"\n        android:layout_alignParentEnd=\"true\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_marginBottom=\"8dp\"\n        android:layout_marginEnd=\"12dp\"\n        android:layout_marginRight=\"12dp\"\n        android:gravity=\"center\"\n        android:orientation=\"horizontal\">\n\n\n        <ImageView\n            android:id=\"@+id/iv_num_reduce\"\n            android:layout_width=\"22dp\"\n            android:layout_height=\"22dp\"\n            android:background=\"@drawable/selector_item_child\"/>\n\n        <TextView\n            android:id=\"@+id/tv_num\"\n            android:layout_width=\"35dp\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:text=\"0\"/>\n\n        <ImageView\n            android:id=\"@+id/iv_num_add\"\n            android:layout_width=\"22dp\"\n            android:layout_height=\"22dp\"\n            android:background=\"@drawable/selector_item_child\"/>\n\n    </LinearLayout>\n\n\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/item_long_click_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n\n    android:id=\"@+id/card_view\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"115dip\"\n    android:layout_gravity=\"center\"\n    android:layout_margin=\"5dp\"\n    android:background=\"@drawable/touch_bg\"\n    android:gravity=\"center_vertical\"\n    android:orientation=\"horizontal\"\n    >\n\n    <ImageView\n        android:id=\"@+id/imageView\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:scaleType=\"centerCrop\"\n        android:src=\"@mipmap/click_head_img_0\"/>\n\n    <Button\n        android:id=\"@+id/btn_long\"\n        android:layout_width=\"85dp\"\n        android:layout_height=\"33dp\"\n        android:layout_alignParentEnd=\"true\"\n        android:layout_alignParentRight=\"true\"\n        android:layout_alignParentBottom=\"true\"\n        android:layout_marginEnd=\"20dp\"\n        android:layout_marginRight=\"20dp\"\n        android:layout_marginBottom=\"15dp\"\n        android:background=\"@drawable/touch_bg\"\n        android:gravity=\"center\"\n        android:text=\"长按我\"\n\n        android:textColor=\"@color/txt_color\" />\n\n    <TextView\n        android:id=\"@+id/tv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentTop=\"true\"\n        android:layout_marginLeft=\"13dp\"\n        android:layout_marginTop=\"16dp\"\n        android:layout_toEndOf=\"@+id/imageView\"\n        android:layout_toRightOf=\"@+id/imageView\"\n        android:text=\"Shooting Stars\"\n        android:textColor=\"@android:color/black\"\n        android:textSize=\"18sp\"\n        android:textStyle=\"bold\"/>\n\n    <TextView\n        android:id=\"@+id/tv1\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignLeft=\"@+id/tv\"\n        android:layout_alignStart=\"@+id/tv\"\n        android:layout_below=\"@+id/tv\"\n        android:layout_weight=\"1\"\n        android:text=\"O ever youthful,O ever weeping.\"\n\n        android:textColor=\"@color/txt_color\"\n        android:textSize=\"13sp\"/>\n\n\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/item_movie.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <data>\n\n        <variable\n            name=\"movie\"\n            type=\"com.chad.baserecyclerviewadapterhelper.entity.Movie\" />\n\n        <variable\n            name=\"presenter\"\n            type=\"com.chad.baserecyclerviewadapterhelper.entity.MoviePresenter\" />\n    </data>\n\n    <androidx.cardview.widget.CardView xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"175dp\"\n        app:cardBackgroundColor=\"@android:color/white\"\n        app:cardCornerRadius=\"8dp\"\n        app:cardElevation=\"4dp\"\n        app:cardUseCompatPadding=\"true\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n\n            <com.google.android.material.floatingactionbutton.FloatingActionButton\n                android:id=\"@+id/button\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentEnd=\"true\"\n                android:layout_alignParentRight=\"true\"\n                android:layout_alignParentBottom=\"true\"\n                android:layout_marginEnd=\"16dp\"\n                android:layout_marginRight=\"16dp\"\n                android:layout_marginBottom=\"16dp\"\n                android:onClick=\"@{(view) -> presenter.buyTicket(view, movie)}\"\n                android:src=\"@mipmap/buy_icon\"\n                app:backgroundTint=\"@color/color_light_blue\" />\n\n            <RelativeLayout\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"match_parent\"\n                android:layout_alignParentStart=\"true\"\n                android:layout_alignParentLeft=\"true\"\n                android:layout_alignParentTop=\"true\">\n\n                <ImageView\n                    android:id=\"@+id/iv\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"match_parent\"\n                    android:scaleType=\"centerCrop\"\n                    android:src=\"@mipmap/databinding_img\" />\n\n                <TextView\n                    android:id=\"@+id/movie_name\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginLeft=\"10dp\"\n                    android:layout_marginTop=\"10dp\"\n                    android:layout_toRightOf=\"@id/iv\"\n                    android:text=\"@{movie.name}\"\n                    android:textColor=\"@color/txt_color\"\n                    android:textSize=\"16sp\"\n                    android:textStyle=\"bold\"\n                    tools:text=\"Chad\" />\n\n                <TextView\n                    android:id=\"@+id/movie_content\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_below=\"@+id/movie_name\"\n                    android:layout_alignStart=\"@+id/movie_name\"\n                    android:layout_alignLeft=\"@+id/movie_name\"\n                    android:text='@{movie.content}'\n                    android:textColor=\"#888888\"\n                    android:textSize=\"12sp\"\n                    tools:text=\"He was one of Australia's most distinguished artistes\" />\n\n                <TextView\n                    android:id=\"@+id/movie_length\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_below=\"@+id/movie_content\"\n                    android:layout_alignStart=\"@+id/movie_content\"\n                    android:layout_alignLeft=\"@+id/movie_content\"\n                    android:text='@{movie.length+ \" minute\"}'\n                    android:textColor=\"#CCCCCC\"\n                    android:textSize=\"12sp\"\n                    tools:text=\"PM 11:28\" />\n\n                <TextView\n                    android:id=\"@+id/movie_price\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignStart=\"@+id/movie_length\"\n                    android:layout_alignLeft=\"@+id/movie_length\"\n                    android:layout_alignParentBottom=\"true\"\n                    android:layout_marginBottom=\"17dp\"\n                    android:text='@{\"$ \" + movie.price}'\n                    android:textColor=\"@color/txt_color\"\n                    android:textSize=\"28sp\"\n                    android:textStyle=\"bold\"\n                    tools:text=\"$ 12\" />\n            </RelativeLayout>\n\n        </RelativeLayout>\n    </androidx.cardview.widget.CardView>\n</layout>\n"
  },
  {
    "path": "app/src/main/res/layout/item_node_level_1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\"\n        android:gravity=\"center_vertical\"\n        android:paddingHorizontal=\"15dp\"\n        android:paddingVertical=\"20dp\">\n\n        <TextView\n            android:id=\"@+id/tv_title\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            android:textColor=\"@android:color/black\"\n            android:textSize=\"18sp\"\n            android:textStyle=\"bold\"\n            tools:text=\"index 1\" />\n\n        <ImageView\n            android:id=\"@+id/iv_arrow\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            tools:src=\"@drawable/ic_node_down\" />\n\n    </LinearLayout>\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:layout_marginHorizontal=\"15dp\"\n        android:background=\"#DEDEDE\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_node_level_2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:gravity=\"center_vertical\"\n    android:orientation=\"horizontal\"\n    android:paddingHorizontal=\"15dp\"\n    android:paddingVertical=\"10dp\">\n\n    <TextView\n        android:id=\"@+id/tv_title\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"15dp\"\n        android:layout_weight=\"1\"\n        android:textColor=\"@android:color/black\"\n        android:textSize=\"14sp\"\n        android:textStyle=\"bold\"\n        tools:text=\"Level 2\" />\n\n    <ImageView\n        android:id=\"@+id/iv_arrow\"\n        android:layout_width=\"28dp\"\n        android:layout_height=\"28dp\"\n        tools:src=\"@drawable/ic_node_down\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_node_level_3.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"horizontal\"\n    android:paddingHorizontal=\"15dp\"\n    android:paddingVertical=\"10dp\">\n\n    <TextView\n        android:id=\"@+id/tv_title\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"25dp\"\n        android:layout_weight=\"1\"\n        android:textColor=\"@android:color/black\"\n        android:textSize=\"14sp\"\n        tools:text=\"Level 2\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_section_content.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card_view\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"150dp\"\n    android:layout_gravity=\"center\"\n    android:foreground=\"?android:attr/selectableItemBackground\"\n    card_view:cardBackgroundColor=\"@android:color/white\"\n    card_view:cardCornerRadius=\"4dp\"\n    card_view:cardElevation=\"2dp\"\n    card_view:cardUseCompatPadding=\"true\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:id=\"@+id/iv\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"100dp\"\n            android:layout_gravity=\"center\"\n            android:layout_marginBottom=\"10dp\"\n            android:scaleType=\"fitXY\"\n            android:src=\"@mipmap/m_img1\" />\n\n        <TextView\n            android:id=\"@+id/tv\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center|bottom\"\n            android:text=\"C\"\n            android:textColor=\"@color/txt_color\"\n            android:textStyle=\"bold\" />\n    </LinearLayout>\n</androidx.cardview.widget.CardView>"
  },
  {
    "path": "app/src/main/res/layout/layout_animation.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card_view\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center\"\n    android:layout_marginLeft=\"5dp\"\n    android:layout_marginRight=\"5dp\"\n    android:foreground=\"?android:attr/selectableItemBackground\"\n    card_view:cardBackgroundColor=\"@color/item_bg\"\n    card_view:cardCornerRadius=\"4dp\"\n    card_view:cardUseCompatPadding=\"true\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\">\n\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentStart=\"true\"\n            android:layout_alignParentLeft=\"true\"\n            android:layout_alignParentTop=\"true\"\n            android:scaleType=\"centerCrop\"\n            android:src=\"@mipmap/animation_img1\" />\n\n        <TextView\n            android:id=\"@+id/tweetName\"\n            style=\"@style/tweetName\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_below=\"@+id/img\"\n            android:layout_alignParentStart=\"true\"\n            android:layout_alignParentLeft=\"true\"\n            android:layout_marginTop=\"@dimen/dp_10\"\n            android:paddingLeft=\"@dimen/dp_10\"\n            android:text=\"Chad\" />\n\n        <TextView\n            android:id=\"@+id/tweetText\"\n            style=\"@style/tweetText\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_below=\"@+id/tweetName\"\n            android:layout_alignParentStart=\"true\"\n            android:layout_alignParentLeft=\"true\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_alignParentRight=\"true\"\n            android:paddingLeft=\"@dimen/dp_10\"\n            android:paddingRight=\"@dimen/dp_10\"\n            android:paddingBottom=\"@dimen/dp_10\"\n            android:text=\"Hello world!\"\n            android:textColor=\"@android:color/darker_gray\" />\n\n        <TextView\n            android:id=\"@+id/tweetDate\"\n            style=\"@style/tweetDate\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignBaseline=\"@+id/tweetName\"\n            android:layout_alignBottom=\"@+id/tweetName\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_alignParentRight=\"true\"\n            android:paddingRight=\"@dimen/dp_10\"\n            android:text=\"04/06/13\" />\n\n    </RelativeLayout>\n</androidx.cardview.widget.CardView>\n"
  },
  {
    "path": "app/src/main/res/layout/layout_title_bar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/ly_main_actionbar\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"32dp\"\n    android:background=\"@color/spinner_bg\">\n\n    <ImageView\n        android:id=\"@+id/img_back\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerVertical=\"true\"\n        android:paddingTop=\"10dp\"\n        android:paddingRight=\"10dp\"\n        android:paddingBottom=\"10dp\"\n        android:src=\"@mipmap/back\" />\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginLeft=\"10dp\"\n        android:layout_toRightOf=\"@+id/img_back\"\n        android:gravity=\"center_vertical\"\n        android:text=\"title\"\n        android:textColor=\"@color/white_text_color\"\n        android:textSize=\"16sp\" />\n\n    <TextView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginLeft=\"10dp\"\n        android:layout_toRightOf=\"@+id/title\"\n        android:gravity=\"center_vertical\"\n        android:text=\"Demo\"\n        android:textColor=\"@color/gray_color\"\n        android:textSize=\"12sp\" />\n\n</RelativeLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/layout_tool_bar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:background=\"@color/spinner_bg\"\n    tools:layout_height=\"wrap_content\"\n    tools:layout_width=\"match_parent\"\n    tools:parentTag=\"android.widget.LinearLayout\">\n\n    <Space\n        android:id=\"@+id/fake_bar\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"0dp\" />\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginVertical=\"12dp\"\n        android:orientation=\"horizontal\">\n\n        <ImageView\n            android:id=\"@+id/iv_back\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"match_parent\"\n            android:layout_centerVertical=\"true\"\n            android:paddingStart=\"15dp\"\n            android:paddingEnd=\"15dp\"\n            android:scaleType=\"centerInside\"\n            android:src=\"@mipmap/back\" />\n\n        <TextView\n            android:id=\"@+id/tv_title\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginStart=\"10dp\"\n            android:layout_toEndOf=\"@id/iv_back\"\n            android:gravity=\"center_vertical\"\n            android:textColor=\"@color/white_text_color\"\n            android:textSize=\"16sp\"\n            tools:text=\"title\" />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginStart=\"10dp\"\n            android:layout_toEndOf=\"@id/tv_title\"\n            android:gravity=\"center_vertical\"\n            android:text=\"Demo\"\n            android:textColor=\"@color/gray_color\"\n            android:textSize=\"12sp\" />\n    </LinearLayout>\n\n\n</merge>\n"
  },
  {
    "path": "app/src/main/res/layout/loading_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    style=\"@style/bg\"\n    android:gravity=\"center\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        style=\"@style/empty_img\"\n        android:src=\"@mipmap/empty_icon\" />\n\n    <LinearLayout\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"5dp\"\n        android:orientation=\"horizontal\">\n\n        <ProgressBar\n            android:id=\"@+id/progressBar\"\n            style=\"?android:attr/progressBarStyleSmall\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginLeft=\"8dp\"\n            android:text=\"@string/brvah_loading\"\n            android:textColor=\"@color/txt_color\" />\n    </LinearLayout>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/node_footer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\"\n    android:padding=\"8dp\">\n\n    <TextView\n        android:id=\"@+id/footerTv\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"end\"\n        android:text=\"@string/see_more\"\n        android:textStyle=\"bold\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/toolbar_layout.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.appcompat.widget.Toolbar xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/toolbar\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@color/spinner_bg\"\n    android:minHeight=\"?attr/actionBarSize\"\n    app:popupTheme=\"@style/ThemeOverlay.AppCompat.Light\"\n    app:theme=\"@style/ThemeOverlay.AppCompat.Dark.ActionBar\">\n\n    <include layout=\"@layout/layout_title_bar\" />\n</androidx.appcompat.widget.Toolbar>\n"
  },
  {
    "path": "app/src/main/res/layout/top_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n             android:layout_width=\"match_parent\"\n             android:layout_height=\"wrap_content\">\n\n    <ImageView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:src=\"@mipmap/top_background\"/>\n\n    <ImageView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"right|bottom\"\n        android:src=\"@mipmap/monkey\"/>\n</FrameLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/view_load_more.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"@dimen/dp_40\">\n\n    <LinearLayout\n        android:id=\"@+id/load_more_loading_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:gravity=\"center\"\n        android:orientation=\"horizontal\">\n\n        <ProgressBar\n            android:id=\"@+id/loading_progress\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            style=\"?android:attr/progressBarStyleSmall\"\n            android:layout_marginRight=\"@dimen/dp_4\"\n            android:indeterminateDrawable=\"@drawable/brvah_sample_footer_loading_progress\"/>\n\n        <TextView\n            android:id=\"@+id/loading_text\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginLeft=\"@dimen/dp_4\"\n            android:text=\"@string/brvah_loading\"\n            android:textColor=\"#0dddb8\"\n            android:textSize=\"@dimen/sp_14\"/>\n    </LinearLayout>\n\n    <FrameLayout\n        android:id=\"@+id/load_more_load_fail_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n\n        <TextView\n            android:id=\"@+id/tv_prompt\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:textColor=\"#0dddb8\"\n            android:text=\"@string/brvah_load_failed\"/>\n\n    </FrameLayout>\n\n    <FrameLayout\n        android:id=\"@+id/load_more_load_complete_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:text=\"戳我，还有更多惊喜内容👇\"\n            android:textColor=\"@android:color/darker_gray\"/>\n    </FrameLayout>\n\n    <FrameLayout\n        android:id=\"@+id/load_more_load_end_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:text=\"@string/brvah_load_end\"\n            android:textColor=\"@android:color/darker_gray\"/>\n    </FrameLayout>\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#333244</color>\n    <color name=\"colorPrimaryDark\">#292836</color>\n\n    <color name=\"color_light_blue\">#00DDB6</color>\n    <color name=\"txt_color\">#48495F</color>\n    <color name=\"item_bg\">#FFFFFF</color>\n    <color name=\"bg\">#F0F0F0</color>\n    <color name=\"spinner_bg\">#333244</color>\n    <color name=\"new_text_color\">#555771</color>\n    <color name=\"white_text_color\">#F0F0F0</color>\n    <color name=\"gray_color\">#4b4b58</color>\n    <color name=\"hard_color\">#48495f</color>\n    <color name=\"clickspan_color\">#00ddb6</color>\n    <color name=\"dull_blue\">#3B4BBF</color>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"def_height\">80dp</dimen>\n\n    <dimen name=\"dp_4\">4dp</dimen>\n    <dimen name=\"dp_10\">10dp</dimen>\n    <dimen name=\"dp_40\">40dp</dimen>\n\n    <dimen name=\"sp_14\">14sp</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"network_err\">Simulation network error</string>\n    <string name=\"empty_network_error\">Network error, Click Retry</string>\n    <string name=\"empty_no_data\">There is no data, Click Retry</string>\n\n    <string name=\"see_more\">See More ...</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorPrimary</item>\n        <item name=\"android:textColorPrimary\">@android:color/white</item>\n        <item name=\"android:windowIsTranslucent\">true</item>\n    </style>\n\n    <style name=\"WelcomeTheme\" parent=\"AppTheme\">\n        <item name=\"android:windowBackground\">@mipmap/welcome</item>\n    </style>\n\n\n\n    <style name=\"tweetName\">\n        <item name=\"android:textColor\">@color/hard_color</item>\n        <item name=\"android:textStyle\">bold</item>\n        <item name=\"android:textSize\">18sp</item>\n        <!--<item name=\"android:textStyle\">bold</item>-->\n        <item name=\"android:shadowColor\">#44000000</item>\n        <item name=\"android:shadowDx\">1</item>\n        <item name=\"android:shadowDy\">1</item>\n        <item name=\"android:shadowRadius\">1</item>\n    </style>\n\n    <style name=\"tweetText\">\n        <item name=\"android:textSize\">13sp</item>\n        <item name=\"android:textColorLink\">#888888</item>\n        <item name=\"android:lineSpacingExtra\">4dp</item>\n    </style>\n\n    <style name=\"tweetDate\">\n        <item name=\"android:textSize\">10sp</item>\n        <item name=\"android:textColor\">#FFCCCCCC</item>\n    </style>\n\n\n    <style name=\"bg\">\n        <item name=\"android:layout_width\">match_parent</item>\n        <item name=\"android:layout_height\">match_parent</item>\n        <item name=\"android:background\">@color/bg</item>\n        <item name=\"android:orientation\">vertical</item>\n    </style>\n\n    <style name=\"empty_img\">\n        <item name=\"android:layout_width\">@dimen/def_height</item>\n        <item name=\"android:layout_height\">@dimen/def_height</item>\n        <item name=\"android:layout_marginBottom\">10dp</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-v21/styles.xml",
    "content": "<resources>\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorPrimary</item>\n        <item name=\"android:windowDrawsSystemBarBackgrounds\">true</item>\n        <!--<item name=\"android:statusBarColor\">@android:color/transparent</item>-->\n        <item name=\"android:textColorPrimary\">@android:color/white</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-zh/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"see_more\">查看更多 ...</string>\n    <string name=\"network_err\">模拟网络错误</string>\n    <string name=\"empty_no_data\">没有数据，点击重试</string>\n    <string name=\"empty_network_error\">网络错误，点击重试</string>\n</resources>"
  },
  {
    "path": "build.gradle",
    "content": "\nplugins {\n    id 'com.android.application' version '8.12.2' apply false\n    id 'com.android.library' version '8.12.2' apply false\n    id 'org.jetbrains.kotlin.android' version '2.2.10' apply false\n    id 'com.google.devtools.ksp' version '2.2.10-2.0.2' apply false\n}\n\ntasks.register('clean', Delete) {\n    delete rootProject.buildDir\n}\n\n\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon May 29 14:19:55 CST 2023\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.14.3-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "## For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n#\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx1024m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n#\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n#Wed Feb 26 13:11:31 CST 2020\norg.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\\=\"-Xmx2048M\"\nandroid.useAndroidX=true\nandroid.enableJetifier=false\nandroid.injected.testOnly=false\n\nandroid.nonTransitiveRClass=true\nandroid.nonFinalResIds=false"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "library/.gitignore",
    "content": ".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",
    "content": "import java.io.FileInputStream\nimport java.io.InputStreamReader\nimport java.util.*\n\nplugins {\n    id(\"com.android.library\")\n    kotlin(\"android\")\n    `maven-publish`\n    signing\n}\n\nval versionName = \"4.3.4\"\n\n\nandroid {\n    namespace = \"com.chad.library.adapter4\"\n\n    compileSdk = 31\n\n    defaultConfig {\n        minSdk = 19\n\n        consumerProguardFiles(\"proguard-rules.pro\")\n    }\n\n\n    buildTypes {\n        getByName(\"release\") {\n            consumerProguardFiles(\"proguard-rules.pro\")\n        }\n    }\n\n\n    compileOptions {\n        kotlinOptions.freeCompilerArgs = ArrayList<String>().apply {\n            add(\"-module-name\")\n            add(\"com.github.CymChad.brvah\")\n            add(\"-Xjvm-default=all\")\n        }\n        sourceCompatibility = JavaVersion.VERSION_11\n        targetCompatibility = JavaVersion.VERSION_11\n    }\n    kotlinOptions {\n        jvmTarget = \"11\"\n    }\n\n\n\n    publishing {\n        singleVariant(\"release\") {\n            // if you don't want sources/javadoc, remove these lines\n            withSourcesJar()\n            withJavadocJar()\n        }\n    }\n}\n\n\ndependencies {\n    implementation(\"androidx.annotation:annotation:1.8.0\")\n\n    implementation(\"androidx.recyclerview:recyclerview:1.3.2\")\n\n    compileOnly(\"androidx.databinding:databinding-runtime:8.0.0\")\n}\n\n//---------- maven upload info -----------------------------------\n\nvar signingKeyId = \"\"//签名的密钥后8位\nvar signingPassword = \"\"//签名设置的密码\nvar secretKeyRingFile = \"\"//生成的secring.gpg文件目录\nvar ossrhUsername = \"\"//sonatype用户名\nvar ossrhPassword = \"\" //sonatype密码\n\n\ntry {\n    val localProperties: File = project.rootProject.file(\"local.properties\")\n\n    if (localProperties.exists()) {\n        println(\"Found secret props file, loading props\")\n        val properties = Properties()\n\n        InputStreamReader(FileInputStream(localProperties), Charsets.UTF_8).use { reader ->\n            properties.load(reader)\n        }\n        signingKeyId = properties.getProperty(\"signing.keyId\")\n        signingPassword = properties.getProperty(\"signing.password\")\n        secretKeyRingFile = properties.getProperty(\"signing.secretKeyRingFile\")\n        ossrhUsername = properties.getProperty(\"ossrhUsername\")\n        ossrhPassword = properties.getProperty(\"ossrhPassword\")\n\n    } else {\n        println(\"No props file, loading env vars\")\n    }\n} catch (_: Exception) {\n}\n\n\nafterEvaluate {\n\n    publishing {\n        publications {\n            create<MavenPublication>(\"release\") {\n                from(components.findByName(\"release\"))\n                groupId = \"io.github.cymchad\"\n                artifactId = \"BaseRecyclerViewAdapterHelper4\"\n                version = versionName\n\n                pom {\n                    name.value(\"BaseRecyclerViewAdapterHelper\")\n                    description.value(\"Powerful and flexible RecyclerAdapter\")\n                    url.value(\"https://github.com/CymChad/BaseRecyclerViewAdapterHelper\")\n\n                    licenses {\n                        license {\n                            //协议类型\n                            name.value(\"The MIT License\")\n                            url.value(\"https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/LICENSE\")\n                        }\n                    }\n\n                    developers {\n                        developer {\n                            id.value(\"limuyang2\")\n                            name.value(\"limuyang\")\n                            email.value(\"limuyang2@hotmail.com\")\n                        }\n                    }\n\n                    scm {\n                        connection.value(\"scm:git@github.com/CymChad/BaseRecyclerViewAdapterHelper.git\")\n                        developerConnection.value(\"scm:git@github.com/CymChad/BaseRecyclerViewAdapterHelper.git\")\n                        url.value(\"https://github.com/CymChad/BaseRecyclerViewAdapterHelper\")\n                    }\n                }\n            }\n\n        }\n\n        repositories {\n            maven {\n                url = uri(\"https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/\")\n                credentials {\n                    username = ossrhUsername\n                    password = ossrhPassword\n                }\n            }\n\n//            maven {\n//                setUrl(\"$rootDir/Repo\")\n//            }\n        }\n\n    }\n\n}\n\ngradle.taskGraph.whenReady {\n    if (allTasks.any { it is Sign }) {\n\n        allprojects {\n            extra[\"signing.keyId\"] = signingKeyId\n            extra[\"signing.secretKeyRingFile\"] = secretKeyRingFile\n            extra[\"signing.password\"] = signingPassword\n        }\n    }\n}\n\nsigning {\n    sign(publishing.publications)\n}\n\n"
  },
  {
    "path": "library/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/huasheng/Desktop/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Data binding混淆规则\n-keep class * {\n @androidx.databinding.BindingAdapter <methods>;\n}"
  },
  {
    "path": "library/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n</manifest>\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseDifferAdapter.kt",
    "content": "package com.chad.library.adapter4\n\nimport androidx.recyclerview.widget.*\nimport androidx.recyclerview.widget.AsyncListDiffer.ListListener\nimport java.util.*\n\n/**\n * Deprecated.\n *\n * Base differ adapter.\n *\n * 使用 Differ 的父类。异步执行 Diff 计算，不会有性能问题。\n *\n * @param T 数据类型\n * @param VH ViewHolder 类型\n */\n@Deprecated(\"请直接使用 BaseQuickAdapter。Please use BaseQuickAdapter directly.\")\nabstract class BaseDifferAdapter<T : Any, VH : RecyclerView.ViewHolder>(\n    config: AsyncDifferConfig<T>, items: List<T>\n) : BaseQuickAdapter<T, VH>(items, config) {\n\n    constructor(diffCallback: DiffUtil.ItemCallback<T>) : this(diffCallback, emptyList())\n\n    constructor(diffCallback: DiffUtil.ItemCallback<T>, items: List<T>) : this(\n        AsyncDifferConfig.Builder(diffCallback).build(), items\n    )\n\n    constructor(config: AsyncDifferConfig<T>) : this(config, emptyList())\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseMultiItemAdapter.kt",
    "content": "package com.chad.library.adapter4\n\nimport android.content.Context\nimport android.util.SparseArray\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.AsyncDifferConfig\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.BaseQuickAdapter\nimport java.lang.ref.WeakReference\n\n/**\n * MultiItemType layout.\n * 多类型布局\n *\n */\nabstract class BaseMultiItemAdapter<T : Any> (items: List<T>, config: AsyncDifferConfig<T>?) :\n    BaseQuickAdapter<T, RecyclerView.ViewHolder>(items, config) {\n\n    constructor(diffCallback: DiffUtil.ItemCallback<T>) : this(emptyList(), diffCallback)\n\n    constructor(items: List<T>, diffCallback: DiffUtil.ItemCallback<T>) : this(\n        items, AsyncDifferConfig.Builder(diffCallback).build(),\n    )\n\n    constructor(config: AsyncDifferConfig<T>?) : this(emptyList(), config)\n\n    constructor(items: List<T>) : this(items, null)\n\n    constructor() : this(emptyList(), null)\n\n    private val typeViewHolders =\n        SparseArray<OnMultiItemAdapterListener<T, RecyclerView.ViewHolder>>(1)\n\n    private var onItemViewTypeListener: OnItemViewTypeListener<T>? = null\n\n    override fun onCreateViewHolder(\n        context: Context, parent: ViewGroup, viewType: Int\n    ): RecyclerView.ViewHolder {\n        val listener = typeViewHolders.get(viewType)\n            ?: throw IllegalArgumentException(\"ViewType: $viewType not found onViewHolderListener，please use addItemType() first!\")\n\n        return listener.onCreate(parent.context, parent, viewType).apply {\n            itemView.setTag(R.id.BaseQuickAdapter_key_multi, listener)\n        }\n    }\n\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, item: T?) {\n        findListener(holder)?.onBind(holder, position, item)\n    }\n\n    override fun onBindViewHolder(\n        holder: RecyclerView.ViewHolder, position: Int, item: T?, payloads: List<Any>\n    ) {\n        if (payloads.isEmpty()) {\n            onBindViewHolder(holder, position, item)\n            return\n        }\n\n        findListener(holder)?.onBind(holder, position, item, payloads)\n    }\n\n    /**\n     * Call this function to add multiTypeItems.\n     * 调用此方法，设置多布局\n     * @param itemViewType Int\n     * @param listener Int\n     */\n    fun <V : RecyclerView.ViewHolder> addItemType(\n        itemViewType: Int, listener: OnMultiItemAdapterListener<T, V>\n    ) = apply {\n        if (listener is OnMultiItem) {\n            listener.weakA = WeakReference(this)\n        }\n        typeViewHolders.put(\n            itemViewType, listener as OnMultiItemAdapterListener<T, RecyclerView.ViewHolder>\n        )\n    }\n\n    /**\n     * 设置 ItemViewType 的监听，根据不同数据类型，返回不同的type值\n     *\n     * @param listener\n     */\n    fun onItemViewType(listener: OnItemViewTypeListener<T>?) = apply {\n        this.onItemViewTypeListener = listener\n    }\n\n    override fun getItemViewType(position: Int, list: List<T>): Int {\n        return onItemViewTypeListener?.onItemViewType(position, list)\n            ?: super.getItemViewType(position, list)\n    }\n\n    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {\n        super.onViewAttachedToWindow(holder)\n\n        findListener(holder)?.onViewAttachedToWindow(holder)\n    }\n\n    override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {\n        super.onViewDetachedFromWindow(holder)\n        findListener(holder)?.onViewDetachedFromWindow(holder)\n    }\n\n    override fun onViewRecycled(holder: RecyclerView.ViewHolder) {\n        super.onViewRecycled(holder)\n        findListener(holder)?.onViewRecycled(holder)\n    }\n\n    override fun onFailedToRecycleView(holder: RecyclerView.ViewHolder): Boolean {\n        return findListener(holder)?.onFailedToRecycleView(holder) ?: false\n    }\n\n    override fun isFullSpanItem(itemType: Int): Boolean {\n        return super.isFullSpanItem(itemType) ||\n                (typeViewHolders.get(itemType)?.isFullSpanItem(itemType) == true)\n    }\n\n    private fun findListener(holder: RecyclerView.ViewHolder) : OnMultiItemAdapterListener<T, RecyclerView.ViewHolder>? {\n       return holder.itemView.getTag(R.id.BaseQuickAdapter_key_multi) as? OnMultiItemAdapterListener<T, RecyclerView.ViewHolder>\n    }\n\n    /**\n     * 多类型布局 Adapter Listener\n     *\n     * @param T 数据类型\n     * @param V ViewHolder 类型\n     */\n    interface OnMultiItemAdapterListener<T, V : RecyclerView.ViewHolder> {\n        fun onCreate(context: Context, parent: ViewGroup, viewType: Int): V\n\n        fun onBind(holder: V, position: Int, item: T?)\n\n        fun onBind(holder: V, position: Int, item: T?, payloads: List<Any>) {\n            onBind(holder, position, item)\n        }\n\n        fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {}\n\n        fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {}\n\n        fun onViewRecycled(holder: RecyclerView.ViewHolder) {}\n\n        fun onFailedToRecycleView(holder: RecyclerView.ViewHolder): Boolean = false\n\n        fun isFullSpanItem(itemType: Int): Boolean {\n            return false\n        }\n    }\n\n    /**\n     * 如果需要一些属性，例如：adapter、context，则使用此抽象类.\n     * 如果不需要，则可以直接实现[OnMultiItemAdapterListener]接口.\n     *\n     * @param T\n     * @param V\n     * @constructor Create empty On multi item\n     */\n    abstract class OnMultiItem<T : Any, V : RecyclerView.ViewHolder> :\n        OnMultiItemAdapterListener<T, V> {\n        internal var weakA: WeakReference<BaseMultiItemAdapter<T>>? = null\n\n        val adapter: BaseMultiItemAdapter<T>?\n            get() = weakA?.get()\n\n        val context: Context?\n            get() = weakA?.get()?.context\n    }\n\n    fun interface OnItemViewTypeListener<T> {\n        /**\n         * 根据不同数据类型，返回不同的type值\n         *\n         * @param position\n         * @param list\n         * @return\n         */\n        fun onItemViewType(position: Int, list: List<T>): Int\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseNodeAdapter.kt",
    "content": "package com.chad.library.adapter4\n\nimport androidx.recyclerview.widget.AsyncDifferConfig\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\n\n/**\n * @author LiMuYang\n * @date 2025/9/2\n * @description\n *\n * 树节点类型列表适配器。\n *\n * Tree node type list adapter.\n */\nabstract class BaseNodeAdapter(config: AsyncDifferConfig<Any>?) : BaseQuickAdapter<Any, RecyclerView.ViewHolder>(config = config) {\n\n    constructor(diffCallback: DiffUtil.ItemCallback<Any>) : this(\n        AsyncDifferConfig.Builder(diffCallback).build()\n    )\n\n    constructor() : this(null)\n\n    /**\n     * 记录打开的节点。\n     *\n     * Set of open nodes.\n     */\n    private val openedSet = HashSet<Any>()\n\n    /**\n     * 获取子节点列表。\n     *\n     * Get child node list.\n     *\n     * @param position\n     *\n     * @return\n     * 子节点列表，如果没有，请返回null。\n     *\n     * List of child nodes, if not, return null.\n     */\n    abstract fun getChildNodeList(position: Int, parent: Any): List<Any>?\n\n    /**\n     * 设置数据时，默认需要打开的节点。\n     *\n     * 注意：此方法会被调用多次，包括对原始列表和递归展开的子节点。\n     * position 参数表示在正在构建的列表中的位置，而非原始输入列表的位置。\n     * 如果你只需要判断原始根节点，请同时检查 item 是否在原始列表中。\n     *\n     * When submitList, the nodes that need to be opened by default.\n     *\n     * Note: This method will be called multiple times, including for the original list\n     * and recursively expanded child nodes. The position parameter represents the position\n     * in the list being constructed, not the original input list. If you only want to\n     * check the original root nodes, also check if the item is in the original list.\n     *\n     * @param position 在当前正在构建的列表中的位置 / Position in the list being constructed\n     * @param item 节点对象 / Node object\n     * @return 是否需要初始展开 / Whether to initially expand\n     */\n    abstract fun isInitialOpen(position: Int, item: Any): Boolean\n\n    /**\n     * 判断两个节点是否是同一个逻辑节点\n     * 默认使用 === 比较引用\n     * 如果新数据是新的对象实例，子类应该重写此方法，提供自定义的节点匹配逻辑\n     * （例如根据节点 ID 或其他唯一标识符进行匹配）\n     *\n     * Determine if two nodes are the same logical node\n     * By default uses === to compare references\n     * If the new data is a new object instance, subclasses should override this method\n     * to provide custom node matching logic (e.g., match by node ID or other unique identifier)\n     *\n     * @param item1 节点1 / Node 1\n     * @param item2 节点2 / Node 2\n     * @return 是否是同一个节点 / Whether they are the same node\n     */\n    protected open fun isSameNode(item1: Any, item2: Any): Boolean {\n        return item1 === item2\n    }\n\n    override fun submitList(list: List<Any>?, commitCallback: Runnable?) {\n        this.submitList(list, false, commitCallback)\n    }\n\n    /**\n     * 提交列表数据\n     *\n     * @param list 数据列表 / Data list\n     * @param commitCallback 回调 / Callback\n     * @param clearOpenStates 是否清空之前的展开状态。\n     * false，保留用户的展开状态。\n     * 如果设置为 true，会重新根据 isInitialOpen 判断展开状态。\n     *\n     * Submit list data\n     *\n     * @param clearOpenStates Whether to clear previous expanded states.\n     * false, preserving user expanded states.\n     * If set to true, will re-determine expanded states based on isInitialOpen.\n     */\n    fun submitList(\n        list: List<Any>?,\n        clearOpenStates: Boolean,\n        commitCallback: Runnable? = null,\n    ) {\n        if (list.isNullOrEmpty()) {\n            openedSet.clear()\n            super.submitList(list, commitCallback)\n            return\n        }\n\n        // 处理展开状态\n        // Handle expanded states\n        if (clearOpenStates) {\n            // 清空之前的展开状态，完全重新计算\n            // Clear previous expanded states and completely recalculate\n            openedSet.clear()\n        } else {\n            // 保留展开状态：将旧数据的展开状态递归映射到新数据\n            // Preserve expanded states: recursively map old data's expanded states to new data\n            val oldOpenedSet = openedSet.toSet()\n            val newOpenedSet = HashSet<Any>()\n\n            // 递归遍历新数据的所有节点，包括子节点\n            // Recursively traverse all nodes in new data, including child nodes\n            val allNewNodes = ArrayList<Any>()\n            collectAllNodes(list, allNewNodes)\n\n            oldOpenedSet.forEach { oldNode ->\n                // 在所有新节点中查找匹配的节点（包括子节点）\n                // Find matching node in all new nodes (including child nodes)\n                val matchedNode = allNewNodes.find { isSameNode(it, oldNode) }\n                if (matchedNode != null) {\n                    // 找到匹配的节点，保留展开状态\n                    // Found matching node, preserve expanded state\n                    newOpenedSet.add(matchedNode)\n                }\n            }\n            openedSet.clear()\n            openedSet.addAll(newOpenedSet)\n        }\n\n        val newList = ArrayList<Any>(list)\n\n        // 使用索引遍历，动态处理新添加的元素\n        // Use index traversal to dynamically handle newly added elements\n        var index = 0\n        while (index < newList.size) {\n            val item = newList[index]\n\n            // 只对不在 openedSet 中的节点使用 isInitialOpen 判断\n            // Only use isInitialOpen for nodes not in openedSet\n            if (!openedSet.contains(item)) {\n                if (isInitialOpen(index, item)) {\n                    getChildNodeList(index, item)?.let { children ->\n                        openedSet.add(item)\n\n                        // 在当前位置之后插入子节点\n                        // Insert child nodes after the current position\n                        var insertPosition = index + 1\n                        children.forEach { child ->\n                            newList.add(insertPosition, child)\n                            insertPosition++\n                        }\n                    }\n                }\n            } else {\n                // 节点已经在 openedSet 中（用户手动展开或之前保留的），需要添加子节点\n                // Node is already in openedSet (manually expanded by user or preserved), need to add child nodes\n                getChildNodeList(index, item)?.let { children ->\n                    // 在当前位置之后插入子节点\n                    // Insert child nodes after the current position\n                    var insertPosition = index + 1\n                    children.forEach { child ->\n                        newList.add(insertPosition, child)\n                        insertPosition++\n                    }\n                }\n            }\n\n            // 继续遍历，包括新添加的子节点\n            // Continue traversing, including newly added child nodes\n            index++\n        }\n\n        super.submitList(newList, commitCallback)\n    }\n\n    /**\n     * 递归收集树中的所有节点（包括所有层级的子节点）\n     *\n     * Recursively collect all nodes in the tree (including child nodes at all levels)\n     *\n     * @param nodes 节点列表 / Node list\n     * @param result 结果集合 / Result collection\n     */\n    private fun collectAllNodes(nodes: List<Any>, result: MutableList<Any>) {\n        nodes.forEach { node ->\n            result.add(node)\n\n            // 递归收集子节点\n            // Recursively collect child nodes\n            val children = getChildNodeList(result.size - 1, node)\n            if (!children.isNullOrEmpty()) {\n                collectAllNodes(children, result)\n            }\n        }\n    }\n\n    /**\n     * 查找最后一个可见子节点（递归）\n     *\n     * Find the last visible child node (recursive)\n     *\n     * @param node 要查找的节点 / The node to find\n     * @return 最后一个子节点 / The last child node\n     */\n    private fun findLastChild(node: Any): Any {\n        if (isOpened(node)) {\n            val childList = getChildNodeList(items.indexOfFirst { it === node }, node)\n\n            return if (childList.isNullOrEmpty()) {\n                node\n            } else {\n                findLastChild(childList.last())\n            }\n        } else {\n            return node\n        }\n    }\n\n    /**\n     * 移除列表中所有节点的打开标记（递归）\n     * 注意：此方法需要在从 items 中移除节点列表之前调用\n     *\n     * Remove open flags for all nodes in the list (recursive)\n     * Note: This method should be called before removing the node list from items\n     *\n     * @param list 节点列表 / The node list\n     */\n    private fun removeListOpenFlag(list: List<Any>) {\n        list.forEach { c ->\n            if (isOpened(c)) {\n                openedSet.remove(c)\n\n                val cList = getChildNodeList(items.indexOfFirst { it === c }, c)\n                if (!cList.isNullOrEmpty()) {\n                    removeListOpenFlag(cList)\n                }\n            }\n        }\n    }\n\n    /**\n     * 打开节点。\n     *\n     * Open node.\n     *\n     * @param position 节点位置 / Node position\n     * @param positionPayload 用于刷新的 payload / Payload for refresh\n     * @return 是否成功 / Is success\n     */\n    @JvmOverloads\n    fun open(position: Int, positionPayload: Any? = null): Boolean {\n        if (position < 0) return false\n        val item = items.getOrNull(position) ?: return false\n\n        val child = getChildNodeList(position, item)\n        if (child != null) {\n            // 使用 HashSet 的 contains 方法，性能 O(1)\n            if (!openedSet.contains(item)) {\n                openedSet.add(item)\n                notifyItemChanged(position, positionPayload)\n                addAll(position + 1, child)\n                return true\n            }\n        }\n\n        return false\n    }\n\n    /**\n     * 关闭节点。\n     *\n     * Close node.\n     *\n     * @param position 节点位置 / Node position\n     * @param positionPayload 用于刷新的 payload / Payload for refresh\n     * @return 是否成功 / Is success\n     */\n    @JvmOverloads\n    fun close(position: Int, positionPayload: Any? = null): Boolean {\n        if (position < 0) return false\n        val item = items.getOrNull(position) ?: return false\n\n        val childList = getChildNodeList(position, item)\n        if (!childList.isNullOrEmpty()) {\n            // 先移除打开标记\n            openedSet.remove(item)\n\n            val last = childList.last()\n            val index = if (isOpened(last)) {\n                // 最后一个节点是打开的，需要递归找到最后的子节点\n                // The last node is opened, need to recursively find the last child\n                val node = findLastChild(last)\n                items.indexOfFirst { it === node }\n            } else {\n                // 最后一个节点是关闭的\n                // The last node is closed\n                items.indexOfFirst { it === last }\n            }\n\n            if (index > -1 && index > position) {\n                // 在移除前，先清除所有子节点的打开标记\n                // Before removing, clear open flags for all child nodes\n                removeListOpenFlag(childList)\n                notifyItemChanged(position, positionPayload)\n                removeAtRange(IntRange(position + 1, index))\n                return true\n            }\n        }\n\n        return false\n    }\n\n    /**\n     * 关闭全部的节点\n     *\n     * Close all.\n     */\n    fun closeAll() {\n        // 创建副本遍历，避免并发修改异常\n        // Create a copy for iteration to avoid concurrent modification exception\n        openedSet.toList().forEach { opened ->\n            val position = items.indexOfFirst { it === opened }\n            if (position >= 0) {\n                close(position)\n            }\n        }\n    }\n\n    /**\n     * 打开或关闭节点。\n     *\n     * Open or close.\n     *\n     * @param position adapter 的数据位置 / The data location of the adapter\n     * @return 是否成功 / Is success\n     */\n    fun openOrClose(position: Int): Boolean {\n        val item = items.getOrNull(position) ?: return false\n\n        return if (isOpened(item)) {\n            close(position)\n        } else {\n            open(position)\n        }\n    }\n\n    /**\n     * 是否打开。\n     *\n     * Is opened\n     *\n     * @param item 节点对象 / The node object\n     * @return 是否打开 / Whether opened\n     */\n    fun isOpened(item: Any?): Boolean {\n        if (item == null) return false\n        return openedSet.contains(item)\n    }\n\n    /**\n     * 指定位置的节点是否打开。\n     *\n     * Whether the node at the specified position is opened\n     *\n     * @param position 位置 / Position\n     * @return 是否打开 / Whether opened\n     */\n    fun isOpenedAt(position: Int): Boolean {\n        return isOpened(items.getOrNull(position))\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseQuickAdapter.kt",
    "content": "package com.chad.library.adapter4\n\nimport android.animation.Animator\nimport android.content.Context\nimport android.util.SparseArray\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport androidx.annotation.CallSuper\nimport androidx.annotation.IdRes\nimport androidx.annotation.IntRange\nimport androidx.annotation.LayoutRes\nimport androidx.recyclerview.widget.AdapterListUpdateCallback\nimport androidx.recyclerview.widget.AsyncDifferConfig\nimport androidx.recyclerview.widget.AsyncListDiffer\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.animation.AlphaInAnimation\nimport com.chad.library.adapter4.animation.ItemAnimator\nimport com.chad.library.adapter4.animation.ScaleInAnimation\nimport com.chad.library.adapter4.animation.SlideInBottomAnimation\nimport com.chad.library.adapter4.animation.SlideInLeftAnimation\nimport com.chad.library.adapter4.animation.SlideInRightAnimation\nimport com.chad.library.adapter4.util.asStaggeredGridFullSpan\nimport com.chad.library.adapter4.viewholder.StateLayoutVH\nimport java.util.Collections\n\n/**\n * Base Class\n * @param T : type of data, 数据类型\n * @param VH : ViewHolder\n * @param config: Differ Config\n */\nabstract class BaseQuickAdapter<T : Any, VH : RecyclerView.ViewHolder>(\n    private var _items: List<T>,\n    config: AsyncDifferConfig<T>?\n) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {\n\n    constructor(diffCallback: DiffUtil.ItemCallback<T>) : this(emptyList(), diffCallback)\n\n    constructor(items: List<T>, diffCallback: DiffUtil.ItemCallback<T>) : this(\n        items, AsyncDifferConfig.Builder(diffCallback).build(),\n    )\n\n    constructor(config: AsyncDifferConfig<T>?) : this(emptyList(), config)\n\n    constructor(items: List<T>) : this(items, null)\n\n    constructor() : this(emptyList(), null)\n\n    /********************************* Private property *****************************************/\n    private var mLastPosition = -1\n    private var mOnItemClickListener: OnItemClickListener<T>? = null\n    private var mOnItemLongClickListener: OnItemLongClickListener<T>? = null\n    private var mOnItemChildClickArray: SparseArray<OnItemChildClickListener<T>>? = null\n    private var mOnItemChildLongClickArray: SparseArray<OnItemChildLongClickListener<T>>? = null\n    private var mOnViewAttachStateChangeListeners: MutableList<OnViewAttachStateChangeListener>? =\n        null\n\n    private val mDiffer: AsyncListDiffer<T>? =\n        config?.let { AsyncListDiffer(AdapterListUpdateCallback(this), it) }\n\n\n    private var _recyclerView: RecyclerView? = null\n\n    /**\n     * Items data\n     */\n    var items: List<T>\n        get() {\n            return mDiffer?.currentList ?: _items\n        }\n        set(value) {\n            if (mDiffer != null) {\n                mDiffer.submitList(value, null)\n            } else {\n                val oldItems = _items\n                _items = value\n                onCurrentListChanged(oldItems, _items)\n            }\n        }\n\n    /**\n     * 绑定此 Adapter 的 RecyclerView\n     */\n    val recyclerView: RecyclerView\n        get() {\n            return checkNotNull(_recyclerView) {\n                \"Please get it after onAttachedToRecyclerView()\"\n            }\n        }\n\n    val context: Context\n        get() {\n            return recyclerView.context\n        }\n\n\n    /**\n     * Function to judge if the viewHolder is EmptyLayoutVH.\n     * 判断 ViewHolder 是否是 [StateLayoutVH]\n     *\n     * @receiver RecyclerView.ViewHolder\n     * @return Boolean\n     */\n    inline val RecyclerView.ViewHolder.isEmptyViewHolder: Boolean\n        get() = this is StateLayoutVH\n\n    /**\n     *  Whether to use empty layout.\n     *  是否使用空布局。\n     * */\n    @Deprecated(\"使用 isStateViewEnable\", ReplaceWith(\"isStateViewEnable\"))\n    var isEmptyViewEnable\n        set(value) {\n            isStateViewEnable = value\n        }\n        get() = isStateViewEnable\n\n    /**\n     *  Whether to use state layout.\n     *  是否使用状态布局。\n     * */\n    var isStateViewEnable = false\n        set(value) {\n            val oldDisplayEmptyLayout = displayEmptyView()\n\n            field = value\n\n            val newDisplayEmptyLayout = displayEmptyView()\n\n            if (oldDisplayEmptyLayout && !newDisplayEmptyLayout) {\n                notifyItemRemoved(0)\n            } else if (newDisplayEmptyLayout && !oldDisplayEmptyLayout) {\n                notifyItemInserted(0)\n            } else if (oldDisplayEmptyLayout && newDisplayEmptyLayout) {\n                notifyItemChanged(0, EMPTY_PAYLOAD)\n            }\n        }\n\n    /**\n     * State view. Attention please: take effect when [items] is empty array.\n     * 状态视图，注意：[items]为空数组才会生效\n     */\n    var stateView: View? = null\n        set(value) {\n            val oldDisplayEmptyLayout = displayEmptyView()\n\n            field = value\n\n            val newDisplayEmptyLayout = displayEmptyView()\n\n            if (oldDisplayEmptyLayout && !newDisplayEmptyLayout) {\n                notifyItemRemoved(0)\n            } else if (newDisplayEmptyLayout && !oldDisplayEmptyLayout) {\n                notifyItemInserted(0)\n            } else if (oldDisplayEmptyLayout && newDisplayEmptyLayout) {\n                notifyItemChanged(0, EMPTY_PAYLOAD)\n            }\n        }\n\n    /**\n     * 是否使用状态布局的尺寸。\n     *\n     * Whether to use the dimensions of the state layout.\n     */\n    var isUseStateViewSize = false\n\n    /**\n     * Empty view. Attention please: take effect when [items] is empty array.\n     * 空视图，注意：[items]为空数组才会生效\n     */\n    @Deprecated(\"使用 stateView\", ReplaceWith(\"stateView\"))\n    var emptyView: View?\n        set(value) {\n            stateView = value\n        }\n        get() = stateView\n\n    /**\n     * Whether enable animation.\n     * 是否打开动画\n     */\n    var animationEnable: Boolean = false\n\n    /**\n     * Whether the animation executed only the first time.\n     * 动画是否仅第一次执行\n     */\n    var isAnimationFirstOnly = true\n\n    /**\n     * Set custom animation.\n     * 设置自定义动画\n     */\n    var itemAnimation: ItemAnimator? = null\n        set(value) {\n            animationEnable = true\n            field = value\n        }\n\n    init {\n        mDiffer?.let {\n            mDiffer.addListListener { previousList, currentList ->\n                val oldDisplayEmptyLayout = displayEmptyView(previousList)\n                val newDisplayEmptyLayout = displayEmptyView(currentList)\n\n                if (oldDisplayEmptyLayout && !newDisplayEmptyLayout) {\n                    notifyItemRemoved(0)\n                    recyclerView.scrollToPosition(0)\n                } else if (newDisplayEmptyLayout && !oldDisplayEmptyLayout) {\n                    notifyItemInserted(0)\n                } else if (oldDisplayEmptyLayout && newDisplayEmptyLayout) {\n                    notifyItemChanged(0, EMPTY_PAYLOAD)\n                }\n\n                this.onCurrentListChanged(previousList, currentList)\n            }\n\n            it.submitList(_items)\n        }\n    }\n\n\n\n    protected abstract fun onCreateViewHolder(\n        context: Context, parent: ViewGroup, viewType: Int\n    ): VH\n\n    /**\n     * Implement this method and use the helper to adapt the view to the given item.\n     *\n     * 实现此方法，并使用 [holder] 完成 item 视图的操作\n     *\n     * @param holder A fully initialized helper.\n     * @param item   The item that needs to be displayed.\n     */\n    protected abstract fun onBindViewHolder(holder: VH, position: Int, item: T?)\n\n    /**\n     * Optional implementation this method and use the helper to adapt the view to the given item.\n     * If use [payloads], will perform this method, Please implement this method for partial refresh.\n     * If use [RecyclerView.Adapter.notifyItemChanged(Int, Object)] with payload,\n     * Will execute this method.\n     *\n     * 可选实现，如果你是用了[payloads]刷新item，请实现此方法，进行局部刷新\n     *\n     * @param holder   A fully initialized helper.\n     * @param item     The item that needs to be displayed.\n     * @param payloads payload info.\n     */\n    protected open fun onBindViewHolder(holder: VH, position: Int, item: T?, payloads: List<Any>) {\n        onBindViewHolder(holder, position, item)\n    }\n\n    /**\n     * Override this method and return your item size.\n     * 重写此方法，返回你的item数量。\n     */\n    protected open fun getItemCount(items: List<T>): Int {\n        return items.size\n    }\n\n    /**\n     * Override this method and return your ViewType.\n     * 重写此方法，返回你的ViewType。\n     */\n    protected open fun getItemViewType(position: Int, list: List<T>): Int = 0\n\n    /**\n     * Don't override this method.\n     *\n     * 不要重写此方法.\n     *\n     * @return Int\n     */\n    final override fun getItemCount(): Int {\n        return if (displayEmptyView()) {\n            1\n        } else {\n            getItemCount(items)\n        }\n    }\n\n    /**\n     * Don't override this method.\n     *\n     * 不要重写此方法\n     *\n     * @param position Int\n     * @return Int\n     */\n    final override fun getItemViewType(position: Int): Int {\n        if (displayEmptyView()) return EMPTY_VIEW\n        return getItemViewType(position, items)\n    }\n\n    final override fun onCreateViewHolder(\n        parent: ViewGroup, viewType: Int\n    ): RecyclerView.ViewHolder {\n        if (viewType == EMPTY_VIEW) {\n            return StateLayoutVH(parent, stateView, isUseStateViewSize)\n        }\n\n        return onCreateViewHolder(parent.context, parent, viewType).apply {\n            bindViewClickListener(this, viewType)\n        }\n    }\n\n    final override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\n        if (holder is StateLayoutVH) {\n            holder.changeStateView(stateView, isUseStateViewSize)\n            return\n        }\n\n        onBindViewHolder(holder as VH, position, getItemOrNull(position))\n    }\n\n    final override fun onBindViewHolder(\n        holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>\n    ) {\n        if (payloads.isEmpty()) {\n            onBindViewHolder(holder, position)\n            return\n        }\n\n        if (holder is StateLayoutVH) {\n            holder.changeStateView(stateView, isUseStateViewSize)\n            return\n        }\n\n        onBindViewHolder(holder as VH, position, getItemOrNull(position), payloads)\n    }\n\n    override fun getItemId(position: Int): Long {\n        return position.toLong()\n    }\n\n    /**\n     * 当 ViewHolder 视图已附加到窗口时调用。\n     *\n     * Called when a view created by this holder has been attached to a window.\n     * simple to solve item will layout using all.\n     *\n     * [asStaggeredGridFullSpan]\n     *\n     * @param holder\n     */\n    @CallSuper\n    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {\n        super.onViewAttachedToWindow(holder)\n\n        if (holder is StateLayoutVH || isFullSpanItem(getItemViewType(holder.bindingAdapterPosition))) {\n            holder.asStaggeredGridFullSpan()\n        } else {\n            runAnimator(holder)\n        }\n\n        mOnViewAttachStateChangeListeners?.forEach {\n            it.onViewAttachedToWindow(holder)\n        }\n    }\n\n    @CallSuper\n    override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {\n        mOnViewAttachStateChangeListeners?.forEach {\n            it.onViewDetachedFromWindow(holder)\n        }\n    }\n\n    @CallSuper\n    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {\n        _recyclerView = recyclerView\n    }\n\n    @CallSuper\n    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {\n        _recyclerView = null\n    }\n\n\n    /**\n     * 绑定 item 点击事件\n     * @param viewHolder VH\n     */\n    protected open fun bindViewClickListener(viewHolder: VH, viewType: Int) {\n        mOnItemClickListener?.let {\n            viewHolder.itemView.setOnClickListener { v ->\n                val position = viewHolder.bindingAdapterPosition\n                if (position == RecyclerView.NO_POSITION) {\n                    return@setOnClickListener\n                }\n                onItemClick(v, position)\n            }\n        }\n        mOnItemLongClickListener?.let {\n            viewHolder.itemView.setOnLongClickListener { v ->\n                val position = viewHolder.bindingAdapterPosition\n                if (position == RecyclerView.NO_POSITION) {\n                    return@setOnLongClickListener false\n                }\n                onItemLongClick(v, position)\n            }\n        }\n\n        mOnItemChildClickArray?.let {\n            for (i in 0 until it.size()) {\n                val id = it.keyAt(i)\n\n                viewHolder.itemView.findViewById<View>(id)?.let { childView ->\n                    childView.setOnClickListener { v ->\n                        val position = viewHolder.bindingAdapterPosition\n                        if (position == RecyclerView.NO_POSITION) {\n                            return@setOnClickListener\n                        }\n                        onItemChildClick(v, position)\n                    }\n                }\n            }\n        }\n\n        mOnItemChildLongClickArray?.let {\n            for (i in 0 until it.size()) {\n                val id = it.keyAt(i)\n\n                viewHolder.itemView.findViewById<View>(id)?.let { childView ->\n                    childView.setOnLongClickListener { v ->\n                        val position = viewHolder.bindingAdapterPosition\n                        if (position == RecyclerView.NO_POSITION) {\n                            return@setOnLongClickListener false\n                        }\n                        onItemChildLongClick(v, position)\n                    }\n                }\n            }\n        }\n\n    }\n\n    /**\n     * override this method if you want to override click event logic.\n     *\n     * 如果你想重新实现 item 点击事件逻辑，请重写此方法.\n     * @param v\n     * @param position\n     */\n    protected open fun onItemClick(v: View, position: Int) {\n        mOnItemClickListener?.onClick(this, v, position)\n    }\n\n    /**\n     * override this method if you want to override longClick event logic.\n     *\n     * 如果你想重新实现 item 长按事件逻辑，请重写此方法.\n     *\n     * @param v\n     * @param position\n     * @return\n     */\n    protected open fun onItemLongClick(v: View, position: Int): Boolean {\n        return mOnItemLongClickListener?.onLongClick(this, v, position) ?: false\n    }\n\n    protected open fun onItemChildClick(v: View, position: Int) {\n        mOnItemChildClickArray?.get(v.id)?.onItemClick(this, v, position)\n    }\n\n    protected open fun onItemChildLongClick(v: View, position: Int): Boolean {\n        return mOnItemChildLongClickArray?.get(v.id)?.onItemLongClick(this, v, position)\n            ?: false\n    }\n\n\n    /**\n     * Is full span item.\n     *\n     * 是否是完整跨度的item。\n     *\n     * @param itemType\n     * @return\n     */\n    open fun isFullSpanItem(itemType: Int): Boolean {\n        return itemType == EMPTY_VIEW\n    }\n\n    /**\n     * Get the data item associated with the specified position in the data set.\n     *\n     * 获取与数据集中指定位置的数据项。\n     *\n     * @param position Position of the item whose data we want within the adapter's\n     * data set.\n     * @return The data at the specified position.\n     */\n    open fun getItem(@IntRange(from = 0) position: Int): T = items[position]\n\n    /**\n     * Get the data item associated with the specified position in the data set.\n     *\n     * 获取与数据集中指定位置的数据项。如果未找到数据，则返回 null。\n     *\n     * @param position Position of the item whose data we want within the adapter's\n     * data set.\n     * @return The data at the specified position.\n     */\n    open fun getItemOrNull(@IntRange(from = 0) position: Int): T? = items.getOrNull(position)\n\n    /**\n     * 获取对应首个匹配的 item 数据的索引。如果返回 -1，表示不存在\n     * @param item T\n     * @return Int\n     */\n    fun itemIndexOfFirst(item: T): Int {\n        return items.indexOfFirst { item == it }\n    }\n\n    /**\n     * Set state view layout.\n     *\n     * 状态视图的布局id.\n     *\n     * @param layoutResId\n     */\n    fun setStateViewLayout(context: Context, @LayoutRes layoutResId: Int) {\n        stateView = LayoutInflater.from(context).inflate(layoutResId, FrameLayout(context), false)\n    }\n\n    /**\n     * Set empty view layout.\n     *\n     * 空视图的布局id。\n     *\n     * @param layoutResId\n     */\n    @Deprecated(\"使用 setStateViewLayout()\", replaceWith = ReplaceWith(\"setStateViewLayout(context, layoutResId)\"))\n    fun setEmptyViewLayout(context: Context, @LayoutRes layoutResId: Int) {\n        setStateViewLayout(context, layoutResId)\n    }\n\n    /**\n     * 判断是否能显示“空状态”布局\n     */\n    fun displayEmptyView(list: List<T> = items): Boolean {\n        if (stateView == null || !isStateViewEnable) return false\n        return list.isEmpty()\n    }\n\n    /**\n     * Run animation when you want to show time.\n     *\n     * @param holder\n     */\n    private fun runAnimator(holder: RecyclerView.ViewHolder) {\n        if (animationEnable) {\n            if (!isAnimationFirstOnly || holder.layoutPosition > mLastPosition) {\n                val animation: ItemAnimator = itemAnimation ?: AlphaInAnimation()\n                animation.animator(holder.itemView).apply {\n                    startItemAnimator(this, holder)\n                }\n                mLastPosition = holder.layoutPosition\n            }\n        }\n    }\n\n    /**\n     * Start executing animation.\n     * Override this method to execute more actions.\n     *\n     * 开始执行动画方法。\n     * 可以重写此方法，实行更多行为。\n     *\n     * @param anim\n     * @param holder\n     */\n    protected open fun startItemAnimator(anim: Animator, holder: RecyclerView.ViewHolder) {\n        anim.start()\n    }\n\n    /**\n     * use preset animations\n     *\n     * 使用内置默认动画设置\n     *\n     * @param animationType AnimationType\n     */\n    fun setItemAnimation(animationType: AnimationType) {\n        itemAnimation = when (animationType) {\n            AnimationType.AlphaIn -> AlphaInAnimation()\n            AnimationType.ScaleIn -> ScaleInAnimation()\n            AnimationType.SlideInBottom -> SlideInBottomAnimation()\n            AnimationType.SlideInLeft -> SlideInLeftAnimation()\n            AnimationType.SlideInRight -> SlideInRightAnimation()\n        }\n    }\n\n    /**\n     * (Optional) Override this method to monitor changes in the dataset before and after.\n     *\n     * （可选）重写此方法，监听前后数据集变化.\n     *\n     * @param previousList 原数据集\n     * @param currentList 当前数据集\n     */\n    open fun onCurrentListChanged(previousList: List<T>, currentList: List<T>) {}\n\n    /**\n     * setting up a new instance to data;\n     *\n     * 设置新的数据集合\n     *\n     * @param list 新数据集\n     */\n    @JvmOverloads\n    open fun submitList(list: List<T>?, commitCallback: Runnable? = null) {\n        if (mDiffer == null) {\n            val newList = list ?: emptyList()\n\n            mLastPosition = -1\n\n            val oldDisplayEmptyLayout = displayEmptyView()\n            val newDisplayEmptyLayout = displayEmptyView(newList)\n\n            val oldItem = _items\n\n            if (oldDisplayEmptyLayout && !newDisplayEmptyLayout) {\n                _items = newList\n                notifyItemRemoved(0)\n                notifyItemRangeInserted(0, newList.size)\n            } else if (newDisplayEmptyLayout && !oldDisplayEmptyLayout) {\n                notifyItemRangeRemoved(0, _items.size)\n                _items = newList\n                notifyItemInserted(0)\n            } else if (oldDisplayEmptyLayout && newDisplayEmptyLayout) {\n                _items = newList\n                notifyItemChanged(0, EMPTY_PAYLOAD)\n            } else {\n                _items = newList\n                notifyDataSetChanged()\n            }\n\n            onCurrentListChanged(oldItem, _items)\n            commitCallback?.run()\n        } else {\n            // Diff的逻辑\n            mDiffer.submitList(list, commitCallback)\n        }\n    }\n\n    /**\n     * change data\n     * 改变某一位置数据\n     */\n    open operator fun set(@IntRange(from = 0) position: Int, data: T) {\n        set(position, data,null, null)\n    }\n\n    open fun set(\n        @IntRange(from = 0) position: Int,\n        data: T,\n        payload: Any? = null,\n        commitCallback: Runnable? = null,\n    ) {\n        if (position >= items.size) {\n            throw IndexOutOfBoundsException(\"position: ${position}. size:${items.size}\")\n        }\n\n        if (mDiffer == null) {\n            mutableItems[position] = data\n            notifyItemChanged(position, payload)\n\n            commitCallback?.run()\n        } else {\n            // Diff的逻辑\n            mDiffer.currentList.toMutableList().also {\n                it[position] = data\n                mDiffer.submitList(it, commitCallback)\n            }\n        }\n    }\n\n    /**\n     * add one new data in to certain location\n     * 在指定位置添加一条新数据\n     *\n     * @param position\n     */\n    @JvmOverloads\n    open fun add(@IntRange(from = 0) position: Int, data: T, commitCallback: Runnable? = null) {\n        if (position > items.size || position < 0) {\n            throw IndexOutOfBoundsException(\"position: ${position}. size:${items.size}\")\n        }\n\n        if (mDiffer == null) {\n            if (displayEmptyView()) {\n                // 如果之前在显示空布局，需要先移除\n                notifyItemRemoved(0)\n            }\n            mutableItems.add(position, data)\n            notifyItemInserted(position)\n\n            commitCallback?.run()\n        } else {\n            // Diff的逻辑\n            mDiffer.currentList.toMutableList().also {\n                it.add(position, data)\n                mDiffer.submitList(it, commitCallback)\n            }\n        }\n    }\n\n    /**\n     * add one new data，not null.\n     * 添加一条新数据，不可为 null。\n     */\n    @JvmOverloads\n    open fun add(data: T, commitCallback: Runnable? = null) {\n        if (mDiffer == null) {\n            if (displayEmptyView()) {\n                // 如果之前在显示空布局，需要先移除\n                notifyItemRemoved(0)\n            }\n            if (mutableItems.add(data)) {\n                notifyItemInserted(_items.size - 1)\n            }\n\n            commitCallback?.run()\n        } else {\n            // Diff的逻辑\n            mDiffer.currentList.toMutableList().also {\n                it.add(data)\n                mDiffer.submitList(it, commitCallback)\n            }\n        }\n    }\n\n    /**\n     * add new data in to certain location\n     * 在指定位置添加数据\n     *\n     * @param position the insert position\n     * @param collection  the new data collection\n     */\n    @JvmOverloads\n    open fun addAll(@IntRange(from = 0) position: Int, collection: Collection<T>, commitCallback: Runnable? = null) {\n        if (position > items.size || position < 0) {\n            throw IndexOutOfBoundsException(\"position: ${position}. size:${items.size}\")\n        }\n\n        if (collection.isEmpty()) {\n            commitCallback?.run()\n            return\n        }\n\n        if (mDiffer == null) {\n            if (displayEmptyView()) {\n                // 如果之前在显示空布局，需要先移除\n                notifyItemRemoved(0)\n            }\n            if (mutableItems.addAll(position, collection)) {\n                notifyItemRangeInserted(position, collection.size)\n            }\n\n            commitCallback?.run()\n        } else {\n            // Diff的逻辑\n            mDiffer.currentList.toMutableList().also {\n                it.addAll(position, collection)\n                mDiffer.submitList(it, commitCallback)\n            }\n        }\n    }\n\n    /**\n     * 添加一组数据，不可为 null。\n     */\n    @JvmOverloads\n    open fun addAll(collection: Collection<T>, commitCallback: Runnable? = null) {\n        if (collection.isEmpty()) {\n            commitCallback?.run()\n            return\n        }\n\n        if (mDiffer == null) {\n            if (displayEmptyView()) {\n                // 如果之前在显示空布局，需要先移除\n                notifyItemRemoved(0)\n            }\n\n            val oldSize = _items.size\n            if (mutableItems.addAll(collection)) {\n                notifyItemRangeInserted(oldSize, collection.size)\n            }\n\n            commitCallback?.run()\n        } else {\n            // Diff的逻辑\n            mDiffer.currentList.toMutableList().also {\n                it.addAll(collection)\n                mDiffer.submitList(it, commitCallback)\n            }\n        }\n    }\n\n    /**\n     * remove the item associated with the specified position of adapter\n     * 删除指定位置的数据\n     *\n     * @param position\n     */\n    @JvmOverloads\n    open fun removeAt(@IntRange(from = 0) position: Int, commitCallback: Runnable? = null) {\n        if (position >= items.size) {\n            throw IndexOutOfBoundsException(\"position: ${position}. size:${items.size}\")\n        }\n\n        if (mDiffer == null) {\n            mutableItems.removeAt(position)\n            notifyItemRemoved(position)\n\n            // 处理空视图的情况\n            if (displayEmptyView()) {\n                notifyItemInserted(0)\n            }\n\n            commitCallback?.run()\n        } else {\n            mDiffer.currentList.toMutableList().also {\n                it.removeAt(position)\n                mDiffer.submitList(it, commitCallback)\n            }\n        }\n    }\n\n    /**\n     * 删除数据\n     *\n     * @param data\n     */\n    @JvmOverloads\n    open fun remove(data: T, commitCallback: Runnable? = null) {\n        if (mDiffer == null) {\n            val index = _items.indexOf(data)\n            if (index == -1) return\n            removeAt(index)\n\n            commitCallback?.run()\n        } else {\n            mDiffer.currentList.toMutableList().also {\n                it.remove(data)\n                mDiffer.submitList(it, commitCallback)\n            }\n        }\n    }\n\n    /**\n     * 删除给定范围内的数据\n     *\n     * @param range Int 索引范围\n     */\n    @JvmOverloads\n    open fun removeAtRange(range: kotlin.ranges.IntRange, commitCallback: Runnable? = null) {\n        if (range.isEmpty()) {\n            return\n        }\n        if (range.first >= items.size) {\n            throw IndexOutOfBoundsException(\"Range first position: ${range.first} - last position: ${range.last}. size:${items.size}\")\n        }\n\n        val last = if (range.last >= items.size) {\n            items.size - 1\n        } else {\n            range.last\n        }\n\n        if (mDiffer == null) {\n            mutableItems.subList(range.first, last + 1).clear()\n\n            notifyItemRangeRemoved(range.first, last - range.first + 1)\n\n            // 处理空视图的情况\n            if (displayEmptyView()) {\n                notifyItemInserted(0)\n            }\n\n            commitCallback?.run()\n        } else {\n            val list = mDiffer.currentList.toMutableList()\n            list.subList(range.first, last + 1).clear()\n            mDiffer.submitList(list, commitCallback)\n        }\n    }\n\n    /**\n     * Item swap\n     * 数据位置交换。这里单纯的只是两个数据交换位置。（注意⚠️，这里移动后的数据顺序与 [move] 不同)\n     *\n     * @param fromPosition\n     * @param toPosition\n     */\n    @JvmOverloads\n    open fun swap(fromPosition: Int, toPosition: Int, commitCallback: Runnable? = null) {\n        if (mDiffer == null) {\n            if (fromPosition in _items.indices && toPosition in _items.indices) {\n                Collections.swap(_items, fromPosition, toPosition)\n                notifyItemChanged(fromPosition)\n                notifyItemChanged(toPosition)\n\n                commitCallback?.run()\n            }\n        } else {\n            val list = mDiffer.currentList\n            if (fromPosition in list.indices && toPosition in list.indices) {\n                list.toMutableList().also {\n                    Collections.swap(it, fromPosition, toPosition)\n                    mDiffer.submitList(it, commitCallback)\n                }\n            }\n        }\n    }\n\n    /**\n     * Move Item\n     * item 位置的移动。（注意⚠️，这里移动后的数据顺序与 [swap] 不同)\n     *\n     * @param fromPosition\n     * @param toPosition\n     */\n    @JvmOverloads\n    open fun move(fromPosition: Int, toPosition: Int, commitCallback: Runnable? = null) {\n        if (mDiffer == null) {\n            if (fromPosition in _items.indices && toPosition in _items.indices) {\n                val e = mutableItems.removeAt(fromPosition)\n                mutableItems.add(toPosition, e)\n                notifyItemMoved(fromPosition, toPosition)\n\n                commitCallback?.run()\n            }\n        } else {\n            val list = mDiffer.currentList\n            if (fromPosition in list.indices || toPosition in list.indices) {\n                list.toMutableList().also {\n                    val e = it.removeAt(fromPosition)\n                    it.add(toPosition, e)\n                    mDiffer.submitList(it, commitCallback)\n                }\n            }\n        }\n    }\n\n    /**\n     * _items 转化为 MutableList\n     */\n    private val mutableItems: MutableList<T>\n        get() {\n            return when (_items) {\n                is java.util.AbstractList -> {\n                    _items as java.util.AbstractList\n                }\n                is MutableList -> {\n                    _items as MutableList\n                }\n                else -> {\n                    _items.toMutableList().apply { _items = this }\n                }\n            }\n        }\n\n    /************************************** Set Listener ****************************************/\n\n    fun setOnItemClickListener(listener: OnItemClickListener<T>?) = apply {\n        this.mOnItemClickListener = listener\n    }\n\n    fun getOnItemClickListener(): OnItemClickListener<T>? = mOnItemClickListener\n\n    fun setOnItemLongClickListener(listener: OnItemLongClickListener<T>?)  = apply {\n        this.mOnItemLongClickListener = listener\n    }\n\n    fun getOnItemLongClickListener(): OnItemLongClickListener<T>? = mOnItemLongClickListener\n\n    fun addOnItemChildClickListener(@IdRes id: Int, listener: OnItemChildClickListener<T>) = apply {\n        mOnItemChildClickArray =\n            (mOnItemChildClickArray ?: SparseArray<OnItemChildClickListener<T>>(2)).apply {\n                put(id, listener)\n            }\n    }\n\n    fun removeOnItemChildClickListener(@IdRes id: Int) = apply {\n        mOnItemChildClickArray?.remove(id)\n    }\n\n    fun addOnItemChildLongClickListener(@IdRes id: Int, listener: OnItemChildLongClickListener<T>) =\n        apply {\n            mOnItemChildLongClickArray = (mOnItemChildLongClickArray ?: SparseArray<OnItemChildLongClickListener<T>>(2)).apply {\n                put(id, listener)\n            }\n        }\n\n    fun removeOnItemChildLongClickListener(@IdRes id: Int) = apply {\n        mOnItemChildLongClickArray?.remove(id)\n    }\n\n    fun addOnViewAttachStateChangeListener(listener: OnViewAttachStateChangeListener) = apply {\n        mOnViewAttachStateChangeListeners =\n            (mOnViewAttachStateChangeListeners ?: ArrayList()).apply {\n                if (!this.contains(listener)) {\n                    this += listener\n                }\n            }\n    }\n\n    fun removeOnViewAttachStateChangeListener(listener: OnViewAttachStateChangeListener) {\n        mOnViewAttachStateChangeListeners?.remove(listener)\n    }\n\n    fun clearOnViewAttachStateChangeListener() {\n        mOnViewAttachStateChangeListeners?.clear()\n    }\n\n    /**\n     * 内置默认动画类型\n     */\n    enum class AnimationType {\n        AlphaIn, ScaleIn, SlideInBottom, SlideInLeft, SlideInRight\n    }\n\n    interface OnViewAttachStateChangeListener {\n\n        /**\n         * Called when a view is attached to the RecyclerView.\n         */\n        fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder)\n\n        /**\n         * Called when a view is detached from RecyclerView.\n         */\n        fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder)\n    }\n\n\n    fun interface OnItemClickListener<T : Any> {\n        fun onClick(adapter: BaseQuickAdapter<T, *>, view: View, position: Int)\n    }\n\n    fun interface OnItemLongClickListener<T : Any> {\n        fun onLongClick(adapter: BaseQuickAdapter<T, *>, view: View, position: Int): Boolean\n    }\n\n    fun interface OnItemChildClickListener<T : Any> {\n        fun onItemClick(adapter: BaseQuickAdapter<T, *>, view: View, position: Int)\n    }\n\n    fun interface OnItemChildLongClickListener<T : Any> {\n        fun onItemLongClick(adapter: BaseQuickAdapter<T, *>, view: View, position: Int): Boolean\n    }\n\n\n    companion object {\n        val EMPTY_VIEW = R.id.BaseQuickAdapter_empty_view\n\n        internal const val EMPTY_PAYLOAD = 0\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/BaseSingleItemAdapter.kt",
    "content": "package com.chad.library.adapter4\n\nimport androidx.recyclerview.widget.RecyclerView\n\n/**\n * Adapter for single item\n * 只有单个/一个 item 情况下的 Adapter\n *\n * @param T 数据类型 type of data\n * @param VH viewHolder类型 type of the viewHolder\n * @property mItem 数据 data\n */\nabstract class BaseSingleItemAdapter<T : Any, VH : RecyclerView.ViewHolder>(private var mItem: T? = null) :\n    BaseQuickAdapter<Any, VH>() {\n\n    protected abstract fun onBindViewHolder(holder: VH, item: T?)\n\n    open fun onBindViewHolder(holder: VH, item: T?, payloads: List<Any>) {\n        onBindViewHolder(holder, item)\n    }\n\n    final override fun onBindViewHolder(holder: VH, position: Int, item: Any?) {\n        onBindViewHolder(holder, mItem)\n    }\n\n    final override fun onBindViewHolder(holder: VH, position: Int, item: Any?, payloads: List<Any>) {\n        onBindViewHolder(holder, mItem, payloads)\n    }\n\n    final override fun getItemCount(items: List<Any>): Int {\n        return 1\n    }\n\n    /**\n     * 设置 item 数据（payload 方式）\n     *\n     * @param t\n     * @param payload\n     */\n    fun setItem(t: T?, payload: Any?) {\n        mItem = t\n        notifyItemChanged(0, payload)\n    }\n\n    /**\n     * 获取/设置 item 数据\n     */\n    var item: T?\n        get() = mItem\n        set(value) {\n            mItem = value\n            notifyItemChanged(0)\n        }\n\n    override fun submitList(list: List<Any>?, commitCallback: Runnable?) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n\n    override fun add(data: Any, commitCallback: Runnable?) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n\n    override fun add(position: Int, data: Any, commitCallback: Runnable?) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n\n    override fun addAll(collection: Collection<Any>, commitCallback: Runnable?) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n\n    override fun addAll(position: Int, collection: Collection<Any>, commitCallback: Runnable?) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n\n    override fun remove(data: Any, commitCallback: Runnable?) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n\n    override fun removeAtRange(range: IntRange, commitCallback: Runnable?) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n\n    override fun removeAt(position: Int, commitCallback: Runnable?) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n\n    override fun set(position: Int, data: Any) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n\n    override fun set(position: Int, data: Any, payload: Any?, commitCallback: Runnable?) {\n        throw RuntimeException(\"Please use setItem()\")\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/QuickAdapterHelper.kt",
    "content": "package com.chad.library.adapter4\n\nimport androidx.recyclerview.widget.ConcatAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.loadState.LoadState\nimport com.chad.library.adapter4.loadState.leading.DefaultLeadingLoadStateAdapter\nimport com.chad.library.adapter4.loadState.leading.LeadingLoadStateAdapter\nimport com.chad.library.adapter4.loadState.trailing.DefaultTrailingLoadStateAdapter\nimport com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter\nimport java.util.Collections\n\n/**\n * 用于组合 Adapter 的帮助类，生成一个 [ConcatAdapter]。\n *\n * 结构如下:\n *\n *                            ConcatAdapter\n * ｜-----------------------------------------------------------------｜\n * ｜                                                                 ｜\n * ｜         leadingLoadStateAdapter 或者 BeforeAdapter               ｜\n * ｜                                                                 ｜\n * ｜-----------------------------------------------------------------｜\n * ｜                                                                 ｜\n * ｜                                                                 ｜\n * ｜                        contentAdapter（内容）                    ｜\n * ｜                                                                 ｜\n * ｜                                                                 ｜\n * ｜-----------------------------------------------------------------｜\n * ｜                                                                 ｜\n * ｜         trailingLoadStateAdapter 或者 AfterAdapter               ｜\n * ｜                                                                 ｜\n * ｜-----------------------------------------------------------------｜\n *\n * 使用时，请获取此 Helper 提供的 Adapter：\n * ```\n * val helper = QuickAdapterHelper.Builder(...).build()\n *\n * recyclerView.adapter = helper.adapter\n * ```\n *\n * @property contentAdapter\n * @property leadingLoadStateAdapter\n * @property trailingLoadStateAdapter\n *\n * @param config\n */\nclass QuickAdapterHelper private constructor(\n    val contentAdapter: BaseQuickAdapter<*, *>,\n\n    /**\n     * Adapter for loading more at the head.\n     * 首部\"加载跟多\"Adapter\n     */\n    val leadingLoadStateAdapter: LeadingLoadStateAdapter<*>?,\n\n    /**\n     * Adapter for loading more at the tail.\n     * 尾部\"加载跟多\"Adapter\n     */\n    val trailingLoadStateAdapter: TrailingLoadStateAdapter<*>?,\n\n    config: ConcatAdapter.Config\n) {\n\n    private val mBeforeList = ArrayList<BaseQuickAdapter<*, *>>(0)\n    private val mAfterList = ArrayList<BaseQuickAdapter<*, *>>(0)\n\n    /**\n     * The adapter which is finally attached to the RecyclerView.\n     * 最终设置给 RecyclerView 的 adapter\n     */\n    private val mAdapter = ConcatAdapter(config)\n\n    /**\n     * 获取 Adapter\n     */\n    val adapter: ConcatAdapter get() = mAdapter\n\n    /**\n     * Loading state of the head.\n     * 首部的加载状态\n     */\n    var leadingLoadState: LoadState\n        set(value) {\n            leadingLoadStateAdapter?.loadState = value\n        }\n        get() {\n            return leadingLoadStateAdapter?.loadState\n                ?: LoadState.NotLoading(endOfPaginationReached = false)\n        }\n\n    /**\n     * Loading state of the tail.\n     * 尾部的加载状态\n     */\n    var trailingLoadState: LoadState\n        set(value) {\n            trailingLoadStateAdapter?.loadState = value\n        }\n        get() {\n            return trailingLoadStateAdapter?.loadState\n                ?: LoadState.NotLoading(endOfPaginationReached = false)\n        }\n\n    private var firstAdapterOnViewAttachChangeListener: BaseQuickAdapter.OnViewAttachStateChangeListener? =\n        null\n    private var lastAdapterOnViewAttachChangeListener: BaseQuickAdapter.OnViewAttachStateChangeListener? =\n        null\n\n    init {\n        leadingLoadStateAdapter?.let {\n            mAdapter.addAdapter(it)\n\n            firstAdapterOnViewAttachChangeListener =\n                object : BaseQuickAdapter.OnViewAttachStateChangeListener {\n\n                    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {\n                        leadingLoadStateAdapter.checkPreload(holder.bindingAdapterPosition)\n                    }\n\n                    override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {\n\n                    }\n                }.apply { contentAdapter.addOnViewAttachStateChangeListener(this) }\n        }\n\n        mAdapter.addAdapter(contentAdapter)\n\n        trailingLoadStateAdapter?.let {\n            mAdapter.addAdapter(it)\n\n            lastAdapterOnViewAttachChangeListener =\n                object : BaseQuickAdapter.OnViewAttachStateChangeListener {\n\n                    override fun onViewAttachedToWindow(holder: RecyclerView.ViewHolder) {\n                        trailingLoadStateAdapter.checkPreload(\n                            holder.bindingAdapter?.itemCount ?: 0,\n                            holder.bindingAdapterPosition\n                        )\n                    }\n\n                    override fun onViewDetachedFromWindow(holder: RecyclerView.ViewHolder) {\n\n                    }\n                }.apply { contentAdapter.addOnViewAttachStateChangeListener(this) }\n        }\n    }\n\n    /**\n     * Add Adapter before [contentAdapter].\n     * 在 [contentAdapter] 之前添加 Adapter\n     *\n     * @param adapter Adapter<*>\n     */\n    fun addBeforeAdapter(adapter: BaseQuickAdapter<*, *>) = apply {\n        addBeforeAdapter(mBeforeList.size, adapter)\n    }\n\n    /**\n     * Add Adapter before [contentAdapter].\n     * 在 [contentAdapter] 之前添加 Adapter\n     *\n     * @param index 相对于 [contentAdapter] 的位置索引\n     * @param adapter\n     */\n    fun addBeforeAdapter(index: Int, adapter: BaseQuickAdapter<*, *>) = apply {\n        if (index < 0 || index > mBeforeList.size) throw IndexOutOfBoundsException(\"Index must be between 0 and ${mBeforeList.size}. Given:${index}\")\n\n        if (index == 0) {\n            firstAdapterOnViewAttachChangeListener?.let {\n                if (mBeforeList.isEmpty()) {\n                    contentAdapter.removeOnViewAttachStateChangeListener(it)\n                } else {\n                    mBeforeList.first().removeOnViewAttachStateChangeListener(it)\n                }\n                adapter.addOnViewAttachStateChangeListener(it)\n            }\n        }\n\n        val realIndex = if (leadingLoadStateAdapter == null) {\n            index\n        } else {\n            index + 1\n        }\n\n       if (mAdapter.addAdapter(realIndex, adapter)) {\n           mBeforeList += adapter\n       }\n    }\n\n    /**\n     * Clear all Before Adapters.\n     * 清空全部的  Before Adapters\n     */\n    fun clearBeforeAdapters() = apply {\n        mBeforeList.forEach {\n            mAdapter.removeAdapter(it)\n            firstAdapterOnViewAttachChangeListener?.let { listener ->\n                it.removeOnViewAttachStateChangeListener(listener)\n            }\n        }\n        mBeforeList.clear()\n    }\n\n    /**\n     * Add Adapter after [contentAdapter].\n     * 在 [contentAdapter] 之后添加 Adapter\n     *\n     * @param adapter Adapter<*>\n     */\n    fun addAfterAdapter(adapter: BaseQuickAdapter<*, *>) = apply {\n\n        lastAdapterOnViewAttachChangeListener?.let {\n            if (mAfterList.isEmpty()) {\n                contentAdapter.removeOnViewAttachStateChangeListener(it)\n            } else {\n                mAfterList.last().removeOnViewAttachStateChangeListener(it)\n            }\n            adapter.addOnViewAttachStateChangeListener(it)\n        }\n\n        val isTure = if (trailingLoadStateAdapter == null) {\n            mAdapter.addAdapter(adapter)\n        } else {\n            mAdapter.addAdapter(mAdapter.adapters.size - 1, adapter)\n        }\n\n        if (isTure) {\n            mAfterList += adapter\n        }\n    }\n\n    /**\n     * Add Adapter after [contentAdapter].\n     * 在 [contentAdapter] 之后添加 Adapter\n     *\n     * @param index\n     * @param adapter\n     */\n    fun addAfterAdapter(index: Int, adapter: BaseQuickAdapter<*, *>) = apply {\n        if (index < 0 || index > mAfterList.size) throw IndexOutOfBoundsException(\"Index must be between 0 and ${mAfterList.size}. Given:${index}\")\n\n        if (index == mAfterList.size) {\n            addAfterAdapter(adapter)\n            return@apply\n        }\n\n        val realIndex = if (trailingLoadStateAdapter == null) {\n            mAdapter.adapters.size - mAfterList.size + index\n        } else {\n            mAdapter.adapters.size - 1 - mAfterList.size + index\n        }\n\n        if(mAdapter.addAdapter(realIndex, adapter)) {\n            mAfterList += adapter\n        }\n    }\n\n    /**\n     * Clear AfterList.\n     * 清空 AfterList\n     */\n    fun clearAfterAdapters() = apply {\n        mAfterList.forEach {\n            mAdapter.removeAdapter(it)\n            lastAdapterOnViewAttachChangeListener?.let { listener ->\n                it.removeOnViewAttachStateChangeListener(listener)\n            }\n        }\n        mAfterList.clear()\n    }\n\n    /**\n     * Get Adapter List before [contentAdapter]\n     * 获取 [contentAdapter] 之前的 AdapterList\n     */\n    val beforeAdapterList: List<BaseQuickAdapter<*, *>> get() = Collections.unmodifiableList(mBeforeList)\n\n    /**\n     * Get Adapter List after [contentAdapter]\n     * 获取 [contentAdapter] 之后的 AdapterList\n     */\n    val afterAdapterList: List<BaseQuickAdapter<*, *>> get() = Collections.unmodifiableList(mAfterList)\n\n    fun removeAdapter(adapter: BaseQuickAdapter<*, *>) = apply {\n        if (adapter == contentAdapter) {\n            return@apply\n        }\n        mAdapter.removeAdapter(adapter)\n        mBeforeList -= adapter\n        mAfterList -= adapter\n\n        firstAdapterOnViewAttachChangeListener?.let {\n            adapter.removeOnViewAttachStateChangeListener(it)\n            if (mBeforeList.isEmpty()) {\n                contentAdapter.addOnViewAttachStateChangeListener(it)\n            } else {\n                mBeforeList.first().addOnViewAttachStateChangeListener(it)\n            }\n        }\n\n        lastAdapterOnViewAttachChangeListener?.let {\n            adapter.removeOnViewAttachStateChangeListener(it)\n            if (mAfterList.isEmpty()) {\n                contentAdapter.addOnViewAttachStateChangeListener(it)\n            } else {\n                mAfterList.last().addOnViewAttachStateChangeListener(it)\n            }\n        }\n    }\n\n    /**\n     * Builder\n     * 通过 \"向前加载\"、\"向后加载\"、主要内容Adapter，构建 [QuickAdapterHelper]\n     *\n     * @property contentAdapter 展示内容的 Adapter\n     * @constructor Create empty Builder\n     */\n    class Builder(private val contentAdapter: BaseQuickAdapter<*, *>) {\n\n        private var leadingLoadStateAdapter: LeadingLoadStateAdapter<*>? = null\n        private var trailingLoadStateAdapter: TrailingLoadStateAdapter<*>? = null\n\n        private var config: ConcatAdapter.Config = ConcatAdapter.Config.DEFAULT\n\n        private fun getTrailingLoadStateAdapter(): TrailingLoadStateAdapter<*> {\n            return trailingLoadStateAdapter ?: DefaultTrailingLoadStateAdapter().apply {\n                trailingLoadStateAdapter = this\n            }\n        }\n\n        /**\n         * 尾部\"加载更多\"Adapter\n         * @param loadStateAdapter LoadStateAdapter<*>?\n         * @return Builder\n         */\n        fun setTrailingLoadStateAdapter(loadStateAdapter: TrailingLoadStateAdapter<*>?) = apply {\n            this.trailingLoadStateAdapter = loadStateAdapter\n        }\n\n        fun setTrailingLoadStateAdapter(\n            loadMoreListener: TrailingLoadStateAdapter.OnTrailingListener?\n        ) = apply {\n            getTrailingLoadStateAdapter().setOnLoadMoreListener(loadMoreListener)\n        }\n\n        /**\n         * 设置“加载更多”的预加载。\n         *\n         * Preload, the number of items from the tail.\n         *\n         * @param size\n         */\n        fun setTrailPreloadSize(size: Int) = apply {\n            getTrailingLoadStateAdapter().preloadSize = size\n        }\n\n\n        /**\n         * 设置“加载更多”。是否打开自动加载更多\n         *\n         * Whether to turn on autoload more. Called when it must be initialized\n         *\n         * @param enable\n         */\n        fun isTrailAutoLoadMore(enable: Boolean) = apply {\n            getTrailingLoadStateAdapter().isAutoLoadMore = enable\n        }\n\n\n        private fun getLeadingLoadStateAdapter(): LeadingLoadStateAdapter<*> {\n            return leadingLoadStateAdapter ?: DefaultLeadingLoadStateAdapter().apply {\n                leadingLoadStateAdapter = this\n            }\n        }\n\n        /**\n         * 首部\"加载更多\"Adapter\n         *\n         * @param loadStateAdapter\n         */\n        fun setLeadingLoadStateAdapter(loadStateAdapter: LeadingLoadStateAdapter<*>?) = apply {\n            this.leadingLoadStateAdapter = loadStateAdapter\n        }\n\n        fun setLeadingLoadStateAdapter(\n            loadListener: LeadingLoadStateAdapter.OnLeadingListener?\n        ) = apply {\n            getLeadingLoadStateAdapter().setOnLeadingListener(loadListener)\n        }\n\n        /**\n         * 设置“向上加载”的预加载。\n         *\n         * Preload, the number of items from the leading.\n         *\n         * @param size\n         */\n        fun setLeadPreloadSize(size: Int) = apply {\n            getLeadingLoadStateAdapter().preloadSize = size\n        }\n\n        /**\n         * 设置 ConcatAdapter 的配置\n         *\n         * @param config\n         */\n        fun setConfig(config: ConcatAdapter.Config) = apply {\n            this.config = config\n        }\n\n        /**\n         * 构建并返回 QuickAdapterHelper\n         *\n         * @return\n         */\n        fun build(): QuickAdapterHelper {\n            return QuickAdapterHelper(\n                contentAdapter,\n                leadingLoadStateAdapter,\n                trailingLoadStateAdapter,\n                config\n            )\n        }\n\n        /**\n         * 附加到指定的 RecyclerView 上，并返回 QuickAdapterHelper\n         *\n         * @param recyclerView\n         * @return\n         */\n        fun attachTo(recyclerView: RecyclerView): QuickAdapterHelper {\n            return QuickAdapterHelper(\n                contentAdapter,\n                leadingLoadStateAdapter,\n                trailingLoadStateAdapter,\n                config\n            ).apply {\n                recyclerView.adapter = this.adapter\n            }\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/AlphaInAnimation.kt",
    "content": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator\nimport android.view.View\nimport android.view.animation.LinearInterpolator\n\n/**\n * An animation to fade item in, changing alpha from default 0f to 1.0f at a uniform rate in default 300ms.\n *\n * item 淡入显示的动画\n */\nclass AlphaInAnimation @JvmOverloads constructor(\n    private val duration: Long = 300,\n    private val mFrom: Float = DEFAULT_ALPHA_FROM\n) : ItemAnimator {\n\n    private val interpolator = LinearInterpolator()\n\n    override fun animator(view: View): Animator {\n        val animator = ObjectAnimator.ofFloat(view, \"alpha\", mFrom, 1f)\n        animator.duration = duration\n        animator.interpolator = interpolator\n        return animator\n    }\n\n    companion object {\n        private const val DEFAULT_ALPHA_FROM = 0f\n    }\n\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/ItemAnimator.kt",
    "content": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.view.View\n\n/**\n * https://github.com/CymChad/BaseRecyclerViewAdapterHelper\n */\ninterface ItemAnimator {\n    fun animator(view: View): Animator\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/ScaleInAnimation.kt",
    "content": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.AnimatorSet\nimport android.animation.ObjectAnimator\nimport android.view.View\nimport android.view.animation.DecelerateInterpolator\n\n/**\n * item 缩放进入的动画\n * An animation to scale item in, changing item's scaleX and scaleY from default 0.5f to 1.0f in default 300ms.(Using a DecelerateInterpolator with default factor.)\n */\nclass ScaleInAnimation @JvmOverloads constructor(\n    private val duration: Long = 300,\n    private val mFrom: Float = DEFAULT_SCALE_FROM\n) : ItemAnimator {\n\n    private val interpolator = DecelerateInterpolator()\n\n    override fun animator(view: View): Animator {\n        val scaleX = ObjectAnimator.ofFloat(view, \"scaleX\", mFrom, 1f)\n\n        val scaleY = ObjectAnimator.ofFloat(view, \"scaleY\", mFrom, 1f)\n\n        val animatorSet = AnimatorSet()\n        animatorSet.duration = duration\n        animatorSet.interpolator = interpolator\n        animatorSet.play(scaleX).with(scaleY)\n\n        return animatorSet\n    }\n\n    companion object {\n        private const val DEFAULT_SCALE_FROM = .5f\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/SlideInBottomAnimation.kt",
    "content": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator\nimport android.view.View\nimport android.view.animation.DecelerateInterpolator\n\n/**\n * 让 item 从底部滑入的动画\n * An animation to let items slide in from the bottom.(Using a DecelerateInterpolator with 1.3 factor.) Default duration is 400ms.\n */\nclass SlideInBottomAnimation @JvmOverloads constructor(\n    private val duration: Long = 400L,\n) : ItemAnimator {\n\n    private val interpolator = DecelerateInterpolator(1.3f)\n\n    override fun animator(view: View): Animator {\n        val animator = ObjectAnimator.ofFloat(view, \"translationY\", view.measuredHeight.toFloat(), 0f)\n        animator.duration = duration\n        animator.interpolator = interpolator\n        return animator\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/SlideInLeftAnimation.kt",
    "content": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator\nimport android.view.View\nimport android.view.animation.DecelerateInterpolator\n\n/**\n * 让 item 从左侧滑入的动画\n * An animation to let items slide in from the left.(Using a DecelerateInterpolator with 1.8 factor.) Default duration is 400ms.\n */\nclass SlideInLeftAnimation @JvmOverloads constructor(\n    private val duration: Long = 400L,\n) : ItemAnimator {\n\n    private val interpolator = DecelerateInterpolator(1.8f)\n\n    override fun animator(view: View): Animator {\n        val animator = ObjectAnimator.ofFloat(view, \"translationX\", -view.rootView.width.toFloat(), 0f)\n        animator.duration = duration\n        animator.interpolator = interpolator\n        return animator\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/animation/SlideInRightAnimation.kt",
    "content": "package com.chad.library.adapter4.animation\n\nimport android.animation.Animator\nimport android.animation.ObjectAnimator\nimport android.view.View\nimport android.view.animation.DecelerateInterpolator\n\n/**\n * 让 item 从右侧滑入的动画\n * An animation to let items slide in from the right.(Using a DecelerateInterpolator with 1.8 factor.) Default duration is 400ms.\n */\nclass SlideInRightAnimation @JvmOverloads constructor(\n    private val duration: Long = 400L,\n) : ItemAnimator {\n    private val interpolator = DecelerateInterpolator(1.8f)\n\n    override fun animator(view: View): Animator {\n        val animator = ObjectAnimator.ofFloat(view, \"translationX\", view.rootView.width.toFloat(), 0f)\n        animator.duration = duration\n        animator.interpolator = interpolator\n        return animator\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/DragSwipeExt.kt",
    "content": "package com.chad.library.adapter4.dragswipe\n\nimport android.graphics.Canvas\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.dragswipe.listener.OnItemDragListener\nimport com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener\n\n/**\n * 使用拖拽方式的拓展函数\n */\ninline fun QuickDragAndSwipe.setItemDragListener(\n    crossinline onItemDragStart: ((viewHolder: RecyclerView.ViewHolder?, pos: Int) -> Unit) = { _, _ -> },\n    crossinline onItemDragMoving: ((\n        source: RecyclerView.ViewHolder,\n        from: Int,\n        target: RecyclerView.ViewHolder,\n        to: Int\n    ) -> Unit) = { _, _, _, _ -> },\n    crossinline onItemDragEnd: ((viewHolder: RecyclerView.ViewHolder, pos: Int) -> Unit) = { _, _ -> },\n\n    ) = apply {\n    val listener = object :\n        OnItemDragListener {\n        override fun onItemDragStart(viewHolder: RecyclerView.ViewHolder?, pos: Int) {\n            onItemDragStart.invoke(viewHolder, pos)\n        }\n\n        override fun onItemDragMoving(\n            source: RecyclerView.ViewHolder,\n            from: Int,\n            target: RecyclerView.ViewHolder,\n            to: Int\n        ) {\n            onItemDragMoving.invoke(source, from, target, to)\n        }\n\n        override fun onItemDragEnd(viewHolder: RecyclerView.ViewHolder, pos: Int) {\n            onItemDragEnd.invoke(viewHolder, pos)\n        }\n    }\n    this.setItemDragListener(listener)\n}\n\n/**\n * 滑动删除的拓展函数\n */\ninline fun QuickDragAndSwipe.setItemSwipeListener(\n    crossinline onItemSwipeStart: ((viewHolder: RecyclerView.ViewHolder?, bindingAdapterPosition: Int) -> Unit) = { _, _ -> },\n    crossinline onItemSwipeMoving: ((\n        canvas: Canvas,\n        viewHolder: RecyclerView.ViewHolder,\n        dX: Float,\n        dY: Float,\n        isCurrentlyActive: Boolean\n    ) -> Unit) = { _, _, _, _, _ -> },\n    crossinline onItemSwiped: ((viewHolder: RecyclerView.ViewHolder, direction: Int, bindingAdapterPosition: Int) -> Unit) = { _, _, _ -> },\n    crossinline onItemSwipeEnd: ((viewHolder: RecyclerView.ViewHolder, bindingAdapterPosition: Int) -> Unit) = { _, _ -> }\n) = apply {\n    val listener = object :\n        OnItemSwipeListener {\n        override fun onItemSwipeStart(viewHolder: RecyclerView.ViewHolder?, pos: Int) {\n            onItemSwipeStart.invoke(viewHolder, pos)\n        }\n\n        override fun onItemSwipeMoving(\n            canvas: Canvas,\n            viewHolder: RecyclerView.ViewHolder,\n            dX: Float,\n            dY: Float,\n            isCurrentlyActive: Boolean\n        ) {\n            onItemSwipeMoving.invoke(canvas, viewHolder, dX, dY, isCurrentlyActive)\n        }\n\n        override fun onItemSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int, bindingAdapterPosition: Int) {\n            onItemSwiped.invoke(viewHolder, direction, bindingAdapterPosition)\n        }\n\n        override fun onItemSwipeEnd(viewHolder: RecyclerView.ViewHolder, pos: Int) {\n            onItemSwipeEnd.invoke(viewHolder, pos)\n        }\n    }\n    this.setItemSwipeListener(listener)\n}\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/QuickDragAndSwipe.kt",
    "content": "package com.chad.library.adapter4.dragswipe\n\nimport android.graphics.Canvas\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback\nimport com.chad.library.adapter4.dragswipe.listener.OnItemDragListener\nimport com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener\nimport com.chad.library.adapter4.viewholder.StateLayoutVH\n\n/**\n * @author yangfeng\n * @date 2022/7/27\n * 默认实现的适配带有头布局的拖拽类，可继承此类自定义\n */\nopen class QuickDragAndSwipe : ItemTouchHelper.Callback() {\n\n    protected var recyclerView: RecyclerView? = null\n\n    private val _itemTouchHelper: ItemTouchHelper = ItemTouchHelper(this)\n\n    private var _isLongPressDragEnabled: Boolean = true\n    private var _isItemViewSwipeEnabled: Boolean = true\n\n    /**\n     * 设置拖拽的flag\n     */\n    private var _dragMoveFlags: Int = ItemTouchHelper.ACTION_STATE_IDLE\n\n    /**\n     * 设置侧滑的flag\n     */\n    private var _swipeMoveFlags: Int = ItemTouchHelper.ACTION_STATE_IDLE\n\n    private var mOnItemDragListener: OnItemDragListener? = null\n    private var mOnItemSwipeListener: OnItemSwipeListener? = null\n    private var _dataCallback: DragAndSwipeDataCallback? = null\n    private var isDrag = false\n    private var isSwipe = false\n\n    private var tempSwipedPosition = -1\n\n    val dataCallback: DragAndSwipeDataCallback\n        get() {\n            checkNotNull(_dataCallback) {\n                \"Please set _adapterImpl\"\n            }\n            return _dataCallback!!\n        }\n\n    val itemTouchHelper: ItemTouchHelper get() = _itemTouchHelper\n\n    /**\n     * 绑定RecyclerView\n     */\n    open fun attachToRecyclerView(recyclerView: RecyclerView) = apply {\n        if (this.recyclerView == recyclerView) return this\n        this.recyclerView = recyclerView\n        _itemTouchHelper.attachToRecyclerView(recyclerView)\n    }\n\n    /**\n     * 设置拖拽的flag\n     */\n    fun setDragMoveFlags(dragMoveFlags: Int) = apply {\n        this._dragMoveFlags = dragMoveFlags\n    }\n\n    fun getDragMoveFlags(): Int = this._dragMoveFlags\n\n    /**\n     * 设置侧滑的flag\n     */\n    fun setSwipeMoveFlags(swipeMoveFlags: Int) = apply {\n        this._swipeMoveFlags = swipeMoveFlags\n    }\n\n    fun getSwipeMoveFlags(): Int = this._swipeMoveFlags\n\n    /**\n     * 是否开启拖拽\n     */\n    fun setLongPressDragEnabled(isLongPressDragEnabled: Boolean) = apply {\n        _isLongPressDragEnabled = isLongPressDragEnabled\n    }\n\n    /**\n     * 是否开启侧滑\n     *\n     * @param isItemViewSwipeEnabled\n     */\n    fun setItemViewSwipeEnabled(isItemViewSwipeEnabled: Boolean) = apply {\n        _isItemViewSwipeEnabled = isItemViewSwipeEnabled\n    }\n\n    /**\n     * 拖拽\n     * 长按默认可拖动，可不进行设置此方法\n     * 此方法可以做特殊使用进行调用\n     * 如：长按此条position对应的item，触发 position+1 对应的item\n     */\n    open fun startDrag(holder: RecyclerView.ViewHolder) = apply {\n        _itemTouchHelper.startDrag(holder)\n    }\n\n    /**\n     * 拖拽\n     * 长按默认可拖动，可不进行设置此方法\n     * 此方法可以做特殊使用进行调用\n     * 如：长按此条position对应的item，触发 position+1 对应的item\n     */\n    open fun startDrag(position: Int) = apply {\n        val holder = recyclerView?.findViewHolderForAdapterPosition(position) ?: return this\n        _itemTouchHelper.startDrag(holder)\n    }\n\n    /**\n     * 启动侧滑\n     */\n    open fun startSwipe(holder: RecyclerView.ViewHolder) = apply {\n        _itemTouchHelper.startSwipe(holder)\n    }\n\n    /**\n     * 启动侧滑\n     */\n    open fun startSwipe(position: Int) = apply {\n        val holder = recyclerView?.findViewHolderForAdapterPosition(position) ?: return this\n        _itemTouchHelper.startSwipe(holder)\n    }\n\n    /********************************************************/\n    /*              ItemTouchHelper.Callback()              */\n    /********************************************************/\n\n    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {\n        when (actionState) {\n            ItemTouchHelper.ACTION_STATE_DRAG -> {\n                isDrag = true\n                mOnItemDragListener?.onItemDragStart(\n                    viewHolder,\n                    getViewHolderPosition(viewHolder)\n                )\n            }\n            ItemTouchHelper.ACTION_STATE_SWIPE -> {\n                isSwipe = true\n                mOnItemSwipeListener?.onItemSwipeStart(\n                    viewHolder,\n                    getViewHolderPosition(viewHolder)\n                )\n            }\n        }\n        super.onSelectedChanged(viewHolder, actionState)\n    }\n\n    /**\n     * 是否可拖动或左右滑动\n     * 可根据viewHolder获取对应的条目对某条，不进行拖动或滑动操作。返回值设置为 makeMovementFlags(0, 0) 即可\n     */\n    override fun getMovementFlags(\n        recyclerView: RecyclerView,\n        viewHolder: RecyclerView.ViewHolder\n    ): Int {\n        //此处判断，是否可以长按拖动\n        if (isEmptyView(viewHolder)) {\n            return makeMovementFlags(0, 0)\n        }\n        return makeMovementFlags(_dragMoveFlags, _swipeMoveFlags)\n    }\n\n    override fun onMove(\n        recyclerView: RecyclerView,\n        viewHolder: RecyclerView.ViewHolder,\n        target: RecyclerView.ViewHolder\n    ): Boolean {\n        return viewHolder.itemViewType == target.itemViewType\n    }\n\n    override fun onMoved(\n        recyclerView: RecyclerView,\n        viewHolder: RecyclerView.ViewHolder,\n        fromPos: Int,\n        target: RecyclerView.ViewHolder,\n        toPos: Int,\n        x: Int,\n        y: Int\n    ) {\n        super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)\n        val fromPosition = viewHolder.bindingAdapterPosition\n        val toPosition = target.bindingAdapterPosition\n\n        if (fromPosition == RecyclerView.NO_POSITION || toPosition == RecyclerView.NO_POSITION) return\n\n        // 进行位置的切换\n        _dataCallback?.dataMove(fromPosition, toPosition)\n        mOnItemDragListener?.onItemDragMoving(viewHolder, fromPosition, target, toPosition)\n    }\n\n\n    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {\n        val position = viewHolder.bindingAdapterPosition\n\n        if (position == RecyclerView.NO_POSITION) return\n        tempSwipedPosition = position\n        // 删除数据\n        _dataCallback?.dataRemoveAt(position)\n\n        mOnItemSwipeListener?.onItemSwiped(viewHolder, direction, position)\n    }\n\n    override fun isLongPressDragEnabled(): Boolean {\n        return _isLongPressDragEnabled\n    }\n\n    override fun isItemViewSwipeEnabled(): Boolean {\n        return _isItemViewSwipeEnabled\n    }\n\n    override fun onChildDraw(\n        c: Canvas,\n        recyclerView: RecyclerView,\n        viewHolder: RecyclerView.ViewHolder,\n        dX: Float,\n        dY: Float,\n        actionState: Int,\n        isCurrentlyActive: Boolean\n    ) {\n        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)\n        when (actionState) {\n            ItemTouchHelper.ACTION_STATE_SWIPE -> {\n                mOnItemSwipeListener?.onItemSwipeMoving(c, viewHolder, dX, dY, isCurrentlyActive)\n            }\n        }\n    }\n\n    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {\n        super.clearView(recyclerView, viewHolder)\n        if (isSwipe) {\n            isSwipe = false\n            val position = tempSwipedPosition\n            tempSwipedPosition = -1\n            mOnItemSwipeListener?.onItemSwipeEnd(viewHolder, position)\n        }\n        if (isDrag) {\n            isDrag = false\n            val position = viewHolder.bindingAdapterPosition\n            mOnItemDragListener?.onItemDragEnd(viewHolder, position)\n        }\n    }\n\n    /********************************************************/\n    /*                 private method                       */\n    /********************************************************/\n\n    /**\n     * 是否是空布局\n     */\n    private fun isEmptyView(viewHolder: RecyclerView.ViewHolder): Boolean {\n        return viewHolder is StateLayoutVH\n    }\n\n\n    private fun getViewHolderPosition(viewHolder: RecyclerView.ViewHolder?): Int {\n        return viewHolder?.bindingAdapterPosition ?: RecyclerView.NO_POSITION\n    }\n\n    /********************************************************/\n    /*                       Listener                       */\n    /********************************************************/\n\n    /**\n     * 设置拖拽的监听\n     */\n    fun setItemDragListener(onItemDragListener: OnItemDragListener?) = apply {\n        this.mOnItemDragListener = onItemDragListener\n    }\n\n    fun setItemSwipeListener(onItemSwipeListener: OnItemSwipeListener?) = apply {\n        this.mOnItemSwipeListener = onItemSwipeListener\n    }\n\n    fun setDataCallback(callback: DragAndSwipeDataCallback) = apply {\n        this._dataCallback = callback\n    }\n\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/listener/DragAndSwipeDataCallback.kt",
    "content": "package com.chad.library.adapter4.dragswipe.listener\n\n/**\n * 由外部实现的数据操作\n */\ninterface DragAndSwipeDataCallback {\n\n    /**\n     * item 数据交换\n     */\n    fun dataMove(fromPosition: Int, toPosition: Int)\n\n    /**\n     * 删除 Item 数据\n     *\n     * @param position\n     */\n    fun dataRemoveAt(position: Int)\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/listener/OnItemDragListener.java",
    "content": "package com.chad.library.adapter4.dragswipe.listener;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.RecyclerView;\n\n/**\n * Created by luoxw on 2016/6/20.\n */\npublic interface OnItemDragListener {\n    void onItemDragStart(@Nullable RecyclerView.ViewHolder viewHolder, int pos);\n\n    void onItemDragMoving(@NonNull RecyclerView.ViewHolder source, int from, @NonNull RecyclerView.ViewHolder target, int to);\n\n    void onItemDragEnd(@NonNull RecyclerView.ViewHolder viewHolder, int pos);\n}\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/dragswipe/listener/OnItemSwipeListener.java",
    "content": "package com.chad.library.adapter4.dragswipe.listener;\n\nimport android.graphics.Canvas;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.recyclerview.widget.RecyclerView;\n\n/**\n * Created by luoxw on 2016/6/23.\n */\npublic interface OnItemSwipeListener {\n    /**\n     * Called when the swipe action start.\n     */\n    void onItemSwipeStart(@Nullable RecyclerView.ViewHolder viewHolder, int bindingAdapterPosition);\n\n    /**\n     * Called when the swipe action is over.\n     * If you change the view on the start, you should reset is here, no matter the item has swiped or not.\n     *\n     * @param pos If the view is swiped, pos will be negative.\n     */\n    void onItemSwipeEnd(@NonNull RecyclerView.ViewHolder viewHolder, int bindingAdapterPosition);\n\n    /**\n     * Called when item is swiped, the view is going to be removed from the adapter.\n     */\n    void onItemSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction, int bindingAdapterPosition);\n\n    /**\n     * Draw on the empty edge when swipe moving\n     *\n     * @param canvas            the empty edge's canvas\n     * @param viewHolder        The ViewHolder which is being interacted by the User or it was\n     *                          interacted and simply animating to its original position\n     * @param dX                The amount of horizontal displacement caused by user's action\n     * @param dY                The amount of vertical displacement caused by user's action\n     * @param isCurrentlyActive True if this view is currently being controlled by the user or\n     *                          false it is simply animating back to its original state.\n     */\n    void onItemSwipeMoving(@NonNull Canvas canvas, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive);\n}\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/fullspan/FullSpanAdapterType.kt",
    "content": "package com.chad.library.adapter4.fullspan\n\nimport androidx.recyclerview.widget.GridLayoutManager\n\n/**\n * If Adapter needs full span, implement this interface.\n * Need to be used with [com.chad.library.adapter4.base.layoutmanager.QuickGridLayoutManager]\n *\n * 如果此类型的 Adapter 需要满跨度，实现此接口。\n * 需要配合 [com.chad.library.adapter4.base.layoutmanager.QuickGridLayoutManager] 使用，或者自行实现[GridLayoutManager.SpanSizeLookup]\n *\n */\ninterface FullSpanAdapterType"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/layoutmanager/QuickGridLayoutManager.kt",
    "content": "package com.chad.library.adapter4.layoutmanager\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport androidx.annotation.CallSuper\nimport androidx.recyclerview.widget.ConcatAdapter\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.BaseQuickAdapter\nimport com.chad.library.adapter4.fullspan.FullSpanAdapterType\n\n/**\n * grid layout manager.\n * Used to achieve full span. Adapter needs to implement [FullSpanAdapterType] interface\n *\n * 网格布局 GridLayoutManager，用于实现满跨度，Adapter 需要实现 [FullSpanAdapterType] 接口\n *\n */\nopen class QuickGridLayoutManager : GridLayoutManager {\n\n    constructor(\n        context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int\n    ) : super(context, attrs, defStyleAttr, defStyleRes)\n\n    constructor(context: Context, spanCount: Int) : super(context, spanCount)\n\n    constructor(\n        context: Context, spanCount: Int,\n        @RecyclerView.Orientation orientation: Int, reverseLayout: Boolean\n    ) : super(context, spanCount, orientation, reverseLayout)\n\n    private val fullSpanSizeLookup = FullSpanSizeLookup()\n\n    private var adapter: RecyclerView.Adapter<*>? = null\n\n    init {\n        fullSpanSizeLookup.originalSpanSizeLookup = spanSizeLookup\n        super.setSpanSizeLookup(fullSpanSizeLookup)\n    }\n\n    @CallSuper\n    override fun onAdapterChanged(\n        oldAdapter: RecyclerView.Adapter<*>?, newAdapter: RecyclerView.Adapter<*>?\n    ) {\n        adapter = newAdapter\n    }\n\n    override fun onAttachedToWindow(view: RecyclerView?) {\n        super.onAttachedToWindow(view)\n        adapter = view?.adapter\n    }\n\n    override fun onDetachedFromWindow(view: RecyclerView?, recycler: RecyclerView.Recycler?) {\n        super.onDetachedFromWindow(view, recycler)\n        adapter = null\n    }\n\n    override fun setSpanSizeLookup(spanSizeLookup: SpanSizeLookup?) {\n        fullSpanSizeLookup.originalSpanSizeLookup = spanSizeLookup\n    }\n\n    /**\n     * 处理全部跨度item的情况\n     */\n    private inner class FullSpanSizeLookup : SpanSizeLookup() {\n\n        var originalSpanSizeLookup: SpanSizeLookup? = null\n\n        override fun getSpanSize(position: Int): Int {\n            val adapter = adapter ?: return 1\n\n            if (adapter is ConcatAdapter) {\n                val pair = adapter.getWrappedAdapterAndPosition(position)\n\n                return when (val wrappedAdapter = pair.first) {\n                    is FullSpanAdapterType -> {\n                        spanCount\n                    }\n                    is BaseQuickAdapter<*, *> -> {\n                        val type = wrappedAdapter.getItemViewType(pair.second)\n\n                        if (wrappedAdapter.isFullSpanItem(type)) {\n                            spanCount\n                        } else {\n                            originalSpanSizeLookup?.getSpanSize(position) ?: 1\n                        }\n                    }\n                    else -> originalSpanSizeLookup?.getSpanSize(position) ?: 1\n                }\n            } else {\n                return when (adapter) {\n                    is FullSpanAdapterType -> {\n                        spanCount\n                    }\n                    is BaseQuickAdapter<*, *> -> {\n                        val type = adapter.getItemViewType(position)\n\n                        if (adapter.isFullSpanItem(type)) {\n                            spanCount\n                        } else {\n                            originalSpanSizeLookup?.getSpanSize(position) ?: 1\n                        }\n                    }\n                    else -> originalSpanSizeLookup?.getSpanSize(position) ?: 1\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/LoadState.kt",
    "content": "package com.chad.library.adapter4.loadState\n\n/**\n * Load state\n *\n * 加载状态\n *\n * @property endOfPaginationReached 是否已到达分页末尾\n */\nsealed class LoadState(\n    val endOfPaginationReached: Boolean\n) {\n\n    /**\n     * There is currently no status.\n     *\n     * 当前没有任何状态（例如：初始化时，刷新数据时）\n     */\n    object None: LoadState(false) {\n        override fun equals(other: Any?): Boolean {\n            return other is None &&\n                    endOfPaginationReached == other.endOfPaginationReached\n        }\n\n        override fun hashCode(): Int {\n            return endOfPaginationReached.hashCode()\n        }\n\n        override fun toString(): String {\n            return \"None(endOfPaginationReached=$endOfPaginationReached)\"\n        }\n    }\n\n    /**\n     * Is not currently loading, and no error currently observed.\n     *\n     * 当前未加载，并且当前未发生错误。\n     *\n     * @param endOfPaginationReached 是否已到达分页末尾\n     */\n    class NotLoading(\n        endOfPaginationReached: Boolean\n    ) : LoadState(endOfPaginationReached) {\n        override fun toString(): String {\n            return \"NotLoading(endOfPaginationReached=$endOfPaginationReached)\"\n        }\n\n        override fun equals(other: Any?): Boolean {\n            return other is NotLoading &&\n                    endOfPaginationReached == other.endOfPaginationReached\n        }\n\n        override fun hashCode(): Int {\n            return endOfPaginationReached.hashCode()\n        }\n\n        companion object {\n            @JvmStatic\n            val Complete = NotLoading(endOfPaginationReached = true)\n\n            @JvmStatic\n            val Incomplete = NotLoading(endOfPaginationReached = false)\n        }\n    }\n\n    /**\n     * Loading is in progress.\n     *\n     * 正在加载\n     */\n    object Loading : LoadState(false) {\n        override fun toString(): String {\n            return \"Loading(endOfPaginationReached=$endOfPaginationReached)\"\n        }\n\n        override fun equals(other: Any?): Boolean {\n            return other is Loading &&\n                    endOfPaginationReached == other.endOfPaginationReached\n        }\n\n        override fun hashCode(): Int {\n            return endOfPaginationReached.hashCode()\n        }\n    }\n\n    /**\n     * Loading hit an error.\n     *\n     * 加载时出错\n     *\n     * @param error [Throwable] that caused the load operation to generate this error state.\n     */\n    class Error(\n        val error: Throwable\n    ) : LoadState(false) {\n        override fun equals(other: Any?): Boolean {\n            return other is Error &&\n                    endOfPaginationReached == other.endOfPaginationReached &&\n                    error == other.error\n        }\n\n        override fun hashCode(): Int {\n            return endOfPaginationReached.hashCode() + error.hashCode()\n        }\n\n        override fun toString(): String {\n            return \"Error(endOfPaginationReached=$endOfPaginationReached, error=$error)\"\n        }\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/LoadStateAdapter.kt",
    "content": "package com.chad.library.adapter4.loadState\n\nimport android.view.ViewGroup\nimport androidx.annotation.CallSuper\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.fullspan.FullSpanAdapterType\n\n/**\n * Load state Adapter\n * 加载状态的父类，\"加载更多\"、\"向上加载\"都继承于此\n *\n */\nabstract class LoadStateAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>(),\n    FullSpanAdapterType {\n    /**\n     * Changing this property will immediately notify the Adapter to change the item it's\n     * presenting.\n     * [LoadState.None] is the initial state.\n     *\n     * 要在适配器中显示的 LoadState。更改此属性将立即通知适配器更改 item 的样式。\n     * [LoadState.None] 为初始状态。\n     */\n    var loadState: LoadState = LoadState.None\n        set(loadState) {\n            if (field != loadState) {\n                val oldState = field\n\n                val oldItem = displayLoadStateAsItem(field)\n                val newItem = displayLoadStateAsItem(loadState)\n\n                if (oldItem && !newItem) {\n                    notifyItemRemoved(0)\n                } else if (newItem && !oldItem) {\n                    notifyItemInserted(0)\n                } else if (oldItem && newItem) {\n                    notifyItemChanged(0)\n                }\n                field = loadState\n\n                loadStateListeners.forEach {\n                    it.loadState(oldState, loadState)\n                }\n            }\n        }\n\n    /**\n     * Is it loading.\n     *\n     * 是否加载中\n     */\n    val isLoading: Boolean\n        get() {\n            return loadState == LoadState.Loading\n        }\n\n    var recyclerView: RecyclerView? = null\n        private set\n\n    private val loadStateListeners = ArrayList<LoadStateListener>(0)\n\n    final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {\n        return onCreateViewHolder(parent, loadState)\n    }\n\n    final override fun onBindViewHolder(holder: VH, position: Int) {\n        onBindViewHolder(holder, loadState)\n    }\n\n    final override fun onBindViewHolder(holder: VH, position: Int, payloads: MutableList<Any>) {\n        super.onBindViewHolder(holder, position, payloads)\n    }\n\n    final override fun getItemViewType(position: Int): Int = getStateViewType(loadState)\n\n    final override fun getItemCount(): Int = if (displayLoadStateAsItem(loadState)) 1 else 0\n\n    @CallSuper\n    override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {\n        this.recyclerView = recyclerView\n    }\n\n    @CallSuper\n    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {\n        this.recyclerView = null\n    }\n\n    /**\n     * Called to create a ViewHolder for the given LoadState.\n     *\n     * 调用此方法，为 LoadState 创建 ViewHolder。\n     *\n     * @param parent The ViewGroup into which the new View will be added after it is bound to\n     *               an adapter position.\n     * @param loadState The LoadState to be initially presented by the new ViewHolder.\n     *\n     * @see [getItemViewType]\n     * @see [displayLoadStateAsItem]\n     */\n    abstract fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): VH\n\n    /**\n     * Called to bind the passed LoadState to the ViewHolder.\n     *\n     * 调用此方法，将 LoadState 状态绑定至 ViewHolder\n     *\n     * @param loadState LoadState to display.\n     *\n     * @see [getItemViewType]\n     * @see [displayLoadStateAsItem]\n     */\n    abstract fun onBindViewHolder(holder: VH, loadState: LoadState)\n\n    /**\n     * Override this method to use different view types per LoadState.\n     * 重写此方法以对每个 LoadState 使用不同的 View 类型。\n     *\n     * By default, this LoadStateAdapter only uses a single view type.\n     */\n    open fun getStateViewType(loadState: LoadState): Int = 0\n\n    /**\n     * Returns true if the LoadState should be displayed as a list item when active.\n     *\n     * By default, [LoadState.Loading] and [LoadState.Error] present as list items, others do not.\n     *\n     *\n     * 如果 LoadState 在激活时需要显示item，则返回 true。\n     * 默认情况下，[LoadState.Loading] 和 [LoadState.Error] 将会显示，其他则不显示。\n     */\n    open fun displayLoadStateAsItem(loadState: LoadState): Boolean {\n        return loadState is LoadState.Loading || loadState is LoadState.Error\n    }\n\n    fun addLoadStateListener(listener: LoadStateListener) {\n        loadStateListeners.add(listener)\n    }\n\n    fun removeLoadStateListener(listener: LoadStateListener) {\n        loadStateListeners.remove(listener)\n    }\n\n    fun interface LoadStateListener {\n        fun loadState(previousState: LoadState, currentState: LoadState)\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/leading/DefaultLeadingLoadStateAdapter.kt",
    "content": "package com.chad.library.adapter4.loadState.leading\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.R\nimport com.chad.library.adapter4.loadState.LoadState\n\n/**\n * Default leading load state adapter\n *\n * 默认实现的尾部\"向上加载更多\" Adapter\n */\ninternal class DefaultLeadingLoadStateAdapter :\n    LeadingLoadStateAdapter<DefaultLeadingLoadStateAdapter.LeadingLoadStateVH>() {\n\n    /**\n     * Default ViewHolder\n     *\n     * 默认实现的 ViewHolder\n     */\n    internal class LeadingLoadStateVH(\n        parent: ViewGroup,\n        view: View = LayoutInflater.from(parent.context)\n            .inflate(R.layout.brvah_leading_load_more, parent, false)\n    ) : RecyclerView.ViewHolder(view) {\n        val loadingProgress: View = itemView.findViewById(R.id.loading_progress)\n    }\n\n\n    override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): LeadingLoadStateVH {\n        return LeadingLoadStateVH(parent)\n    }\n\n    override fun onBindViewHolder(holder: LeadingLoadStateVH, loadState: LoadState) {\n        if (loadState is LoadState.Loading) {\n            holder.loadingProgress.visibility = View.VISIBLE\n        } else {\n            holder.loadingProgress.visibility = View.GONE\n        }\n    }\n\n    override fun getStateViewType(loadState: LoadState): Int = R.layout.brvah_leading_load_more\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/leading/LeadingLoadStateAdapter.kt",
    "content": "package com.chad.library.adapter4.loadState.leading\n\nimport androidx.annotation.CallSuper\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.loadState.LoadState\nimport com.chad.library.adapter4.loadState.LoadStateAdapter\n\n/**\n * Leading load state adapter\n * 首部的加载状态适配器\n */\nabstract class LeadingLoadStateAdapter<VH: RecyclerView.ViewHolder> : LoadStateAdapter<VH>() {\n\n    /**\n     * A listener for loading more.\n     * 加载更多的监听事件\n     */\n    var onLeadingListener: OnLeadingListener? = null\n        private set\n\n    /**\n     * Whether enable loading.\n     * 是否开启加载功能\n     */\n    var isLoadEnable = true\n\n    /**\n     * Preload, the number of distances from the first item.\n     *\n     * 预加载，距离首 item 的个数\n     */\n    var preloadSize = 0\n\n    private var mDelayNextLoadFlag: Boolean = false\n\n    override fun displayLoadStateAsItem(loadState: LoadState): Boolean {\n        return loadState is LoadState.Loading\n    }\n\n    @CallSuper\n    override fun onViewAttachedToWindow(holder: VH) {\n        if (preloadSize == 0) {\n            loadAction()\n        }\n    }\n\n    /**\n     * Action of loading more.\n     * 加载更多执行的操作\n     */\n    private fun loadAction() {\n        if (!isLoadEnable || onLeadingListener?.isAllowLoading() == false) return\n\n        if (mDelayNextLoadFlag) return\n\n        if (loadState is LoadState.NotLoading && !loadState.endOfPaginationReached) {\n            val recyclerView = recyclerView ?: return\n\n            if (recyclerView.isComputingLayout) {\n                // 如果 RecyclerView 当前正在计算布局，则延迟执行，避免崩溃\n                // To avoid crash. Delay to load more if the recyclerview is computingLayout.\n                mDelayNextLoadFlag = true\n                recyclerView.post {\n                    mDelayNextLoadFlag = false\n                    invokeLoad()\n                }\n                return\n            }\n            invokeLoad()\n        }\n    }\n\n    internal fun checkPreload(currentPosition: Int) {\n        if (currentPosition < 0) return\n\n        if (currentPosition <= preloadSize) {\n            loadAction()\n        }\n    }\n\n    fun invokeLoad() {\n        loadState = LoadState.Loading\n        onLeadingListener?.onLoad()\n    }\n\n\n    fun setOnLeadingListener(listener: OnLeadingListener?) = apply {\n        this.onLeadingListener = listener\n    }\n\n    override fun toString(): String {\n        return \"\"\"\n            LeadingLoadStateAdapter ->\n            [isLoadEnable: $isLoadEnable],\n            [preloadSize: $preloadSize],\n            [loadState: $loadState]\n        \"\"\".trimIndent()\n    }\n\n    interface OnLeadingListener {\n\n        /**\n         * Executing loading.\n         * \"加载更多\"执行逻辑\n         */\n        fun onLoad()\n\n        /**\n         * Whether to allow loading.\n         * 是否允许进行加载\n         */\n        fun isAllowLoading(): Boolean = true\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/trailing/DefaultTrailingLoadStateAdapter.kt",
    "content": "package com.chad.library.adapter4.loadState.trailing\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.R\nimport com.chad.library.adapter4.loadState.LoadState\n\n/**\n * Default trailing load state adapter\n *\n * 默认实现的尾部\"加载更多\" Adapter\n */\ninternal class DefaultTrailingLoadStateAdapter(isLoadEndDisplay: Boolean = true): TrailingLoadStateAdapter<DefaultTrailingLoadStateAdapter.TrailingLoadStateVH>(isLoadEndDisplay) {\n\n    /**\n     * Default implementation of \"load more\" ViewHolder\n     *\n     * 默认实现的\"加载更多\" ViewHolder\n     */\n    internal class TrailingLoadStateVH(\n        parent: ViewGroup,\n        view: View = LayoutInflater.from(parent.context).inflate(R.layout.brvah_trailing_load_more, parent, false)\n    ) : RecyclerView.ViewHolder(view) {\n        val loadCompleteView: View = itemView.findViewById(R.id.load_more_load_complete_view)\n        val loadingView: View = itemView.findViewById(R.id.load_more_loading_view)\n        val loadFailView: View = itemView.findViewById(R.id.load_more_load_fail_view)\n        val loadEndView: View = itemView.findViewById(R.id.load_more_load_end_view)\n    }\n\n    override fun onCreateViewHolder( parent: ViewGroup, loadState: LoadState): TrailingLoadStateVH {\n        return TrailingLoadStateVH(parent).apply {\n            loadFailView.setOnClickListener {\n                // 失败重试点击事件\n                // retry when loaded failed.\n                invokeFailRetry()\n            }\n            loadCompleteView.setOnClickListener {\n                // 加载更多，手动点击事件\n                // manual click to load more.\n                invokeLoadMore()\n            }\n        }\n    }\n\n    /**\n     * bind LoadState\n     *\n     * 绑定加载状态\n     */\n    override fun onBindViewHolder(holder: TrailingLoadStateVH, loadState: LoadState) {\n        when (loadState) {\n            is LoadState.NotLoading -> {\n                if (loadState.endOfPaginationReached) {\n                    holder.loadCompleteView.visibility = View.GONE\n                    holder.loadingView.visibility = View.GONE\n                    holder.loadFailView.visibility = View.GONE\n                    holder.loadEndView.visibility = View.VISIBLE\n                } else {\n                    holder.loadCompleteView.visibility = View.VISIBLE\n                    holder.loadingView.visibility = View.GONE\n                    holder.loadFailView.visibility = View.GONE\n                    holder.loadEndView.visibility = View.GONE\n                }\n            }\n            is LoadState.Loading -> {\n                holder.loadCompleteView.visibility = View.GONE\n                holder.loadingView.visibility = View.VISIBLE\n                holder.loadFailView.visibility = View.GONE\n                holder.loadEndView.visibility = View.GONE\n            }\n            is LoadState.Error -> {\n                holder.loadCompleteView.visibility = View.GONE\n                holder.loadingView.visibility = View.GONE\n                holder.loadFailView.visibility = View.VISIBLE\n                holder.loadEndView.visibility = View.GONE\n            }\n            is LoadState.None -> {\n                holder.loadCompleteView.visibility = View.GONE\n                holder.loadingView.visibility = View.GONE\n                holder.loadFailView.visibility = View.GONE\n                holder.loadEndView.visibility = View.GONE\n            }\n        }\n    }\n\n    override fun getStateViewType(loadState: LoadState): Int = R.layout.brvah_trailing_load_more\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/loadState/trailing/TrailingLoadStateAdapter.kt",
    "content": "package com.chad.library.adapter4.loadState.trailing\n\nimport androidx.annotation.CallSuper\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.recyclerview.widget.StaggeredGridLayoutManager\nimport com.chad.library.adapter4.loadState.LoadState\nimport com.chad.library.adapter4.loadState.LoadStateAdapter\n\n/**\n * Tail load more parent class Adapter.\n * 尾部加载更多的父类 Adapter\n *\n * Custom layout: You can modify the layout by extends this class and customizing [RecyclerView.ViewHolder].\n * 自定义布局：可以通过继承此类，并自定义[RecyclerView.ViewHolder]来修改布局\n */\nabstract class TrailingLoadStateAdapter<VH : RecyclerView.ViewHolder>(\n    /**\n     * Whether to display \"Loading end\" after all data is loaded.\n     *\n     * 所有数据加载完毕后，是否显示\"加载结束\"，必须初始化时传递，中途无法修改参数。\n     */\n    val isLoadEndDisplay: Boolean = true\n) : LoadStateAdapter<VH>() {\n\n    /**\n     * Trailing load state listener events\n     *\n     * 加载更多的监听事件\n     */\n    var onTrailingListener: OnTrailingListener? = null\n        private set\n\n    /**\n     * Whether to turn on autoload more. Called when it must be initialized\n     *\n     * 是否打开自动加载更多\n     */\n    var isAutoLoadMore = true\n\n    /**\n     * Preload, the number of items from the tail.\n     *\n     * 预加载，距离尾部 item 的个数\n     */\n    var preloadSize = 0\n\n    /**\n     * A flag to determine if you can load when content doesn't fill the screen.\n     * 不满一屏时，是否可以继续加载的标记位\n     */\n    private var mNotFullPageNextLoadFlag: Boolean = false\n\n    private var mDelayNextLoadFlag: Boolean = false\n\n    override fun displayLoadStateAsItem(loadState: LoadState): Boolean {\n        return super.displayLoadStateAsItem(loadState)\n                || (loadState is LoadState.NotLoading && !loadState.endOfPaginationReached) // 加载完成的状态，并且还有分页数据的时候，需要显示\n                || (isLoadEndDisplay && (loadState is LoadState.NotLoading && loadState.endOfPaginationReached)) // 加载彻底结束，不会再有分页数据的情况，并且需要显示结束后的item\n    }\n\n    @CallSuper\n    override fun onViewAttachedToWindow(holder: VH) {\n        if (preloadSize == 0) {\n            loadAction()\n        }\n    }\n\n    /**\n     * Executing loading.\n     * 执行加载的操作\n     */\n    private fun loadAction() {\n        if (!isAutoLoadMore || onTrailingListener?.isAllowLoading() == false) {\n            // 不允许进行加载更多（例如：正在进行下拉刷新）\n            // Loading more is forbidden at the moment.(eg: when pulling down to refresh)\n            return\n        }\n\n        if (mNotFullPageNextLoadFlag || mDelayNextLoadFlag) {\n            return\n        }\n\n        if (loadState is LoadState.NotLoading && !loadState.endOfPaginationReached) {\n            val recyclerView = recyclerView ?: return\n\n            if (recyclerView.isComputingLayout) {\n                // 如果 RecyclerView 当前正在计算布局，则延迟执行，避免崩溃\n                // To avoid crash. Delay to load more if the recyclerview is computingLayout.\n                mDelayNextLoadFlag = true\n                recyclerView.post {\n                    mDelayNextLoadFlag = false\n                    invokeLoadMore()\n                }\n                return\n            }\n\n            invokeLoadMore()\n        }\n    }\n\n    internal fun checkPreload(itemCount: Int, currentPosition: Int) {\n        if (currentPosition > itemCount - 1) return\n\n        if (preloadSize > 0 && itemCount - currentPosition - 1 <= preloadSize) {\n            loadAction()\n        }\n    }\n\n    fun invokeLoadMore() {\n        loadState = LoadState.Loading\n        onTrailingListener?.onLoad()\n    }\n\n    fun invokeFailRetry() {\n        loadState = LoadState.Loading\n        onTrailingListener?.onFailRetry()\n    }\n\n    /**\n     * Call this method, Check disable load more if not full page.\n     * 调用此方法，当数据不满足一屏幕的时候，暂停加载更多。应在提交数据 notify 后马上调用。\n     */\n    fun checkDisableLoadMoreIfNotFullPage() {\n        // 先把标记位设置为false\n        mNotFullPageNextLoadFlag = true\n        val recyclerView = this.recyclerView ?: return\n        val manager = recyclerView.layoutManager ?: return\n\n        if (manager is LinearLayoutManager) {\n            recyclerView.post {\n                if (isFullScreen()) {\n                    mNotFullPageNextLoadFlag = false\n                }\n            }\n        } else if (manager is StaggeredGridLayoutManager) {\n            recyclerView.post {\n                val positions = IntArray(manager.spanCount)\n                manager.findLastCompletelyVisibleItemPositions(positions)\n                val pos = getTheBiggestNumber(positions) + 1\n                if (pos != recyclerView.adapter?.itemCount) {\n                    mNotFullPageNextLoadFlag = false\n                }\n            }\n        }\n    }\n\n    private fun isFullScreen(): Boolean {\n        val adapter = recyclerView?.adapter ?: return true\n        val llm = recyclerView?.layoutManager  as? LinearLayoutManager ?: return true\n\n        return (llm.findLastCompletelyVisibleItemPosition() + 1) != adapter.itemCount ||\n                llm.findFirstCompletelyVisibleItemPosition() != 0\n    }\n\n    private fun getTheBiggestNumber(numbers: IntArray?): Int {\n        var tmp = -1\n        if (numbers == null || numbers.isEmpty()) {\n            return tmp\n        }\n        for (num in numbers) {\n            if (num > tmp) {\n                tmp = num\n            }\n        }\n        return tmp\n    }\n\n    /**\n     * Set load state listener\n     * 设置监听事件\n     * @param listener\n     */\n    fun setOnLoadMoreListener(listener: OnTrailingListener?) = apply {\n        this.onTrailingListener = listener\n    }\n\n    override fun toString(): String {\n        return \"\"\"\n            TrailingLoadStateAdapter ->\n            [isLoadEndDisplay: $isLoadEndDisplay],\n            [isAutoLoadMore: $isAutoLoadMore],\n            [preloadSize: $preloadSize],\n            [loadState: $loadState]\n        \"\"\".trimIndent()\n    }\n\n    interface OnTrailingListener {\n\n        /**\n         * \"加载更多\"执行的逻辑\n         */\n        fun onLoad()\n\n        /**\n         * 失败的情况下，点击重试执行的逻辑\n         */\n        fun onFailRetry()\n\n        /**\n         * Whether to allow loading.\n         * 是否允许进行加载更多（例如下拉刷新时，就不应该进行加载更多）\n         */\n        fun isAllowLoading(): Boolean = true\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/util/AdapterUtils.kt",
    "content": "package com.chad.library.adapter4.util\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.annotation.LayoutRes\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.recyclerview.widget.StaggeredGridLayoutManager\n\n/**\n * An extension function to getItemView.\n * 扩展方法，用于获取View\n * @receiver ViewGroup parent\n * @param layoutResId Int\n * @return View\n */\nfun ViewGroup.getItemView(@LayoutRes layoutResId: Int): View {\n    return LayoutInflater.from(this.context).inflate(layoutResId, this, false)\n}\n\n/**\n * If the hold view use StaggeredGridLayoutManager they should using all span area.\n * 如果 ViewHolder 使用 StaggeredGridLayoutManager 布局，则铺满一行。\n */\nfun RecyclerView.ViewHolder.asStaggeredGridFullSpan() {\n    if (this.itemView.layoutParams is StaggeredGridLayoutManager.LayoutParams) {\n        (this.itemView.layoutParams as StaggeredGridLayoutManager.LayoutParams).isFullSpan = true\n    }\n}"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/util/ItemClickUtils.kt",
    "content": "package com.chad.library.adapter4.util\n\nimport android.view.View\nimport androidx.annotation.IdRes\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.BaseQuickAdapter\n\n/**\n * @author 李沐阳\n * @date 2023/5/29\n * @description\n */\nprivate abstract class DebouncedClickListener<T : Any>(private val interval: Long) :\n    BaseQuickAdapter.OnItemClickListener<T>, BaseQuickAdapter.OnItemChildClickListener<T> {\n    private var mLastClickTime: Long = 0\n\n    override fun onClick(adapter: BaseQuickAdapter<T, *>, view: View, position: Int) {\n        val nowTime = System.currentTimeMillis()\n        val diffTime = nowTime - mLastClickTime\n        // 当用户修改系统时间时，可能会导致diffTime为负数\n        if (diffTime >= interval || diffTime < 0) {\n            mLastClickTime = nowTime\n            onSingleClick(adapter, view, position)\n        }\n    }\n\n    override fun onItemClick(adapter: BaseQuickAdapter<T, *>, view: View, position: Int) {\n        val nowTime = System.currentTimeMillis()\n        val diffTime = nowTime - mLastClickTime\n        // 当用户修改系统时间时，可能会导致diffTime为负数\n        if (diffTime >= interval || diffTime < 0) {\n            mLastClickTime = nowTime\n            onSingleClick(adapter, view, position)\n        }\n    }\n\n    abstract fun onSingleClick(adapter: BaseQuickAdapter<T, *>, view: View, position: Int)\n}\n\n\n/**\n * 去除点击抖动的点击方法\n *\n * @param time 间隔时间，单位：毫秒\n * @param block\n * @receiver\n */\nfun <T : Any, VH : RecyclerView.ViewHolder> BaseQuickAdapter<T, VH>.setOnDebouncedItemClick(\n    time: Long = 500,\n    block: BaseQuickAdapter.OnItemClickListener<T>\n) = this.setOnItemClickListener(object : DebouncedClickListener<T>(time) {\n    override fun onSingleClick(adapter: BaseQuickAdapter<T, *>, view: View, position: Int) {\n        block.onClick(adapter, view, position)\n    }\n})\n\n/**\n * 去除 Child View 点击抖动的点击方法\n *\n * @param time 间隔时间，单位：毫秒\n * @param block\n * @receiver\n */\nfun <T : Any, VH : RecyclerView.ViewHolder> BaseQuickAdapter<T, VH>.addOnDebouncedChildClick(\n    @IdRes id: Int,\n    time: Long = 500,\n    block: BaseQuickAdapter.OnItemChildClickListener<T>\n) = this.addOnItemChildClickListener(id, object : DebouncedClickListener<T>(time) {\n    override fun onSingleClick(adapter: BaseQuickAdapter<T, *>, view: View, position: Int) {\n        block.onItemClick(adapter, view, position)\n    }\n})\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/viewholder/DataBindingHolder.java",
    "content": "package com.chad.library.adapter4.viewholder;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport androidx.annotation.LayoutRes;\nimport androidx.annotation.NonNull;\nimport androidx.databinding.DataBindingUtil;\nimport androidx.databinding.ViewDataBinding;\nimport androidx.recyclerview.widget.RecyclerView;\n\n/**\n * A viewHolder quick to use when the project enabled ViewDataBinding.\n * ViewDataBinding 快速使用的 ViewHolder\n * @param <DB> ViewDataBinding\n */\npublic class DataBindingHolder<DB extends ViewDataBinding> extends RecyclerView.ViewHolder {\n\n    private final DB binding;\n\n    public DataBindingHolder(DB binding) {\n        super(binding.getRoot());\n        this.binding = binding;\n    }\n\n    public DataBindingHolder(@NonNull View itemView) {\n        super(itemView);\n        this.binding = DataBindingUtil.bind(itemView);\n\n        if (this.binding == null)\n            throw new NullPointerException(\"DataBinding is Null. Please check Layout resource or ItemView\");\n    }\n\n    public DataBindingHolder(@LayoutRes int resId, @NonNull ViewGroup parent) {\n        this(LayoutInflater.from(parent.getContext()).inflate(resId, parent, false));\n    }\n\n    @NonNull\n    public DB getBinding() {\n        return binding;\n    }\n}\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/viewholder/QuickViewHolder.kt",
    "content": "package com.chad.library.adapter4.viewholder\n\nimport android.graphics.Bitmap\nimport android.graphics.drawable.Drawable\nimport android.util.SparseArray\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.*\nimport androidx.core.content.ContextCompat\nimport androidx.recyclerview.widget.RecyclerView\n\n/**\n * Quick-use ViewHolder class\n * 快速使用的 ViewHolder 类\n */\nopen class QuickViewHolder(view: View) : RecyclerView.ViewHolder(view) {\n\n    constructor(\n        @LayoutRes resId: Int, parent: ViewGroup\n    ) : this(LayoutInflater.from(parent.context).inflate(resId, parent, false))\n\n    /**\n     * Views indexed with their IDs\n     * 记录找到的 view\n     */\n    private val views: SparseArray<View> = SparseArray()\n\n   fun <T : View> getView(@IdRes viewId: Int): T {\n        val view = getViewOrNull<T>(viewId)\n        checkNotNull(view) { \"No view found with id $viewId\" }\n        return view\n    }\n\n    @Suppress(\"UNCHECKED_CAST\")\n    fun <T : View> getViewOrNull(@IdRes viewId: Int): T? {\n        val view = views.get(viewId) ?: return itemView.findViewById<T>(viewId)?.apply {\n            views.put(viewId, this)\n        }\n        return view as? T\n    }\n\n    fun <T : View> Int.findView(): T? {\n        return itemView.findViewById(this)\n    }\n\n    fun setText(@IdRes viewId: Int, value: CharSequence?) = apply {\n        getView<TextView>(viewId).text = value\n    }\n\n    fun setText(@IdRes viewId: Int, @StringRes strId: Int) = apply {\n        getView<TextView>(viewId).setText(strId)\n    }\n\n    fun setTextColor(@IdRes viewId: Int, @ColorInt color: Int) = apply {\n        getView<TextView>(viewId).setTextColor(color)\n    }\n\n    fun setTextColorRes(@IdRes viewId: Int, @ColorRes colorRes: Int) = apply {\n        getView<TextView>(viewId).setTextColor(ContextCompat.getColor(itemView.context, colorRes))\n    }\n\n    fun setImageResource(@IdRes viewId: Int, @DrawableRes imageResId: Int) = apply {\n        getView<ImageView>(viewId).setImageResource(imageResId)\n    }\n\n    fun setImageDrawable(@IdRes viewId: Int, drawable: Drawable?) = apply {\n        getView<ImageView>(viewId).setImageDrawable(drawable)\n    }\n\n    fun setImageBitmap(@IdRes viewId: Int, bitmap: Bitmap?) = apply {\n        getView<ImageView>(viewId).setImageBitmap(bitmap)\n    }\n\n    fun setBackgroundColor(@IdRes viewId: Int, @ColorInt color: Int) = apply {\n        getView<View>(viewId).setBackgroundColor(color)\n    }\n\n    fun setBackgroundResource(@IdRes viewId: Int, @DrawableRes backgroundRes: Int) = apply {\n        getView<View>(viewId).setBackgroundResource(backgroundRes)\n    }\n\n    fun setVisible(@IdRes viewId: Int, isVisible: Boolean) = apply {\n        getView<View>(viewId).visibility = if (isVisible) View.VISIBLE else View.INVISIBLE\n    }\n\n    fun setGone(@IdRes viewId: Int, isGone: Boolean) = apply {\n        getView<View>(viewId).visibility = if (isGone) View.GONE else View.VISIBLE\n    }\n\n    fun setEnabled(@IdRes viewId: Int, isEnabled: Boolean) = apply {\n        getView<View>(viewId).isSelected\n        getView<View>(viewId).isEnabled = isEnabled\n    }\n\n    fun isEnabled(@IdRes viewId: Int) = getView<View>(viewId).isEnabled\n\n    fun setSelected(@IdRes viewId: Int, isSelected: Boolean) = apply {\n        getView<View>(viewId).isSelected = isSelected\n    }\n\n    fun isSelected(@IdRes viewId: Int) = getView<View>(viewId).isSelected\n\n\n}\n\n"
  },
  {
    "path": "library/src/main/java/com/chad/library/adapter4/viewholder/StateLayoutVH.kt",
    "content": "package com.chad.library.adapter4.viewholder\n\nimport android.view.Gravity\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport androidx.recyclerview.widget.RecyclerView\nimport com.chad.library.adapter4.fullspan.FullSpanAdapterType\n\n/**\n * An emptyState viewHolder. (For internal use only)\n * 内部使用的空状态ViewHolder\n *\n * @property stateLayout\n * @constructor Create empty Empty layout v h\n */\ninternal class StateLayoutVH(\n    parent: ViewGroup,\n    stateView: View?,\n    isUseStateViewSize: Boolean,\n    private val stateLayout: FrameLayout = FrameLayout(parent.context).apply {\n        layoutParams = ViewGroup.LayoutParams(\n            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT\n        )\n        setStateView(this, stateView, isUseStateViewSize)\n    }\n) : RecyclerView.ViewHolder(stateLayout), FullSpanAdapterType {\n\n\n    fun changeStateView(stateView: View?, isUseStateViewSize: Boolean) {\n        setStateView(stateLayout, stateView, isUseStateViewSize)\n    }\n\n    companion object {\n        private fun setStateView(rootView: ViewGroup, stateView: View?, isUseStateViewSize: Boolean) {\n            if (stateView == null) {\n                rootView.removeAllViews()\n                return\n            }\n\n            if (rootView.childCount == 1) {\n                val old = rootView.getChildAt(0)\n                if (old == stateView) {\n                    // 如果是同一个view，不进行操作\n                    return\n                }\n            }\n\n            stateView.parent.run {\n                if (this is ViewGroup) {\n                    this.removeView(stateView)\n                }\n            }\n\n            if (stateView.layoutParams == null) {\n                stateView.layoutParams = FrameLayout.LayoutParams(\n                    FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT\n                ).apply {\n                    gravity = Gravity.CENTER\n                }\n            }\n\n            if (isUseStateViewSize) {\n                val lp = rootView.layoutParams\n                lp.height = stateView.layoutParams.height\n                lp.width = stateView.layoutParams.width\n                rootView.layoutParams = lp\n            }\n\n            rootView.removeAllViews()\n            rootView.addView(stateView)\n        }\n    }\n}\n"
  },
  {
    "path": "library/src/main/res/layout/brvah_leading_load_more.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"40dp\">\n\n    <ProgressBar\n        android:id=\"@+id/loading_progress\"\n        android:layout_gravity=\"center\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        style=\"?android:attr/progressBarStyleSmall\"/>\n\n</FrameLayout>"
  },
  {
    "path": "library/src/main/res/layout/brvah_trailing_load_more.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"40dp\">\n\n    <LinearLayout\n        android:id=\"@+id/load_more_loading_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:gravity=\"center\"\n        android:orientation=\"horizontal\">\n\n        <ProgressBar\n            android:id=\"@+id/loading_progress\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            style=\"?android:attr/progressBarStyleSmall\"\n            android:layout_marginRight=\"4dp\"/>\n\n        <TextView\n            android:id=\"@+id/loading_text\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginLeft=\"4dp\"\n            android:text=\"@string/brvah_loading\"\n            android:textColor=\"@android:color/black\"\n            android:textSize=\"14sp\"/>\n    </LinearLayout>\n\n    <FrameLayout\n        android:id=\"@+id/load_more_load_fail_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:text=\"@string/brvah_load_failed\"/>\n\n    </FrameLayout>\n\n    <FrameLayout\n        android:id=\"@+id/load_more_load_complete_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:text=\"@string/brvah_load_complete\"\n            android:textColor=\"@android:color/darker_gray\"/>\n    </FrameLayout>\n\n    <FrameLayout\n        android:id=\"@+id/load_more_load_end_view\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"gone\">\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center\"\n            android:text=\"@string/brvah_load_end\"\n            android:textColor=\"@android:color/darker_gray\"/>\n    </FrameLayout>\n</FrameLayout>"
  },
  {
    "path": "library/src/main/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <item name=\"BaseQuickAdapter_viewholder_support\" type=\"id\"/>\n    <item name=\"BaseQuickAdapter_swiping_support\" type=\"id\"/>\n    <item name=\"BaseQuickAdapter_dragging_support\" type=\"id\"/>\n    <item name=\"BaseQuickAdapter_databinding_support\" type=\"id\"/>\n\n    <item name=\"BaseQuickAdapter_key_multi\" type=\"id\"/>\n\n    <item name=\"BaseQuickAdapter_empty_view\" type=\"id\"/>\n</resources>"
  },
  {
    "path": "library/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"brvah_loading\">加载中...</string>\n    <string name=\"brvah_load_failed\">加载失败，点击重试</string>\n    <string name=\"brvah_load_end\">没有更多数据</string>\n    <string name=\"brvah_load_complete\">点击加载更多</string>\n</resources>\n"
  },
  {
    "path": "library/src/main/res/values-en/strings.xml",
    "content": "<resources>\n    <string name=\"brvah_loading\">Loading...</string>\n    <string name=\"brvah_load_failed\">Load failed, click retry</string>\n    <string name=\"brvah_load_end\">No more data</string>\n    <string name=\"brvah_load_complete\">Click to load more</string>\n</resources>\n"
  },
  {
    "path": "library/src/main/res/values-zh-rHK/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"brvah_loading\">加載中...</string>\n    <string name=\"brvah_load_failed\">加載失敗，點擊重試</string>\n    <string name=\"brvah_load_end\">沒有更多數據</string>\n    <string name=\"brvah_load_complete\">點擊加載更多</string>\n</resources>"
  },
  {
    "path": "library/src/main/res/values-zh-rTW/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"brvah_loading\">加載中...</string>\n    <string name=\"brvah_load_failed\">加載失敗，點擊重試</string>\n    <string name=\"brvah_load_end\">沒有更多數據</string>\n    <string name=\"brvah_load_complete\">點擊加載更多</string>\n</resources>"
  },
  {
    "path": "settings.gradle",
    "content": "pluginManagement {\n    repositories {\n        gradlePluginPortal()\n        google()\n        mavenCentral()\n    }\n}\n\ndependencyResolutionManagement {\n    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)\n    repositories {\n        google()\n        mavenCentral()\n    }\n}\n\ninclude ':app', ':library'\n"
  }
]