├── .circleci └── config.yml ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── pull_request_template.md ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── chad │ │ └── baserecyclerviewadapterhelper │ │ ├── MyApplication.kt │ │ ├── activity │ │ ├── WelcomeActivity.java │ │ ├── animation │ │ │ ├── AnimationUseActivity.kt │ │ │ └── adapter │ │ │ │ └── AnimationAdapter.kt │ │ ├── databinding │ │ │ ├── DataBindingUseActivity.java │ │ │ └── adapter │ │ │ │ └── DataBindingAdapter.java │ │ ├── differ │ │ │ ├── DifferActivity.java │ │ │ └── adapter │ │ │ │ ├── DiffEntityCallback.java │ │ │ │ └── DiffUtilAdapter.java │ │ ├── dragswipe │ │ │ ├── DefaultDragAndSwipeActivity.kt │ │ │ ├── DragAndSwipeDifferActivity.kt │ │ │ ├── DragAndSwipeUseActivity.java │ │ │ ├── HeaderDragAndSwipe.kt │ │ │ ├── HeaderDragAndSwipeActivity.kt │ │ │ ├── ManualDragAndSwipeUseActivity.java │ │ │ └── adapter │ │ │ │ ├── DiffDragAndSwipeAdapter.kt │ │ │ │ ├── DragAndSwipeAdapter.java │ │ │ │ └── HeaderDragAndSwipeAdapter.kt │ │ ├── emptyview │ │ │ ├── EmptyViewUseActivity.kt │ │ │ └── adapter │ │ │ │ └── EmptyViewAdapter.kt │ │ ├── headerfooter │ │ │ ├── HeaderAndFooterUseActivity.kt │ │ │ └── adapter │ │ │ │ ├── FooterAdapter.kt │ │ │ │ ├── HeaderAdapter.kt │ │ │ │ └── HeaderAndFooterAdapter.kt │ │ ├── home │ │ │ ├── HomeActivity.kt │ │ │ └── adapter │ │ │ │ ├── HomeAdapter.kt │ │ │ │ └── HomeTopHeaderAdapter.kt │ │ ├── itemclick │ │ │ ├── ItemClickActivity.kt │ │ │ └── adapter │ │ │ │ └── ItemClickAdapter.java │ │ ├── loadmore │ │ │ ├── AutoLoadMoreRefreshUseActivity.kt │ │ │ ├── NoAutoAutoLoadMoreRefreshUseActivity.kt │ │ │ └── adapter │ │ │ │ ├── CustomLoadMoreAdapter.kt │ │ │ │ └── RecyclerViewAdapter.kt │ │ ├── scene │ │ │ ├── GroupDemoActivity.kt │ │ │ └── adapter │ │ │ │ └── GroupAdapter.kt │ │ └── upfetch │ │ │ ├── UpFetchUseActivity.kt │ │ │ └── adapter │ │ │ └── UpFetchAdapter.kt │ │ ├── animator │ │ ├── CustomAnimation1.java │ │ ├── CustomAnimation2.java │ │ └── CustomAnimation3.java │ │ ├── base │ │ ├── BaseActivity.kt │ │ └── BaseViewBindingActivity.kt │ │ ├── data │ │ └── DataServer.kt │ │ ├── decoration │ │ ├── GridItemDecoration.java │ │ └── GridSectionAverageGapItemDecoration.java │ │ ├── entity │ │ ├── ClickEntity.java │ │ ├── DiffEntity.java │ │ ├── GroupDemoEntity.kt │ │ ├── HomeEntity.kt │ │ ├── Movie.java │ │ ├── MoviePresenter.java │ │ └── Status.java │ │ ├── utils │ │ ├── AppUtils.kt │ │ ├── ClickableMovementMethod.java │ │ ├── Ext.kt │ │ ├── Tips.java │ │ └── VibratorUtils.kt │ │ └── widget │ │ └── BRVAHToolbar.kt │ └── res │ ├── anim │ ├── item_animation_from_bottom.xml │ └── layout_animation_from_bottom.xml │ ├── drawable-v21 │ └── touch_bg.xml │ ├── drawable-xhdpi │ ├── ic_group_item_bottom_bg.9.png │ ├── ic_group_item_mid_bg.9.png │ └── ic_group_item_top_bg.9.png │ ├── drawable │ ├── actionbar_bottom_bg.xml │ ├── brvah_sample_footer_loading.png │ ├── brvah_sample_footer_loading_progress.xml │ ├── custom_text_state_color.xml │ ├── gv_animation.png │ ├── gv_up_fetch.xml │ ├── selector_item_child.xml │ ├── shape_right_top_float_bg.xml │ ├── thumb_drawable.xml │ └── touch_bg.xml │ ├── layout │ ├── activity_animation_use.xml │ ├── activity_choose_multiple_item_use_type.xml │ ├── activity_choose_node_use_type.xml │ ├── activity_diffutil.xml │ ├── activity_empty_view_use.xml │ ├── activity_home.xml │ ├── activity_load_more.xml │ ├── activity_universal_recycler.xml │ ├── activity_welcome.xml │ ├── def_section_head.xml │ ├── empty_view.xml │ ├── error_view.xml │ ├── footer_view.xml │ ├── head_view.xml │ ├── home_item_view.xml │ ├── item_click_childview.xml │ ├── item_click_view.xml │ ├── item_draggable_view.xml │ ├── item_group_type.xml │ ├── item_header_and_footer.xml │ ├── item_image_view.xml │ ├── item_img_text_view.xml │ ├── item_long_click_childview.xml │ ├── item_long_click_view.xml │ ├── item_movie.xml │ ├── item_section_content.xml │ ├── layout_animation.xml │ ├── layout_title_bar.xml │ ├── layout_tool_bar.xml │ ├── loading_view.xml │ ├── node_footer.xml │ ├── toolbar_layout.xml │ ├── top_view.xml │ └── view_load_more.xml │ ├── mipmap-hdpi │ └── logo.png │ ├── mipmap-mdpi │ └── logo.png │ ├── mipmap-xhdpi │ ├── animation_img1.png │ ├── animation_img2.png │ ├── animation_img3.png │ ├── arrow_b.png │ ├── arrow_r.png │ ├── back.png │ ├── click_head_img_0.png │ ├── click_head_img_1.png │ ├── databinding_img.png │ ├── drag_icon.png │ ├── empty_icon.png │ ├── gv_animation.png │ ├── gv_databinding.png │ ├── gv_drag_and_swipe.png │ ├── gv_empty.png │ ├── gv_expandable.png │ ├── gv_header_and_footer.png │ ├── gv_item_click.png │ ├── gv_multipleltem.png │ ├── gv_pulltorefresh.png │ ├── gv_section.png │ ├── head_img.png │ ├── head_img_1.png │ ├── headerandfooter_img1.png │ ├── logo.png │ ├── monkey.png │ └── top_background.png │ ├── mipmap-xxhdpi │ ├── add_icon.png │ ├── animation_img1.png │ ├── animation_img2.png │ ├── animation_img3.png │ ├── buy_icon.png │ ├── head_img0.png │ ├── head_img1.png │ ├── head_img2.png │ ├── header_background.png │ ├── headerandfooter_img1.png │ ├── logo.png │ ├── m_img1.png │ ├── m_img2.png │ ├── reset_icon.png │ ├── rm_icon.png │ └── welcome.png │ ├── values-v21 │ └── styles.xml │ ├── values-zh │ └── strings.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── demo └── app-release.apk ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── chad │ │ └── library │ │ └── adapter4 │ │ ├── BaseDifferAdapter.kt │ │ ├── BaseMultiItemAdapter.kt │ │ ├── BaseQuickAdapter.kt │ │ ├── BaseSingleItemAdapter.kt │ │ ├── QuickAdapterHelper.kt │ │ ├── animation │ │ ├── AlphaInAnimation.kt │ │ ├── ItemAnimator.kt │ │ ├── ScaleInAnimation.kt │ │ ├── SlideInBottomAnimation.kt │ │ ├── SlideInLeftAnimation.kt │ │ └── SlideInRightAnimation.kt │ │ ├── dragswipe │ │ ├── DragSwipeExt.kt │ │ ├── QuickDragAndSwipe.kt │ │ └── listener │ │ │ ├── DragAndSwipeDataCallback.kt │ │ │ ├── OnItemDragListener.java │ │ │ └── OnItemSwipeListener.java │ │ ├── fullspan │ │ └── FullSpanAdapterType.kt │ │ ├── layoutmanager │ │ └── QuickGridLayoutManager.kt │ │ ├── loadState │ │ ├── LoadState.kt │ │ ├── LoadStateAdapter.kt │ │ ├── leading │ │ │ ├── DefaultLeadingLoadStateAdapter.kt │ │ │ └── LeadingLoadStateAdapter.kt │ │ └── trailing │ │ │ ├── DefaultTrailingLoadStateAdapter.kt │ │ │ └── TrailingLoadStateAdapter.kt │ │ ├── util │ │ ├── AdapterUtils.kt │ │ └── ItemClickUtils.kt │ │ └── viewholder │ │ ├── DataBindingHolder.java │ │ ├── QuickViewHolder.kt │ │ └── StateLayoutVH.kt │ └── res │ ├── layout │ ├── brvah_leading_load_more.xml │ └── brvah_trailing_load_more.xml │ ├── values-en │ └── strings.xml │ ├── values-zh-rHK │ └── strings.xml │ ├── values-zh-rTW │ └── strings.xml │ └── values │ ├── ids.xml │ └── strings.xml └── settings.gradle /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: ~/code 5 | docker: 6 | - image: cimg/android:2023.04 7 | environment: 8 | JVM_OPTS: -Xmx3200m 9 | steps: 10 | - checkout 11 | - restore_cache: 12 | key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} 13 | - run: 14 | name: Download Dependencies 15 | command: ./gradlew androidDependencies 16 | - save_cache: 17 | paths: 18 | - ~/.gradle 19 | key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} 20 | - run: 21 | name: Run Tests 22 | command: ./gradlew lint test 23 | - store_artifacts: 24 | path: app/build/reports 25 | destination: reports 26 | - store_test_results: 27 | path: app/build/test-results 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Additional context** 24 | Add any other context about the problem here. 25 | 26 | 1. 尝试在[历史问题](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues?q=is%3Aissue+is%3Aclosed)搜索答案。 27 | 2. 尝试阅读[文档](http://www.jianshu.com/p/b343fcff51b0)找到答案。 28 | 3. 尝试阅读[Demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)找到答案。 29 | 4. 尝试自己检查或试验以找到答案。 30 | 5. 尝试阅读源代码以找到答案。 31 | 6. 请勿将产品的一些特殊交互需求 和 该库暂不支持作为bug混为一谈,请您仔细甄别 32 | 33 | 如果以上都尝试过了请提一个新的[issues](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues/new) 34 | 参考[提問的智慧](https://github.com/FredWe/How-To-Ask-Questions-The-Smart-Way) 35 | 36 | 如果还是没有找到答案,提问请带上这几个必要信息 37 | 1. 当前使用的版本号 38 | 2. 复现操作描述 39 | 3. 使用代码 40 | 3. crash日志 41 | 4. gif复现效果 42 | 5. 抽取demo 43 | **将你出现的问题代码抽出来成一个可直接运行的项目。(最好fork[本库](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)修改)** 44 | **在本地修改demo,然后把commit push到github上,在issue里贴下demo的地址。** 45 | 46 | **有详细的描述才能使得我们更快速的定位问题并解决问题,感谢配合!** 47 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Thank you for contributing to BaseRecyclerViewAdapterHelper. Before pressing the "Create Pull Request" button, please consider the following points: 2 | 3 | - [1] Please give a description about what and why you are contributing, even if it's trivial. 4 | 5 | - [2] Please include the issue list number(s) or other PR numbers in the description if you are contributing in response to those. 6 | 7 | - [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. 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #///////////////////////////////////////////////////////////////////////////// 2 | # OS generated files 3 | #///////////////////////////////////////////////////////////////////////////// 4 | 5 | .DS_Store 6 | ehthumbs.db 7 | Thumbs.db 8 | 9 | # Built application files 10 | *.apk 11 | *.ap_ 12 | 13 | # Files for the Dalvik VM 14 | *.dex 15 | 16 | # Java class files 17 | *.class 18 | 19 | # Generated files 20 | bin/ 21 | gen/ 22 | 23 | # Gradle files 24 | .gradle/ 25 | build/ 26 | 27 | # Local configuration file (sdk path, etc) 28 | local.properties 29 | 30 | # Proguard folder generated by Eclipse 31 | proguard/ 32 | 33 | 34 | # Android Studio project files 35 | *.iml 36 | .gradle 37 | .idea 38 | build 39 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | dist: trusty 3 | jdk: oraclejdk11 4 | sudo: false 5 | 6 | android: 7 | components: 8 | - tools 9 | - platform-tools 10 | - build-tools-33.0.0 11 | - android-32 12 | - extra-android-m2repository 13 | before_install: 14 | - chmod +x gradlew 15 | - mkdir "$ANDROID_HOME/licenses" || true 16 | # Hack to accept Android licenses 17 | - yes | sdkmanager "platforms;android-32" 18 | 19 | script: 20 | - ./gradlew assembleRelease 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 陈宇明 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://user-images.githubusercontent.com/7698209/33198075-ef8f2230-d123-11e7-85a3-4cb9b22f877d.png) 2 | [![](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) [![](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) 3 | # BRVAH 4 | 5 | Powerful and flexible RecyclerView Adapter, 6 | Please feel free to use this. (Welcome to **Star** and **Fork**) 7 | 8 | 强大而灵活的RecyclerView Adapter(欢迎 **Star** 和 **Fork**) 9 | 10 | ​ 11 | 新版4.x.x已发布,完美兼容`ConcatAdapter`,解决了许多遗留问题,拆分了功能模块,BaseAdapter更加简洁干净。“多类型布局”更加灵活。向上、向下加载得到极大加强。 12 | v4版本已经上传 maven 中央仓库,不需要再引入三方仓库配置了。欢迎尝试。 13 | ``` 14 | implementation "io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.4" 15 | ``` 16 | 17 | 18 | Of course, you can continue to use the [2.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/2.x) version. 19 | 20 | 当然,你也可以继续使用[2.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/2.x) 版本、[3.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/3.x/readme/0-BaseRecyclerViewAdapterHelper.md)版本。 21 | 22 | # Document 23 | - English Writing ... 24 | - [3.0版本 中文](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/3.x/readme/0-BaseRecyclerViewAdapterHelper.md) 25 | - [4.0版本 中文](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki) 26 | 27 | 28 | (由于各位项目成员工作较为繁忙,请各位同学谅解) 29 | 30 | ## v4 版本 Demo 31 | [wiki](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki) 32 | 33 | 34 | # proguard-rules.pro 35 | > 此资源库自带混淆规则,并且会自动导入,正常情况下无需手动导入。 36 | 37 | > The library comes with `proguard-rules.pro` rules and is automatically imported. Normally no manual import is required. 38 | > You can also go here to view [proguard-rules](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/library/proguard-rules.pro) 39 | 40 | 41 | 42 | 43 | # Thanks 44 | [JoanZapata / base-adapter-helper](https://github.com/JoanZapata/base-adapter-helper) 45 | 46 | # [License](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/LICENSE) 47 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | .DS_Store 3 | local.properties 4 | 5 | # build files 6 | build/ 7 | bin/ 8 | gen/ 9 | output/ 10 | 11 | # android studio 12 | *.iml 13 | .idea 14 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | id 'kotlin-kapt' 5 | id 'com.google.devtools.ksp' 6 | } 7 | 8 | android { 9 | compileSdk 35 10 | 11 | defaultConfig { 12 | applicationId "com.chad.baserecyclerviewadapterhelper" 13 | minSdk 23 14 | targetSdk 35 15 | versionCode 10 16 | versionName "4.0" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled true 21 | zipAlignEnabled true 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | debug { 25 | minifyEnabled false 26 | zipAlignEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_17 33 | targetCompatibility JavaVersion.VERSION_17 34 | } 35 | kotlinOptions { 36 | jvmTarget = "17" 37 | } 38 | 39 | buildFeatures { 40 | viewBinding = true 41 | dataBinding = true 42 | } 43 | namespace 'com.chad.baserecyclerviewadapterhelper' 44 | } 45 | 46 | dependencies { 47 | implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') 48 | implementation project(path: ':library') 49 | implementation 'com.google.android.material:material:1.12.0' 50 | implementation 'androidx.cardview:cardview:1.0.0' 51 | implementation 'androidx.appcompat:appcompat:1.7.0' 52 | implementation "androidx.core:core-ktx:1.16.0" 53 | 54 | implementation 'com.kyleduo.switchbutton:library:2.1.0' 55 | implementation 'androidx.recyclerview:recyclerview:1.4.0' 56 | implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" 57 | 58 | implementation("com.squareup.moshi:moshi:1.15.1") 59 | ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.1") 60 | 61 | implementation 'com.jaredrummler:material-spinner:1.3.1' 62 | } 63 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/huasheng/Desktop/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | #BaseRecyclerViewAdapterHelper 19 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 31 | 34 | 37 | 40 | 43 | 46 | 49 | 52 | 55 | 58 | 61 | 64 | 65 | 68 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.kt: -------------------------------------------------------------------------------- 1 | /* 2 | ******************************* Copyright (c)*********************************\ 3 | ** 4 | ** (c) Copyright 2015, Allen, china, shanghai 5 | ** All Rights Reserved 6 | ** 7 | ** 8 | ** 9 | **-----------------------------------版本信息------------------------------------ 10 | ** 版 本: V0.1 11 | ** 12 | **------------------------------------------------------------------------------ 13 | ********************************End of Head************************************\ 14 | */ 15 | package com.chad.baserecyclerviewadapterhelper 16 | 17 | import android.app.Application 18 | import com.chad.baserecyclerviewadapterhelper.utils.AppUtils 19 | 20 | /** 21 | * 文 件 名: MyApplication 22 | * 创 建 人: Allen 23 | * 创建日期: 16/12/24 15:33 24 | * 邮 箱: AllenCoder@126.com 25 | * 修改时间: 26 | * 修改备注: 27 | */ 28 | class MyApplication : Application() { 29 | override fun onCreate() { 30 | super.onCreate() 31 | AppUtils.init(this) 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/WelcomeActivity.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.os.Handler; 6 | 7 | import androidx.appcompat.app.AppCompatActivity; 8 | 9 | import com.chad.baserecyclerviewadapterhelper.R; 10 | import com.chad.baserecyclerviewadapterhelper.activity.home.HomeActivity; 11 | 12 | public class WelcomeActivity extends AppCompatActivity { 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_welcome); 18 | new Handler().postDelayed(new Runnable() { 19 | @Override 20 | public void run() { 21 | Intent intent = new Intent(WelcomeActivity.this, HomeActivity.class); 22 | startActivity(intent); 23 | finish(); 24 | } 25 | }, 1000); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/AnimationUseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.animation 2 | 3 | import android.os.Bundle 4 | import com.chad.baserecyclerviewadapterhelper.activity.animation.adapter.AnimationAdapter 5 | import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation1 6 | import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation2 7 | import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation3 8 | import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity 9 | import com.chad.baserecyclerviewadapterhelper.databinding.ActivityAnimationUseBinding 10 | import com.chad.library.adapter4.BaseQuickAdapter 11 | 12 | /** 13 | * https://github.com/CymChad/BaseRecyclerViewAdapterHelper 14 | * 15 | * 16 | * modify by AllenCoder 17 | */ 18 | class AnimationUseActivity : BaseViewBindingActivity() { 19 | 20 | private val mAnimationAdapter: AnimationAdapter = AnimationAdapter().apply { 21 | // 打开 Adapter 的动画 22 | animationEnable = true 23 | // 是否是首次显示时候加载动画 24 | isAnimationFirstOnly = false 25 | } 26 | 27 | override fun initBinding(): ActivityAnimationUseBinding { 28 | return ActivityAnimationUseBinding.inflate(layoutInflater) 29 | } 30 | 31 | override fun onCreate(savedInstanceState: Bundle?) { 32 | super.onCreate(savedInstanceState) 33 | 34 | viewBinding.titleBar.title = "Animation Use" 35 | viewBinding.titleBar.setOnBackListener { finish() } 36 | 37 | viewBinding.rv.adapter = mAnimationAdapter 38 | 39 | initMenu() 40 | } 41 | 42 | /** 43 | * Init menu 44 | * 初始化下拉菜单 45 | */ 46 | private fun initMenu() { 47 | viewBinding.spinner.setItems( 48 | "AlphaIn", 49 | "ScaleIn", 50 | "SlideInBottom", 51 | "SlideInLeft", 52 | "SlideInRight", 53 | "Custom1", 54 | "Custom2", 55 | "Custom3" 56 | ) 57 | viewBinding.spinner.setOnItemSelectedListener { _, position, _, _ -> 58 | when (position) { 59 | 0 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.AlphaIn) 60 | 1 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.ScaleIn) 61 | 2 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInBottom) 62 | 3 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInLeft) 63 | 4 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInRight) 64 | 5 -> mAnimationAdapter.itemAnimation = CustomAnimation1() 65 | 6 -> mAnimationAdapter.itemAnimation = CustomAnimation2() 66 | 7 -> mAnimationAdapter.itemAnimation = CustomAnimation3() 67 | else -> {} 68 | } 69 | mAnimationAdapter.notifyDataSetChanged() 70 | 71 | } 72 | 73 | //init firstOnly state 74 | viewBinding.switchButton.setOnCheckedChangeListener { _, isChecked -> 75 | mAnimationAdapter.isAnimationFirstOnly = isChecked 76 | mAnimationAdapter.notifyDataSetChanged() 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/adapter/AnimationAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.animation.adapter 2 | 3 | import android.content.Context 4 | import android.text.TextPaint 5 | import android.text.style.ClickableSpan 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.TextView 9 | import androidx.core.content.ContextCompat 10 | import androidx.core.text.buildSpannedString 11 | import androidx.core.text.inSpans 12 | import com.chad.baserecyclerviewadapterhelper.R 13 | import com.chad.baserecyclerviewadapterhelper.data.DataServer 14 | import com.chad.baserecyclerviewadapterhelper.entity.Status 15 | import com.chad.baserecyclerviewadapterhelper.utils.ClickableMovementMethod 16 | import com.chad.baserecyclerviewadapterhelper.utils.Tips 17 | import com.chad.library.adapter4.BaseQuickAdapter 18 | import com.chad.library.adapter4.viewholder.QuickViewHolder 19 | 20 | /** 21 | * 文 件 名: AnimationAdapter 22 | * 创 建 人: Allen 23 | * 创建日期: 16/12/24 15:33 24 | * 邮 箱: AllenCoder@126.com 25 | * 修改时间: 26 | * 修改备注: 27 | */ 28 | class AnimationAdapter : 29 | BaseQuickAdapter(DataServer.getSampleData(100)) { 30 | override fun onCreateViewHolder( 31 | context: Context, 32 | parent: ViewGroup, 33 | viewType: Int 34 | ): QuickViewHolder { 35 | return QuickViewHolder(R.layout.layout_animation, parent) 36 | } 37 | 38 | override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: Status?) { 39 | when (holder.layoutPosition % 3) { 40 | 0 -> holder.setImageResource(R.id.img, R.mipmap.animation_img1) 41 | 1 -> holder.setImageResource(R.id.img, R.mipmap.animation_img2) 42 | 2 -> holder.setImageResource(R.id.img, R.mipmap.animation_img3) 43 | else -> {} 44 | } 45 | holder.setText(R.id.tweetName, "Hoteis in Rio de Janeiro") 46 | val msg = 47 | "\"He was one of Australia's most of distinguished artistes, renowned for his portraits\"" 48 | 49 | 50 | 51 | holder.getView(R.id.tweetText).text = buildSpannedString { 52 | append(msg) 53 | inSpans(clickableSpan) { 54 | append("landscapes and nedes") 55 | } 56 | } 57 | holder.getView(R.id.tweetText).movementMethod = ClickableMovementMethod.getInstance() 58 | holder.getView(R.id.tweetText).isFocusable = false 59 | holder.getView(R.id.tweetText).isClickable = false 60 | holder.getView(R.id.tweetText).isLongClickable = false 61 | } 62 | 63 | private val clickableSpan: ClickableSpan = object : ClickableSpan() { 64 | override fun onClick(widget: View) { 65 | Tips.show("事件触发了 landscapes and nedes") 66 | } 67 | 68 | override fun updateDrawState(ds: TextPaint) { 69 | ds.color = ContextCompat.getColor(context, R.color.clickspan_color) 70 | ds.isUnderlineText = true 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/DataBindingUseActivity.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.databinding; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.recyclerview.widget.LinearLayoutManager; 7 | 8 | import com.chad.baserecyclerviewadapterhelper.activity.databinding.adapter.DataBindingAdapter; 9 | import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity; 10 | import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding; 11 | import com.chad.baserecyclerviewadapterhelper.entity.Movie; 12 | import com.chad.baserecyclerviewadapterhelper.utils.Tips; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.Random; 17 | 18 | /** 19 | * @author limuyang 20 | * @date 2019-12-05 21 | * @description 22 | */ 23 | public final class DataBindingUseActivity extends BaseViewBindingActivity { 24 | 25 | private final DataBindingAdapter adapter = new DataBindingAdapter(); 26 | 27 | @NonNull 28 | @Override 29 | public ActivityUniversalRecyclerBinding initBinding() { 30 | return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater()); 31 | } 32 | 33 | @Override 34 | protected void onCreate(Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | 37 | getViewBinding().titleBar.setTitle("DataBinding Use"); 38 | getViewBinding().titleBar.setOnBackListener(v -> finish()); 39 | 40 | 41 | getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this)); 42 | getViewBinding().rv.setAdapter(adapter); 43 | 44 | 45 | //item 点击事件 46 | adapter.setOnItemClickListener((movieBaseQuickAdapter, view, position) -> { 47 | Tips.show("onItemClick: " + position); 48 | }); 49 | 50 | //设置数据 51 | adapter.submitList(genData()); 52 | } 53 | 54 | private List genData() { 55 | ArrayList list = new ArrayList<>(); 56 | Random random = new Random(); 57 | for (int i = 0; i < 10; i++) { 58 | String name = "Chad " + i; 59 | int price = random.nextInt(10) + 10; 60 | int len = random.nextInt(80) + 60; 61 | Movie movie = new Movie(name, len, price, "He was one of Australia's most distinguished artistes"); 62 | list.add(movie); 63 | } 64 | return list; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/adapter/DataBindingAdapter.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.databinding.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.ViewGroup; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.annotation.Nullable; 8 | 9 | import com.chad.baserecyclerviewadapterhelper.R; 10 | import com.chad.baserecyclerviewadapterhelper.databinding.ItemMovieBinding; 11 | import com.chad.baserecyclerviewadapterhelper.entity.Movie; 12 | import com.chad.baserecyclerviewadapterhelper.entity.MoviePresenter; 13 | import com.chad.library.adapter4.BaseQuickAdapter; 14 | import com.chad.library.adapter4.viewholder.DataBindingHolder; 15 | 16 | /** 17 | * @author: limuyang 18 | * @date: 2019-12-05 19 | * @Description: DataBinding Adapter 20 | * 21 | */ 22 | public class DataBindingAdapter extends BaseQuickAdapter> { 23 | 24 | private final MoviePresenter mPresenter = new MoviePresenter(); 25 | 26 | @NonNull 27 | @Override 28 | protected DataBindingHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { 29 | return new DataBindingHolder<>(R.layout.item_movie, parent); 30 | } 31 | 32 | @Override 33 | protected void onBindViewHolder(@NonNull DataBindingHolder holder, int position, @Nullable Movie item) { 34 | if (item == null) return; 35 | 36 | // 获取 Binding 37 | ItemMovieBinding binding = holder.getBinding(); 38 | binding.setMovie(item); 39 | binding.setPresenter(mPresenter); 40 | binding.executePendingBindings(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffEntityCallback.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.recyclerview.widget.DiffUtil; 5 | 6 | import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity; 7 | 8 | /** 9 | * Create DiffCallback 10 | */ 11 | public class DiffEntityCallback extends DiffUtil.ItemCallback { 12 | 13 | /** 14 | * Determine if it is the same item 15 | *

16 | * 判断是否是同一个item 17 | * 18 | * @param oldItem New data 19 | * @param newItem old Data 20 | * @return 21 | */ 22 | @Override 23 | public boolean areItemsTheSame(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) { 24 | return oldItem.getId() == newItem.getId(); 25 | } 26 | 27 | /** 28 | * When it is the same item, judge whether the content has changed. 29 | *

30 | * 当是同一个item时,再判断内容是否发生改变 31 | * 32 | * @param oldItem New data 33 | * @param newItem old Data 34 | * @return 35 | */ 36 | @Override 37 | public boolean areContentsTheSame(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) { 38 | return oldItem.getTitle().equals(newItem.getTitle()) 39 | && oldItem.getContent().equals(newItem.getContent()) 40 | && oldItem.getDate().equals(newItem.getDate()); 41 | } 42 | 43 | /** 44 | * Optional implementation 45 | * Implement this method if you need to precisely modify the content of a view. 46 | * If this method is not implemented, or if null is returned, the entire item will be refreshed. 47 | * 48 | * 可选实现 49 | * 如果需要精确修改某一个view中的内容,请实现此方法。 50 | * 如果不实现此方法,或者返回null,将会直接刷新整个item。 51 | * 52 | * @param oldItem Old data 53 | * @param newItem New data 54 | * @return Payload info. if return null, the entire item will be refreshed. 55 | */ 56 | @Override 57 | public Object getChangePayload(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) { 58 | return null; 59 | } 60 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffUtilAdapter.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.ViewGroup; 5 | 6 | import androidx.annotation.NonNull; 7 | 8 | import com.chad.baserecyclerviewadapterhelper.R; 9 | import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity; 10 | import com.chad.library.adapter4.BaseDifferAdapter; 11 | import com.chad.library.adapter4.viewholder.QuickViewHolder; 12 | 13 | /** 14 | * Create adapter 15 | */ 16 | public class DiffUtilAdapter extends BaseDifferAdapter { 17 | 18 | public DiffUtilAdapter() { 19 | super(new DiffEntityCallback()); 20 | } 21 | 22 | 23 | @NonNull 24 | @Override 25 | protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { 26 | return new QuickViewHolder(R.layout.layout_animation, parent); 27 | } 28 | 29 | @Override 30 | protected void onBindViewHolder(@NonNull QuickViewHolder holder, int position, DiffEntity item) { 31 | holder.setText(R.id.tweetName, item.getTitle()) 32 | .setText(R.id.tweetText, item.getContent()) 33 | .setText(R.id.tweetDate, item.getDate()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeUseActivity.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.dragswipe; 2 | 3 | 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.recyclerview.widget.LinearLayoutManager; 9 | 10 | import com.chad.baserecyclerviewadapterhelper.R; 11 | import com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeAdapter; 12 | import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity; 13 | import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding; 14 | import com.chad.baserecyclerviewadapterhelper.entity.HomeEntity; 15 | 16 | import java.util.ArrayList; 17 | 18 | 19 | public class DragAndSwipeUseActivity extends BaseViewBindingActivity { 20 | private final ArrayList homeItemData = new ArrayList<>(); 21 | 22 | @NonNull 23 | @Override 24 | public ActivityUniversalRecyclerBinding initBinding() { 25 | return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater()); 26 | } 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | 32 | getViewBinding().titleBar.setTitle("Drag And Swipe"); 33 | getViewBinding().titleBar.setOnBackListener(v -> finish()); 34 | 35 | // 设置数据 36 | homeItemData.add(new HomeEntity("Default Drag And Swipe", DefaultDragAndSwipeActivity.class, R.mipmap.gv_drag_and_swipe, "")); 37 | homeItemData.add(new HomeEntity("Manual Drag And Swipe", ManualDragAndSwipeUseActivity.class, R.mipmap.gv_drag_and_swipe, "")); 38 | homeItemData.add(new HomeEntity("Head Drag And Swipe", HeaderDragAndSwipeActivity.class, R.mipmap.gv_drag_and_swipe, "")); 39 | homeItemData.add(new HomeEntity("Diff Drag And Swipe", DragAndSwipeDifferActivity.class, R.mipmap.gv_drag_and_swipe, "")); 40 | 41 | /* 42 | * RV适配器 43 | */ 44 | HomeAdapter mAdapter = new HomeAdapter(homeItemData); 45 | 46 | 47 | getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this)); 48 | getViewBinding().rv.setAdapter(mAdapter); 49 | 50 | mAdapter.setOnItemClickListener((adapter, view, position) -> { 51 | HomeEntity item = adapter.getItems().get(position); 52 | if (!item.isSection()) { 53 | startActivity(new Intent(DragAndSwipeUseActivity.this, item.getActivity())); 54 | } 55 | }); 56 | } 57 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipe.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.dragswipe 2 | 3 | import androidx.recyclerview.widget.ConcatAdapter 4 | import androidx.recyclerview.widget.RecyclerView 5 | import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.HeaderDragAndSwipeAdapter 6 | import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe 7 | 8 | /** 9 | * 重写拖拽类,根据itemType 设置某个类型的是否允许拖拽 10 | */ 11 | class HeaderDragAndSwipe : QuickDragAndSwipe() { 12 | 13 | override fun getMovementFlags( 14 | recyclerView: RecyclerView, 15 | viewHolder: RecyclerView.ViewHolder 16 | ): Int { 17 | if (recyclerView.adapter is ConcatAdapter) { 18 | val adapter = recyclerView.adapter as ConcatAdapter 19 | val absoluteAdapter = 20 | adapter.getWrappedAdapterAndPosition(viewHolder.absoluteAdapterPosition).first 21 | if (absoluteAdapter is HeaderDragAndSwipeAdapter) { 22 | return super.getMovementFlags(recyclerView, viewHolder) 23 | } 24 | return makeMovementFlags(0, 0) 25 | } 26 | return makeMovementFlags(0, 0) 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DiffDragAndSwipeAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter 2 | 3 | import android.content.Context 4 | import android.view.ViewGroup 5 | import com.chad.baserecyclerviewadapterhelper.R 6 | import com.chad.baserecyclerviewadapterhelper.activity.differ.adapter.DiffEntityCallback 7 | import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity 8 | import com.chad.library.adapter4.BaseDifferAdapter 9 | import com.chad.library.adapter4.viewholder.QuickViewHolder 10 | 11 | /** 12 | * Create adapter 13 | */ 14 | class DiffDragAndSwipeAdapter : 15 | BaseDifferAdapter(DiffEntityCallback()) { 16 | 17 | override fun onCreateViewHolder( 18 | context: Context, parent: ViewGroup, viewType: Int 19 | ): QuickViewHolder { 20 | return QuickViewHolder(R.layout.layout_animation, parent) 21 | } 22 | 23 | override fun onBindViewHolder( 24 | holder: QuickViewHolder, position: Int, item: DiffEntity? 25 | ) { 26 | if (item == null) return 27 | 28 | holder.setText(R.id.tweetName, item.title) 29 | .setText(R.id.tweetText, item.content) 30 | .setText(R.id.tweetDate, item.date) 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DragAndSwipeAdapter.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter; 2 | 3 | 4 | import android.content.Context; 5 | import android.view.ViewGroup; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | import com.chad.baserecyclerviewadapterhelper.R; 10 | import com.chad.library.adapter4.BaseQuickAdapter; 11 | import com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback; 12 | import com.chad.library.adapter4.viewholder.QuickViewHolder; 13 | 14 | public class DragAndSwipeAdapter extends BaseQuickAdapter implements DragAndSwipeDataCallback { 15 | 16 | @NonNull 17 | @Override 18 | protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { 19 | return new QuickViewHolder(R.layout.item_draggable_view, parent); 20 | } 21 | 22 | @Override 23 | protected void onBindViewHolder(@NonNull QuickViewHolder holder, int position, String item) { 24 | switch (holder.getLayoutPosition() % 3) { 25 | case 0 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img0); 26 | case 1 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img1); 27 | case 2 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img2); 28 | default -> { 29 | } 30 | } 31 | holder.setText(R.id.tv, item); 32 | } 33 | 34 | @Override 35 | public void dataMove(int fromPosition, int toPosition) { 36 | move(fromPosition, toPosition); 37 | } 38 | 39 | @Override 40 | public void dataRemoveAt(int position) { 41 | removeAt(position); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/HeaderDragAndSwipeAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter 2 | 3 | import android.content.Context 4 | import android.view.ViewGroup 5 | import com.chad.baserecyclerviewadapterhelper.R 6 | import com.chad.library.adapter4.BaseQuickAdapter 7 | import com.chad.library.adapter4.viewholder.QuickViewHolder 8 | import com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback 9 | 10 | /** 11 | * kotlin方式集成案例 12 | */ 13 | open class HeaderDragAndSwipeAdapter : BaseQuickAdapter(), 14 | DragAndSwipeDataCallback { 15 | 16 | override fun onCreateViewHolder( 17 | context: Context, 18 | parent: ViewGroup, 19 | viewType: Int 20 | ): QuickViewHolder { 21 | return QuickViewHolder(R.layout.item_draggable_view, parent) 22 | } 23 | 24 | override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: String?) { 25 | when (holder.layoutPosition % 3) { 26 | 0 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img0) 27 | 1 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img1) 28 | 2 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img2) 29 | else -> {} 30 | } 31 | holder.setText(R.id.tv, item) 32 | } 33 | 34 | override fun dataMove(fromPosition: Int, toPosition: Int) { 35 | move(fromPosition, toPosition) 36 | } 37 | 38 | override fun dataRemoveAt(position: Int) { 39 | removeAt(position) 40 | } 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/EmptyViewUseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.emptyview 2 | 3 | import android.os.Bundle 4 | import android.view.View 5 | import android.widget.FrameLayout 6 | import androidx.recyclerview.widget.StaggeredGridLayoutManager 7 | import com.chad.baserecyclerviewadapterhelper.R 8 | import com.chad.baserecyclerviewadapterhelper.activity.emptyview.adapter.EmptyViewAdapter 9 | import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity 10 | import com.chad.baserecyclerviewadapterhelper.data.DataServer 11 | import com.chad.baserecyclerviewadapterhelper.databinding.ActivityEmptyViewUseBinding 12 | 13 | class EmptyViewUseActivity : BaseViewBindingActivity() { 14 | 15 | private val mAdapter = EmptyViewAdapter() 16 | 17 | private var mError = true 18 | private var mNoData = true 19 | 20 | override fun initBinding(): ActivityEmptyViewUseBinding = 21 | ActivityEmptyViewUseBinding.inflate(layoutInflater) 22 | 23 | override fun onCreate(savedInstanceState: Bundle?) { 24 | super.onCreate(savedInstanceState) 25 | 26 | viewBinding.titleBar.title = "EmptyView Use" 27 | viewBinding.titleBar.setOnBackListener { finish() } 28 | 29 | viewBinding.btnReset.setOnClickListener { reset() } 30 | 31 | viewBinding.rvList.adapter = mAdapter 32 | viewBinding.rvList.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL) 33 | 34 | // 打开空布局功能 35 | mAdapter.isStateViewEnable = true 36 | mAdapter.isUseStateViewSize = true 37 | 38 | onRefresh() 39 | } 40 | 41 | private fun reset() { 42 | mError = true 43 | mNoData = true 44 | mAdapter.submitList(null) 45 | onRefresh() 46 | } 47 | 48 | private val emptyDataView: View 49 | get() { 50 | val notDataView = layoutInflater.inflate(R.layout.empty_view, FrameLayout(this), false) 51 | notDataView.setOnClickListener { onRefresh() } 52 | return notDataView 53 | } 54 | 55 | private val errorView: View 56 | get() { 57 | val errorView = layoutInflater.inflate(R.layout.error_view, FrameLayout(this), false) 58 | errorView.setOnClickListener { onRefresh() } 59 | return errorView 60 | } 61 | 62 | private fun onRefresh() { 63 | // 方式一:直接传入 layout id 64 | mAdapter.setStateViewLayout(this, R.layout.loading_view) 65 | 66 | viewBinding.rvList.postDelayed({ 67 | if (mError) { // 模拟网络错误 68 | // 方式二:传入View 69 | mAdapter.stateView = errorView 70 | 71 | mError = false 72 | } else { 73 | if (mNoData) { // 模拟接口没有数据 74 | mAdapter.stateView = emptyDataView 75 | mNoData = false 76 | } else { 77 | // 模拟正常数据返回 78 | mAdapter.submitList(DataServer.getSampleData(10)) 79 | } 80 | } 81 | }, 1000) 82 | } 83 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/adapter/EmptyViewAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.emptyview.adapter 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.view.ViewGroup 6 | import androidx.recyclerview.widget.RecyclerView 7 | import com.chad.baserecyclerviewadapterhelper.databinding.LayoutAnimationBinding 8 | import com.chad.baserecyclerviewadapterhelper.entity.Status 9 | import com.chad.library.adapter4.BaseQuickAdapter 10 | 11 | class EmptyViewAdapter : BaseQuickAdapter() { 12 | 13 | class VH( 14 | parent: ViewGroup, 15 | val binding: LayoutAnimationBinding = LayoutAnimationBinding.inflate( 16 | LayoutInflater.from(parent.context), parent, false 17 | ), 18 | ) : RecyclerView.ViewHolder(binding.root) 19 | 20 | override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { 21 | return VH(parent) 22 | } 23 | 24 | override fun onBindViewHolder(holder: VH, position: Int, item: Status?) { 25 | if (item == null) return 26 | holder.binding.img.setImageResource(item.userAvatar) 27 | holder.binding.tweetName.text = item.userName 28 | holder.binding.tweetText.text = "O ever youthful,O ever weeping" 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/HeaderAndFooterUseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.headerfooter 2 | 3 | import android.os.Bundle 4 | import androidx.recyclerview.widget.LinearLayoutManager 5 | import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.FooterAdapter 6 | import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter 7 | import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAndFooterAdapter 8 | import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity 9 | import com.chad.baserecyclerviewadapterhelper.data.DataServer 10 | import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding 11 | import com.chad.baserecyclerviewadapterhelper.utils.Tips 12 | import com.chad.library.adapter4.QuickAdapterHelper 13 | 14 | /** 15 | * https://github.com/CymChad/BaseRecyclerViewAdapterHelper 16 | */ 17 | class HeaderAndFooterUseActivity : BaseViewBindingActivity() { 18 | 19 | private lateinit var helper: QuickAdapterHelper 20 | 21 | override fun initBinding(): ActivityUniversalRecyclerBinding = 22 | ActivityUniversalRecyclerBinding.inflate(layoutInflater) 23 | 24 | override fun onCreate(savedInstanceState: Bundle?) { 25 | super.onCreate(savedInstanceState) 26 | 27 | viewBinding.titleBar.title = "Header And Footer Use" 28 | viewBinding.titleBar.setOnBackListener { finish() } 29 | 30 | 31 | val adapter = HeaderAndFooterAdapter(DataServer.getSampleData(PAGE_SIZE)) 32 | adapter.setOnItemClickListener { _, _, position -> 33 | Tips.show("position: $position") 34 | } 35 | 36 | 37 | helper = QuickAdapterHelper.Builder(adapter) 38 | .build() 39 | 40 | viewBinding.rv.layoutManager = LinearLayoutManager(this) 41 | viewBinding.rv.adapter = helper.adapter 42 | addHeader() 43 | 44 | helper.addAfterAdapter( 45 | FooterAdapter(false).setOnItemClickListener { _, _, _ -> 46 | addFooter() 47 | } 48 | ) 49 | } 50 | 51 | private fun addHeader() { 52 | helper.addBeforeAdapter(0, HeaderAdapter().apply { 53 | setOnItemClickListener { _, _, _ -> 54 | addHeader() 55 | } 56 | }) 57 | } 58 | 59 | private fun addFooter() { 60 | helper.addAfterAdapter(FooterAdapter(true).setOnItemClickListener{ adapter, _, _ -> 61 | helper.removeAdapter(adapter) 62 | }) 63 | } 64 | 65 | companion object { 66 | private const val PAGE_SIZE = 3 67 | } 68 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/FooterAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter 2 | 3 | import android.content.Context 4 | import android.view.ViewGroup 5 | import com.chad.baserecyclerviewadapterhelper.R 6 | import com.chad.library.adapter4.BaseSingleItemAdapter 7 | import com.chad.library.adapter4.viewholder.QuickViewHolder 8 | 9 | class FooterAdapter( 10 | private val isDelete: Boolean 11 | ) : BaseSingleItemAdapter() { 12 | 13 | override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): QuickViewHolder { 14 | return QuickViewHolder(R.layout.footer_view, parent) 15 | } 16 | 17 | override fun onBindViewHolder(holder: QuickViewHolder, item: Any?) { 18 | if (isDelete) { 19 | holder.setImageResource(R.id.iv, R.mipmap.rm_icon) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.recyclerview.widget.RecyclerView 8 | import com.chad.baserecyclerviewadapterhelper.R 9 | import com.chad.library.adapter4.BaseSingleItemAdapter 10 | 11 | class HeaderAdapter: BaseSingleItemAdapter() { 12 | 13 | class VH(view: View): RecyclerView.ViewHolder(view) 14 | 15 | override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { 16 | val view = LayoutInflater.from(parent.context).inflate(R.layout.head_view, parent, false) 17 | return VH(view) 18 | } 19 | 20 | override fun onBindViewHolder(holder: VH, item: Any?) { 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAndFooterAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.view.ViewGroup 6 | import androidx.recyclerview.widget.RecyclerView 7 | import com.chad.baserecyclerviewadapterhelper.R 8 | import com.chad.baserecyclerviewadapterhelper.databinding.ItemHeaderAndFooterBinding 9 | import com.chad.baserecyclerviewadapterhelper.entity.Status 10 | import com.chad.library.adapter4.BaseQuickAdapter 11 | 12 | /** 13 | * https://github.com/CymChad/BaseRecyclerViewAdapterHelper 14 | */ 15 | class HeaderAndFooterAdapter(list: List) : 16 | BaseQuickAdapter(list) { 17 | 18 | class VH(var binding: ItemHeaderAndFooterBinding) : RecyclerView.ViewHolder(binding.root) 19 | 20 | override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { 21 | val binding = 22 | ItemHeaderAndFooterBinding.inflate(LayoutInflater.from(context), parent, false) 23 | return VH(binding) 24 | } 25 | 26 | override fun onBindViewHolder(holder: VH, position: Int, item: Status?) { 27 | when (holder.layoutPosition % 3) { 28 | 0 -> holder.binding.iv.setImageResource(R.mipmap.animation_img1) 29 | 1 -> holder.binding.iv.setImageResource(R.mipmap.animation_img2) 30 | 2 -> holder.binding.iv.setImageResource(R.mipmap.animation_img3) 31 | else -> {} 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.home.adapter 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.recyclerview.widget.RecyclerView 8 | import com.chad.baserecyclerviewadapterhelper.databinding.DefSectionHeadBinding 9 | import com.chad.baserecyclerviewadapterhelper.databinding.HomeItemViewBinding 10 | import com.chad.baserecyclerviewadapterhelper.entity.HomeEntity 11 | import com.chad.library.adapter4.BaseMultiItemAdapter 12 | 13 | /** 14 | * https://github.com/CymChad/BaseRecyclerViewAdapterHelper 15 | */ 16 | class HomeAdapter(data: List) : BaseMultiItemAdapter(data) { 17 | 18 | class ItemVH(val viewBinding: HomeItemViewBinding) : RecyclerView.ViewHolder(viewBinding.root) 19 | 20 | class HeaderVH(val viewBinding: DefSectionHeadBinding) : RecyclerView.ViewHolder(viewBinding.root) 21 | 22 | init { 23 | addItemType(ITEM_TYPE, object : OnMultiItemAdapterListener { 24 | override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH { 25 | val viewBinding = 26 | HomeItemViewBinding.inflate(LayoutInflater.from(context), parent, false) 27 | return ItemVH(viewBinding) 28 | } 29 | 30 | override fun onBind(holder: ItemVH, position: Int, item: HomeEntity?) { 31 | if (item == null) return 32 | holder.viewBinding.textView.text = item.name 33 | holder.viewBinding.icon.setImageResource(item.imageResource) 34 | } 35 | }).addItemType(SECTION_TYPE, object : OnMultiItemAdapterListener { 36 | override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): HeaderVH { 37 | val viewBinding = 38 | DefSectionHeadBinding.inflate(LayoutInflater.from(context), parent, false) 39 | return HeaderVH(viewBinding) 40 | } 41 | 42 | override fun onBind(holder: HeaderVH, position: Int, item: HomeEntity?) { 43 | if (item == null) return 44 | 45 | holder.viewBinding.more.visibility = View.GONE 46 | holder.viewBinding.header.text = item.sectionTitle 47 | } 48 | 49 | override fun isFullSpanItem(itemType: Int): Boolean { 50 | return true 51 | } 52 | 53 | }).onItemViewType { position, list -> 54 | if (list[position].isSection) { 55 | SECTION_TYPE 56 | } else { 57 | ITEM_TYPE 58 | } 59 | } 60 | } 61 | 62 | companion object { 63 | private const val ITEM_TYPE = 10 64 | private const val SECTION_TYPE = 11 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeTopHeaderAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.home.adapter 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.recyclerview.widget.RecyclerView 8 | import com.chad.baserecyclerviewadapterhelper.R 9 | import com.chad.library.adapter4.BaseSingleItemAdapter 10 | import com.chad.library.adapter4.fullspan.FullSpanAdapterType 11 | 12 | class HomeTopHeaderAdapter : BaseSingleItemAdapter(), 13 | FullSpanAdapterType { 14 | 15 | companion object { 16 | val HEAD_VIEWTYPE = 0x10000556 17 | } 18 | 19 | class VH(view: View) : RecyclerView.ViewHolder(view) 20 | 21 | override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { 22 | return VH(LayoutInflater.from(parent.context).inflate(R.layout.top_view, parent, false)) 23 | } 24 | 25 | override fun onBindViewHolder(holder: VH, item: Any?) { 26 | } 27 | 28 | override fun getItemViewType(position: Int, list: List): Int { 29 | return HEAD_VIEWTYPE 30 | } 31 | 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/CustomLoadMoreAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import androidx.recyclerview.widget.RecyclerView 7 | import com.chad.baserecyclerviewadapterhelper.databinding.ViewLoadMoreBinding 8 | import com.chad.library.adapter4.loadState.LoadState 9 | import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter 10 | 11 | /** 12 | * 自定义的"加载更多"。 13 | * 这里可以做很多事情,这里仅展示了更改自定义布局的使用。 14 | * 15 | * There are many things that can be done here, only the use of changing custom layouts is shown here. 16 | */ 17 | class CustomLoadMoreAdapter : TrailingLoadStateAdapter() { 18 | 19 | override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): CustomVH { 20 | val viewBinding = ViewLoadMoreBinding.inflate(LayoutInflater.from(parent.context), parent, false) 21 | return CustomVH(viewBinding).apply { 22 | viewBinding.loadMoreLoadFailView.setOnClickListener { 23 | // 失败重试点击事件 24 | invokeFailRetry() 25 | } 26 | viewBinding.loadMoreLoadCompleteView.setOnClickListener { 27 | // 加载更多,手动点击事件 28 | invokeLoadMore() 29 | } 30 | } 31 | } 32 | 33 | override fun onBindViewHolder(holder: CustomVH, loadState: LoadState) { 34 | when (loadState) { 35 | is LoadState.NotLoading -> { 36 | if (loadState.endOfPaginationReached) { 37 | holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE 38 | holder.viewBinding.loadMoreLoadingView.visibility = View.GONE 39 | holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE 40 | holder.viewBinding.loadMoreLoadEndView.visibility = View.VISIBLE 41 | } else { 42 | holder.viewBinding.loadMoreLoadCompleteView.visibility = View.VISIBLE 43 | holder.viewBinding.loadMoreLoadingView.visibility = View.GONE 44 | holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE 45 | holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE 46 | } 47 | } 48 | is LoadState.Loading -> { 49 | holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE 50 | holder.viewBinding.loadMoreLoadingView.visibility = View.VISIBLE 51 | holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE 52 | holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE 53 | } 54 | is LoadState.Error -> { 55 | holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE 56 | holder.viewBinding.loadMoreLoadingView.visibility = View.GONE 57 | holder.viewBinding.loadMoreLoadFailView.visibility = View.VISIBLE 58 | holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE 59 | } 60 | is LoadState.None -> { 61 | holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE 62 | holder.viewBinding.loadMoreLoadingView.visibility = View.GONE 63 | holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE 64 | holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE 65 | } 66 | } 67 | } 68 | 69 | 70 | class CustomVH(val viewBinding: ViewLoadMoreBinding) : RecyclerView.ViewHolder(viewBinding.root) 71 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/RecyclerViewAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter 2 | 3 | import android.content.Context 4 | import android.text.TextPaint 5 | import android.text.method.LinkMovementMethod 6 | import android.text.style.ClickableSpan 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import androidx.core.content.ContextCompat 11 | import androidx.core.text.buildSpannedString 12 | import androidx.core.text.inSpans 13 | import androidx.recyclerview.widget.RecyclerView 14 | import com.chad.baserecyclerviewadapterhelper.R 15 | import com.chad.baserecyclerviewadapterhelper.databinding.LayoutAnimationBinding 16 | import com.chad.baserecyclerviewadapterhelper.entity.Status 17 | import com.chad.baserecyclerviewadapterhelper.utils.Tips 18 | import com.chad.library.adapter4.BaseQuickAdapter 19 | 20 | /** 21 | * @author: limuyang 22 | * @date: 2019-12-04 23 | * @Description: 24 | */ 25 | class RecyclerViewAdapter : BaseQuickAdapter() { 26 | class VH( 27 | parent: ViewGroup, 28 | val viewBinding: LayoutAnimationBinding = LayoutAnimationBinding.inflate( 29 | LayoutInflater.from(parent.context), parent, false 30 | ) 31 | ) : RecyclerView.ViewHolder(viewBinding.root) 32 | 33 | override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { 34 | return VH(parent) 35 | } 36 | 37 | protected override fun onBindViewHolder(holder: VH, position: Int, item: Status?) { 38 | when (holder.layoutPosition % 3) { 39 | 0 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img1) 40 | 1 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img2) 41 | 2 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img3) 42 | else -> {} 43 | } 44 | holder.viewBinding.tweetName.text = 45 | "Hoteis in Rio de Janeiro " + position + " " + item!!.userName 46 | val msg = 47 | "\"He was one of Australia's most of distinguished artistes, renowned for his portraits\"" 48 | holder.viewBinding.tweetText.text = buildSpannedString { 49 | append(msg) 50 | inSpans(clickableSpan) { 51 | append("landscapes and nedes") 52 | } 53 | } 54 | holder.viewBinding.tweetText.movementMethod = LinkMovementMethod.getInstance() 55 | } 56 | 57 | private val clickableSpan: ClickableSpan = object : ClickableSpan() { 58 | override fun onClick(widget: View) { 59 | Tips.show("事件触发了 landscapes and nedes") 60 | } 61 | 62 | override fun updateDrawState(ds: TextPaint) { 63 | ds.color = ContextCompat.getColor(context, R.color.clickspan_color) 64 | ds.isUnderlineText = true 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/adapter/GroupAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.scene.adapter 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.view.ViewGroup 6 | import android.view.ViewGroup.MarginLayoutParams 7 | import androidx.core.view.isVisible 8 | import androidx.core.view.updateLayoutParams 9 | import androidx.recyclerview.widget.RecyclerView 10 | import com.chad.baserecyclerviewadapterhelper.R 11 | import com.chad.baserecyclerviewadapterhelper.databinding.ItemGroupTypeBinding 12 | import com.chad.baserecyclerviewadapterhelper.entity.GroupDemoEntity 13 | import com.chad.baserecyclerviewadapterhelper.utils.dp 14 | import com.chad.library.adapter4.BaseQuickAdapter 15 | 16 | /** 17 | * 每一组的Adapter 18 | * 19 | */ 20 | class GroupAdapter : BaseQuickAdapter(){ 21 | 22 | class VH( 23 | parent: ViewGroup, 24 | val binding: ItemGroupTypeBinding = ItemGroupTypeBinding.inflate(LayoutInflater.from(parent.context), parent ,false) 25 | ):RecyclerView.ViewHolder(binding.root) 26 | 27 | override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { 28 | return VH(parent) 29 | } 30 | 31 | override fun onBindViewHolder(holder: VH, position: Int, item: GroupDemoEntity.Group?) { 32 | if (item == null) return 33 | 34 | holder.binding.tvTitle.text = item.title 35 | holder.binding.tvContent.text = item.content 36 | 37 | holder.binding.lineView.isVisible = position > 0 38 | 39 | when (position) { 40 | 0 -> { 41 | // 第一个item,设置上圆角背景 42 | holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_top_bg) 43 | 44 | // 设置点间距 45 | holder.binding.root.updateLayoutParams { 46 | topMargin = 15.dp 47 | } 48 | } 49 | items.size - 1 -> { 50 | // 最后一个item,设置下圆角背景 51 | holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_bottom_bg) 52 | } 53 | else -> { 54 | // 其他的,没有圆角的背景 55 | holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_mid_bg) 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/adapter/UpFetchAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.activity.upfetch.adapter 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.view.ViewGroup 6 | import androidx.recyclerview.widget.RecyclerView 7 | import com.chad.baserecyclerviewadapterhelper.R 8 | import com.chad.baserecyclerviewadapterhelper.databinding.ItemHeaderAndFooterBinding 9 | import com.chad.baserecyclerviewadapterhelper.entity.Movie 10 | import com.chad.library.adapter4.BaseQuickAdapter 11 | 12 | /** 13 | * @author: limuyang 14 | * @date: 2019-12-06 15 | * @Description: 16 | */ 17 | class UpFetchAdapter : BaseQuickAdapter() { 18 | class VH( 19 | parent: ViewGroup, 20 | val viewBinding: ItemHeaderAndFooterBinding = ItemHeaderAndFooterBinding.inflate( 21 | LayoutInflater.from(parent.context), parent, false 22 | ) 23 | ) : RecyclerView.ViewHolder(viewBinding.root) 24 | 25 | override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { 26 | return VH(parent) 27 | } 28 | 29 | override fun onBindViewHolder(holder: VH, position: Int, item: Movie?) { 30 | when (holder.layoutPosition % 3) { 31 | 0 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img1) 32 | 1 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img2) 33 | 2 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img3) 34 | else -> {} 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation1.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.animator; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorSet; 5 | import android.animation.ObjectAnimator; 6 | import android.view.View; 7 | import android.view.animation.DecelerateInterpolator; 8 | import com.chad.library.adapter4.animation.ItemAnimator; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | /** 12 | * 自定义动画1 13 | */ 14 | public class CustomAnimation1 implements ItemAnimator { 15 | @NotNull 16 | @Override 17 | public Animator animator(@NotNull View view) { 18 | Animator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1f); 19 | 20 | Animator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1.3f, 1); 21 | Animator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1.3f, 1); 22 | 23 | scaleY.setInterpolator(new DecelerateInterpolator()); 24 | scaleX.setInterpolator(new DecelerateInterpolator()); 25 | 26 | AnimatorSet animatorSet = new AnimatorSet(); 27 | animatorSet.setDuration(350); 28 | animatorSet.play(alpha).with(scaleX).with(scaleY); 29 | 30 | return animatorSet; 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation2.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.animator; 2 | 3 | import android.animation.Animator; 4 | import android.animation.ObjectAnimator; 5 | import android.view.View; 6 | import android.view.animation.Interpolator; 7 | 8 | import com.chad.library.adapter4.animation.ItemAnimator; 9 | 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | import static java.lang.Math.PI; 13 | import static java.lang.Math.pow; 14 | import static java.lang.Math.sin; 15 | 16 | 17 | /** 18 | * 自定义动画2 19 | */ 20 | public class CustomAnimation2 implements ItemAnimator { 21 | @NotNull 22 | @Override 23 | public Animator animator(@NotNull View view) { 24 | Animator translationX = 25 | ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0f); 26 | 27 | translationX.setDuration(800); 28 | translationX.setInterpolator(new MyInterpolator2()); 29 | 30 | return translationX; 31 | } 32 | 33 | private static class MyInterpolator2 implements Interpolator { 34 | @Override 35 | public float getInterpolation(float input) { 36 | float factor = 0.7f; 37 | return (float) (pow(2.0, -10.0 * input) * sin((input - factor / 4) * (2 * PI) / factor) + 1); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation3.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.animator; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorSet; 5 | import android.animation.ObjectAnimator; 6 | import android.view.View; 7 | import android.view.animation.DecelerateInterpolator; 8 | 9 | import com.chad.library.adapter4.animation.ItemAnimator; 10 | 11 | import org.jetbrains.annotations.NotNull; 12 | 13 | public class CustomAnimation3 implements ItemAnimator { 14 | 15 | @NotNull 16 | @Override 17 | public Animator animator(@NotNull View view) { 18 | Animator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1f); 19 | 20 | Animator translationY = 21 | ObjectAnimator.ofFloat(view, "translationY", view.getRootView().getHeight(), 0f); 22 | translationY.setInterpolator(new DecelerateInterpolator(1.2f)); 23 | 24 | AnimatorSet animatorSet = new AnimatorSet(); 25 | animatorSet.setDuration(450); 26 | animatorSet.play(alpha).with(translationY); 27 | 28 | return animatorSet; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.base 2 | 3 | import android.os.Build 4 | import android.os.Bundle 5 | import android.view.View 6 | import androidx.annotation.LayoutRes 7 | import androidx.appcompat.app.AppCompatActivity 8 | import androidx.core.content.ContextCompat 9 | import com.chad.baserecyclerviewadapterhelper.R 10 | import com.chad.baserecyclerviewadapterhelper.utils.statusBarLightMode 11 | 12 | abstract class BaseActivity2(@LayoutRes layoutRes: Int = 0) : AppCompatActivity(layoutRes) { 13 | 14 | 15 | protected open val contentView: View? = null 16 | 17 | override fun onCreate(savedInstanceState: Bundle?) { 18 | super.onCreate(savedInstanceState) 19 | 20 | contentView?.let { 21 | setContentView(it) 22 | } 23 | 24 | if (Build.VERSION.SDK_INT >= 21) { 25 | window.statusBarColor = ContextCompat.getColor(this, R.color.spinner_bg) 26 | window.statusBarLightMode = false 27 | } 28 | 29 | 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseViewBindingActivity.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.base 2 | 3 | import android.view.View 4 | import androidx.viewbinding.ViewBinding 5 | 6 | abstract class BaseViewBindingActivity : BaseActivity2() { 7 | 8 | private var _viewBinding: V? = null 9 | 10 | protected val viewBinding: V 11 | get() { 12 | return _viewBinding ?: throw IllegalStateException( 13 | "Should be called initBinding()" 14 | ) 15 | } 16 | 17 | /** 18 | * 初始化 [viewBinding] 19 | */ 20 | abstract fun initBinding(): V 21 | 22 | final override val contentView: View 23 | get() { 24 | return initBinding().apply { 25 | _viewBinding = this 26 | }.root 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.data 2 | 3 | import com.chad.baserecyclerviewadapterhelper.R 4 | import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity 5 | import com.chad.baserecyclerviewadapterhelper.entity.Status 6 | 7 | /** 8 | * https://github.com/CymChad/BaseRecyclerViewAdapterHelper 9 | */ 10 | object DataServer { 11 | const val HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK = 12 | "https://avatars1.githubusercontent.com/u/7698209?v=3&s=460" 13 | const val CYM_CHAD = "CymChad" 14 | const val CHAY_CHAN = "ChayChan" 15 | fun getSampleData(lenth: Int): MutableList { 16 | val list: MutableList = ArrayList() 17 | for (i in 0 until lenth) { 18 | val status = Status() 19 | status.userName = "Chad$i" 20 | status.createdAt = "04/05/$i" 21 | status.isRetweet = i % 2 == 0 22 | 23 | 24 | status.userAvatar = when (i % 3) { 25 | 0 -> R.mipmap.animation_img1 26 | 1 -> R.mipmap.animation_img2 27 | else -> R.mipmap.animation_img3 28 | } 29 | status.text = "BaseRecyclerViewAdpaterHelper https://www.recyclerview.org" 30 | list.add(status) 31 | } 32 | return list 33 | } 34 | 35 | 36 | 37 | val strData: List 38 | get() { 39 | val list: MutableList = ArrayList() 40 | for (i in 0..19) { 41 | var str = HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK 42 | if (i % 2 == 0) { 43 | str = CYM_CHAD 44 | } 45 | list.add(str) 46 | } 47 | return list 48 | } 49 | @JvmStatic 50 | val diffUtilDemoEntities: List 51 | get() { 52 | val list: MutableList = ArrayList() 53 | for (i in 0..9) { 54 | list.add( 55 | DiffEntity( 56 | i, 57 | "Item $i", 58 | "This item $i content", 59 | "06-12" 60 | ) 61 | ) 62 | } 63 | return list 64 | } 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridItemDecoration.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.decoration; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Rect; 6 | import android.graphics.drawable.Drawable; 7 | import android.view.View; 8 | 9 | import androidx.recyclerview.widget.LinearLayoutManager; 10 | import androidx.recyclerview.widget.RecyclerView; 11 | 12 | /** 13 | * https://github.com/CymChad/BaseRecyclerViewAdapterHelper 14 | */ 15 | public class GridItemDecoration extends RecyclerView.ItemDecoration { 16 | 17 | private Drawable dividerDrawable; 18 | private int orientation = LinearLayoutManager.VERTICAL; 19 | 20 | public GridItemDecoration(Drawable divider) { 21 | dividerDrawable = divider; 22 | } 23 | 24 | public GridItemDecoration(Context context, int resId) { 25 | dividerDrawable = context.getResources().getDrawable(resId); 26 | } 27 | 28 | public GridItemDecoration(Context context, int resId, int orientation) { 29 | dividerDrawable = context.getResources().getDrawable(resId); 30 | this.orientation = orientation; 31 | } 32 | 33 | @Override 34 | public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 35 | if (dividerDrawable == null) { 36 | return; 37 | } 38 | 39 | if (parent.getChildLayoutPosition(view) < 1) { 40 | return; 41 | } 42 | 43 | if (orientation == LinearLayoutManager.VERTICAL) { 44 | outRect.top = dividerDrawable.getIntrinsicHeight(); 45 | } else if (orientation == LinearLayoutManager.HORIZONTAL) { 46 | outRect.left = dividerDrawable.getIntrinsicWidth(); 47 | } 48 | } 49 | 50 | /** 51 | * @param c 52 | * @param parent 53 | * @param state 54 | */ 55 | @Override 56 | public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { 57 | if (dividerDrawable == null) { 58 | return; 59 | } 60 | 61 | int childCount = parent.getChildCount(); 62 | int rightV = parent.getWidth(); 63 | for (int i = 0; i < childCount; i++) { 64 | View child = parent.getChildAt(i); 65 | RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); 66 | 67 | int leftV = parent.getPaddingLeft() + child.getPaddingLeft(); 68 | int bottomV = child.getTop() - params.topMargin; 69 | int topV = bottomV - dividerDrawable.getIntrinsicHeight(); 70 | 71 | int topH = child.getTop() + params.topMargin; 72 | int bottomH = child.getBottom() + params.bottomMargin; 73 | int rightH = child.getLeft() - params.leftMargin; 74 | int leftH = rightH - dividerDrawable.getIntrinsicWidth(); 75 | dividerDrawable.setBounds(leftH, topH, rightH, bottomH); 76 | dividerDrawable.draw(c); 77 | dividerDrawable.setBounds(leftV, topV, rightV, bottomV); 78 | dividerDrawable.draw(c); 79 | } 80 | } 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/ClickEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | ******************************* Copyright (c)*********************************\ 3 | ** 4 | ** (c) Copyright 2015, Allen, china, shanghai 5 | ** All Rights Reserved 6 | ** 7 | ** 8 | ** 9 | **-----------------------------------版本信息------------------------------------ 10 | ** 版 本: V0.1 11 | ** 12 | **------------------------------------------------------------------------------ 13 | ********************************End of Head************************************\ 14 | */ 15 | package com.chad.baserecyclerviewadapterhelper.entity; 16 | 17 | /** 18 | * 文 件 名: ClickEntity 19 | * 创 建 人: Allen 20 | * 创建日期: 16/11/1 22:16 21 | * 邮 箱: AllenCoder@126.com 22 | * 修改时间: 23 | * 修改备注: 24 | */ 25 | public class ClickEntity { 26 | public static final int CLICK_ITEM_VIEW = 1; 27 | public static final int CLICK_ITEM_CHILD_VIEW = 2; 28 | public static final int LONG_CLICK_ITEM_VIEW = 3; 29 | public static final int LONG_CLICK_ITEM_CHILD_VIEW = 4; 30 | private final int type; 31 | 32 | public ClickEntity(final int type) { 33 | this.type = type; 34 | } 35 | 36 | public int getItemType() { 37 | return type; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/DiffEntity.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.entity; 2 | 3 | import java.util.Objects; 4 | 5 | public class DiffEntity { 6 | 7 | private int id; 8 | private String title; 9 | private String content; 10 | private String date; 11 | 12 | public DiffEntity(int id, String title, String content, String date) { 13 | this.id = id; 14 | this.title = title; 15 | this.content = content; 16 | this.date = date; 17 | } 18 | 19 | public int getId() { 20 | return id; 21 | } 22 | 23 | public void setId(int id) { 24 | this.id = id; 25 | } 26 | 27 | public String getTitle() { 28 | return title; 29 | } 30 | 31 | public void setTitle(String title) { 32 | this.title = title; 33 | } 34 | 35 | public String getContent() { 36 | return content; 37 | } 38 | 39 | public void setContent(String content) { 40 | this.content = content; 41 | } 42 | 43 | public String getDate() { 44 | return date; 45 | } 46 | 47 | public void setDate(String date) { 48 | this.date = date; 49 | } 50 | 51 | @Override 52 | public boolean equals(Object o) { 53 | if (this == o) return true; 54 | if (!(o instanceof DiffEntity)) return false; 55 | DiffEntity that = (DiffEntity) o; 56 | return id == that.id && Objects.equals(title, that.title) && Objects.equals(content, that.content) && Objects.equals(date, that.date); 57 | } 58 | 59 | @Override 60 | public int hashCode() { 61 | return Objects.hash(id, title, content, date); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/GroupDemoEntity.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.entity 2 | 3 | import com.squareup.moshi.Json 4 | import com.squareup.moshi.JsonClass 5 | 6 | @JsonClass(generateAdapter = true) 7 | data class GroupDemoEntity( 8 | @Json(name = "group_name") 9 | val groupName: String, 10 | @Json(name = "group_list") 11 | val groupList: List, 12 | ) { 13 | 14 | @JsonClass(generateAdapter = true) 15 | data class Group( 16 | @Json(name = "title") 17 | val title: String, 18 | @Json(name = "content") 19 | val content: String, 20 | ) 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeEntity.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.entity 2 | 3 | /** 4 | * @author: limuyang 5 | * @date: 2019-12-06 6 | * @Description: 7 | */ 8 | data class HomeEntity( 9 | val name: String = "", 10 | val activity: Class<*>? = null, 11 | val imageResource: Int = 0, 12 | val sectionTitle: String = "" 13 | ) { 14 | val isSection: Boolean 15 | get() = sectionTitle.isNotBlank() 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Movie.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.entity; 2 | 3 | /** 4 | * Created by luoxiongwen on 16/10/24. 5 | */ 6 | 7 | public class Movie { 8 | 9 | public String name; 10 | public int length; 11 | public int price; 12 | public String content; 13 | 14 | public Movie(String name, int length, int price, String content) { 15 | this.length = length; 16 | this.name = name; 17 | this.price = price; 18 | this.content=content; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MoviePresenter.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.entity; 2 | 3 | import android.view.View; 4 | 5 | import com.chad.baserecyclerviewadapterhelper.utils.Tips; 6 | 7 | /** 8 | * Created by luoxiongwen on 16/10/24. 9 | */ 10 | 11 | public class MoviePresenter { 12 | public void buyTicket(View view, Movie movie) { 13 | Tips.show("buy ticket: " + movie.name); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Status.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.entity; 2 | 3 | /** 4 | * https://github.com/CymChad/BaseRecyclerViewAdapterHelper 5 | */ 6 | public class Status { 7 | private boolean isRetweet; 8 | private String text; 9 | private String userName; 10 | private int userAvatar; 11 | private String createdAt; 12 | 13 | public boolean isRetweet() { 14 | return isRetweet; 15 | } 16 | 17 | public void setRetweet(boolean retweet) { 18 | isRetweet = retweet; 19 | } 20 | 21 | public String getText() { 22 | return text; 23 | } 24 | 25 | public void setText(String text) { 26 | this.text = text; 27 | } 28 | 29 | public String getUserName() { 30 | return userName; 31 | } 32 | 33 | public void setUserName(String userName) { 34 | this.userName = userName; 35 | } 36 | 37 | public int getUserAvatar() { 38 | return userAvatar; 39 | } 40 | 41 | public void setUserAvatar(int userAvatar) { 42 | this.userAvatar = userAvatar; 43 | } 44 | 45 | public String getCreatedAt() { 46 | return createdAt; 47 | } 48 | 49 | public void setCreatedAt(String createdAt) { 50 | this.createdAt = createdAt; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return "Status{" + 56 | "isRetweet=" + isRetweet + 57 | ", text='" + text + '\'' + 58 | ", userName='" + userName + '\'' + 59 | ", userAvatar='" + userAvatar + '\'' + 60 | ", createdAt='" + createdAt + '\'' + 61 | '}'; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/AppUtils.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.utils 2 | 3 | import android.app.Application 4 | 5 | object AppUtils { 6 | private lateinit var mApplication: Application 7 | 8 | val app: Application get() = mApplication 9 | 10 | fun init(application: Application) { 11 | mApplication = application 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/ClickableMovementMethod.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.utils; 2 | 3 | import android.text.Layout; 4 | import android.text.Selection; 5 | import android.text.Spannable; 6 | import android.text.method.BaseMovementMethod; 7 | import android.text.style.ClickableSpan; 8 | import android.view.MotionEvent; 9 | import android.widget.TextView; 10 | 11 | public class ClickableMovementMethod extends BaseMovementMethod { 12 | 13 | private static ClickableMovementMethod sInstance; 14 | 15 | public static ClickableMovementMethod getInstance() { 16 | if (sInstance == null) { 17 | sInstance = new ClickableMovementMethod(); 18 | } 19 | return sInstance; 20 | } 21 | 22 | @Override 23 | public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { 24 | 25 | int action = event.getActionMasked(); 26 | if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { 27 | 28 | int x = (int) event.getX(); 29 | int y = (int) event.getY(); 30 | x -= widget.getTotalPaddingLeft(); 31 | y -= widget.getTotalPaddingTop(); 32 | x += widget.getScrollX(); 33 | y += widget.getScrollY(); 34 | 35 | Layout layout = widget.getLayout(); 36 | int line = layout.getLineForVertical(y); 37 | int off = layout.getOffsetForHorizontal(line, x); 38 | 39 | ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); 40 | if (link.length > 0) { 41 | if (action == MotionEvent.ACTION_UP) { 42 | link[0].onClick(widget); 43 | } else { 44 | Selection.setSelection(buffer, buffer.getSpanStart(link[0]), 45 | buffer.getSpanEnd(link[0])); 46 | } 47 | return true; 48 | } else { 49 | Selection.removeSelection(buffer); 50 | } 51 | } 52 | 53 | return false; 54 | } 55 | 56 | @Override 57 | public void initialize(TextView widget, Spannable text) { 58 | Selection.removeSelection(text); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/Ext.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.utils 2 | 3 | import android.view.Window 4 | import androidx.core.view.WindowCompat 5 | 6 | 7 | /** 8 | * 设置状态栏高亮模式 9 | */ 10 | inline var Window.statusBarLightMode: Boolean 11 | set(value) { 12 | WindowCompat.getInsetsController(this, decorView).isAppearanceLightStatusBars = value 13 | } 14 | get() { 15 | return WindowCompat.getInsetsController(this, decorView).isAppearanceLightStatusBars 16 | } 17 | 18 | 19 | /** 20 | * dp 转 px 21 | */ 22 | inline val Int.dp: Int 23 | get() { 24 | return (this * AppUtils.app.resources.displayMetrics.density + 0.5f).toInt() 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/Tips.java: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.utils; 2 | 3 | import android.graphics.Color; 4 | import android.graphics.Paint; 5 | import android.graphics.drawable.ShapeDrawable; 6 | import android.graphics.drawable.shapes.RoundRectShape; 7 | import android.view.Gravity; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.FrameLayout; 11 | import android.widget.TextView; 12 | import android.widget.Toast; 13 | 14 | public class Tips { 15 | 16 | /** 17 | * 显示 Toast 18 | * @param message 提示信息 19 | */ 20 | public static void show(String message) { 21 | show(message, Toast.LENGTH_SHORT); 22 | } 23 | 24 | /** 25 | * 显示 Toast 26 | * @param message 提示信息 27 | * @param duration 显示时间长短 28 | */ 29 | public static void show(String message, int duration) { 30 | Toast toast = new Toast(AppUtils.INSTANCE.getApp()); 31 | toast.setDuration(duration); 32 | toast.setGravity(Gravity.CENTER, 0, 0); 33 | toast.setView(createTextToastView(message)); 34 | toast.show(); 35 | } 36 | 37 | /** 38 | * 创建自定义 Toast View 39 | * 40 | * @param message 文本消息 41 | * @return View 42 | */ 43 | private static View createTextToastView(String message) { 44 | // 画圆角矩形背景 45 | float rc = dp2px(6); 46 | RoundRectShape shape = new RoundRectShape(new float[]{rc, rc, rc, rc, rc, rc, rc, rc}, null, null); 47 | ShapeDrawable drawable = new ShapeDrawable(shape); 48 | drawable.getPaint().setColor(Color.argb(225, 240, 240, 240)); 49 | drawable.getPaint().setStyle(Paint.Style.FILL); 50 | drawable.getPaint().setAntiAlias(true); 51 | drawable.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG); 52 | 53 | // 创建View 54 | FrameLayout layout = new FrameLayout(AppUtils.INSTANCE.getApp()); 55 | ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 56 | layout.setLayoutParams(layoutParams); 57 | layout.setPadding(dp2px(16), dp2px(12), dp2px(16), dp2px(12)); 58 | layout.setBackground(drawable); 59 | 60 | TextView textView = new TextView(AppUtils.INSTANCE.getApp()); 61 | textView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT)); 62 | textView.setTextSize(15); 63 | textView.setText(message); 64 | textView.setLineSpacing(dp2px(4), 1f); 65 | textView.setTextColor(Color.BLACK); 66 | 67 | layout.addView(textView); 68 | 69 | return layout; 70 | } 71 | 72 | private static int dp2px(float dpValue) { 73 | final float scale = AppUtils.INSTANCE.getApp().getResources().getDisplayMetrics().density; 74 | return (int) (dpValue * scale + 0.5f); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/utils/VibratorUtils.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.utils 2 | 3 | import android.app.Service 4 | import android.content.Context 5 | import android.os.Build 6 | import android.os.VibrationEffect 7 | import android.os.Vibrator 8 | import android.os.VibratorManager 9 | 10 | /** 11 | * 震动 12 | */ 13 | fun Context.vibrate() { 14 | if (Build.VERSION.SDK_INT >= 31) { 15 | // android 12 及以上使用新的 VibratorManager,创建 EFFECT_TICK 轻微震动(需要线性震动马达硬件支持) 16 | val manager: VibratorManager = 17 | getSystemService(VibratorManager::class.java) 18 | manager.defaultVibrator.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)) 19 | } else if (Build.VERSION.SDK_INT >= 29) { 20 | // android 10 及以上使用原 Vibrator,创建 EFFECT_TICK 轻微震动(需要线性震动马达硬件支持) 21 | val vib = getSystemService(Vibrator::class.java) as Vibrator 22 | vib.vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)) 23 | } else { 24 | // 10 以下的系统,没有系统 API 驱动线性震动马达,只能创建普通震动 25 | val vib = getSystemService(Service.VIBRATOR_SERVICE) as Vibrator //震动70毫秒 26 | vib.vibrate(70) 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/chad/baserecyclerviewadapterhelper/widget/BRVAHToolbar.kt: -------------------------------------------------------------------------------- 1 | package com.chad.baserecyclerviewadapterhelper.widget 2 | 3 | import android.content.Context 4 | import android.os.Build 5 | import android.util.AttributeSet 6 | import android.view.LayoutInflater 7 | import android.widget.RelativeLayout 8 | import androidx.core.content.ContextCompat 9 | import com.chad.baserecyclerviewadapterhelper.R 10 | import com.chad.baserecyclerviewadapterhelper.databinding.LayoutToolBarBinding 11 | 12 | class BRVAHToolbar @JvmOverloads constructor( 13 | context: Context, 14 | attrs: AttributeSet? = null, 15 | defStyleAttr: Int = 0 16 | ) : RelativeLayout(context, attrs, defStyleAttr) { 17 | 18 | private val binding = LayoutToolBarBinding.inflate(LayoutInflater.from(context), this) 19 | 20 | var title: String? 21 | get() = binding.tvTitle.text.toString() 22 | set(value) { 23 | binding.tvTitle.text = value 24 | } 25 | 26 | init { 27 | setBackgroundColor(ContextCompat.getColor(context, R.color.spinner_bg)) 28 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 29 | elevation = context.dpF(10) 30 | } 31 | } 32 | 33 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 34 | super.onMeasure( 35 | widthMeasureSpec, MeasureSpec.makeMeasureSpec(context.dp(44), MeasureSpec.EXACTLY) 36 | ) 37 | } 38 | 39 | fun setOnBackListener(listener: OnClickListener) { 40 | binding.ivBack.setOnClickListener(listener) 41 | } 42 | 43 | private companion object { 44 | fun Context.dp(value: Int): Int { 45 | return (value * this.resources.displayMetrics.density + 0.5f).toInt() 46 | } 47 | 48 | fun Context.dpF(value: Int): Float { 49 | return value * this.resources.displayMetrics.density + 0.5f 50 | } 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /app/src/main/res/anim/item_animation_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/anim/layout_animation_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/touch_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_group_item_bottom_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CymChad/BaseRecyclerViewAdapterHelper/564c428ec5dbb4552a53f5db5c704e7918cd2279/app/src/main/res/drawable-xhdpi/ic_group_item_bottom_bg.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_group_item_mid_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CymChad/BaseRecyclerViewAdapterHelper/564c428ec5dbb4552a53f5db5c704e7918cd2279/app/src/main/res/drawable-xhdpi/ic_group_item_mid_bg.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_group_item_top_bg.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CymChad/BaseRecyclerViewAdapterHelper/564c428ec5dbb4552a53f5db5c704e7918cd2279/app/src/main/res/drawable-xhdpi/ic_group_item_top_bg.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/actionbar_bottom_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/brvah_sample_footer_loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CymChad/BaseRecyclerViewAdapterHelper/564c428ec5dbb4552a53f5db5c704e7918cd2279/app/src/main/res/drawable/brvah_sample_footer_loading.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/brvah_sample_footer_loading_progress.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/custom_text_state_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/gv_animation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CymChad/BaseRecyclerViewAdapterHelper/564c428ec5dbb4552a53f5db5c704e7918cd2279/app/src/main/res/drawable/gv_animation.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/gv_up_fetch.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_item_child.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_right_top_float_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/thumb_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/touch_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_animation_use.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 19 | 20 | 21 | 30 | 31 | 37 | 38 | 44 | 45 | 56 | 57 | 58 | 59 | 60 | 61 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_choose_node_use_type.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 21 | 22 | 26 | 27 | 32 | 33 | 41 | 42 | 43 | 44 | 45 | 46 | 59 | 60 | 64 | 65 | 70 | 71 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_diffutil.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 19 | 20 | 26 | 27 |