diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index c81552d1a..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,27 +0,0 @@ -version: 2 -jobs: - build: - working_directory: ~/code - docker: - - image: circleci/android:api-26-alpha - environment: - JVM_OPTS: -Xmx3200m - steps: - - checkout - - restore_cache: - key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} - - run: - name: Download Dependencies - command: ./gradlew androidDependencies - - save_cache: - paths: - - ~/.gradle - key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} - - run: - name: Run Tests - command: ./gradlew lint test - - store_artifacts: - path: app/build/reports - destination: reports - - store_test_results: - path: app/build/test-results diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 000000000..db10e7f08 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,8 @@ +{ + "permissions": { + "allow": [ + "Bash(./gradlew :library:compileDebugKotlin)", + "Bash(./gradlew :app:compileDebugKotlin)" + ] + } +} diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..0deb949bc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,46 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. + +1. 尝试在[历史问题](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues?q=is%3Aissue+is%3Aclosed)搜索答案。 +2. 尝试阅读[文档](http://www.jianshu.com/p/b343fcff51b0)找到答案。 +3. 尝试阅读[Demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)找到答案。 +4. 尝试自己检查或试验以找到答案。 +5. 尝试阅读源代码以找到答案。 +6. 请勿将产品的一些特殊交互需求 和 该库暂不支持作为bug混为一谈,请您仔细甄别 + +如果以上都尝试过了请提一个新的[issues](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues/new) +参考[提問的智慧](https://github.com/FredWe/How-To-Ask-Questions-The-Smart-Way) + +如果还是没有找到答案,提问请带上这几个必要信息 +1. 当前使用的版本号 +2. 复现操作描述 +3. 使用代码 +3. crash日志 +4. gif复现效果 +5. 抽取demo + **将你出现的问题代码抽出来成一个可直接运行的项目。(最好fork[本库](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)修改)** + **在本地修改demo,然后把commit push到github上,在issue里贴下demo的地址。** + +**有详细的描述才能使得我们更快速的定位问题并解决问题,感谢配合!** diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..69d168fb1 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,7 @@ +Thank you for contributing to BaseRecyclerViewAdapterHelper. Before pressing the "Create Pull Request" button, please consider the following points: + + - [1] Please give a description about what and why you are contributing, even if it's trivial. + + - [2] Please include the issue list number(s) or other PR numbers in the description if you are contributing in response to those. + + - [3] Please include a reasonable set of demo tests if you contribute new code or change an existing one. please make sure you have demo for working correctly. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..70d6d376c --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,29 @@ +name: Android Build + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build library + run: ./gradlew :library:compileDebugKotlin diff --git a/.gitignore b/.gitignore index 0bc28625a..bdfa42829 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ +#///////////////////////////////////////////////////////////////////////////// +# OS generated files +#///////////////////////////////////////////////////////////////////////////// + +.DS_Store +ehthumbs.db +Thumbs.db +.kotlin # Built application files *.apk *.ap_ @@ -28,3 +36,4 @@ proguard/ .gradle .idea build +Repo diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c8908aab0..000000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: android -jdk: oraclejdk8 -sudo: false - -android: - components: - - tools - - build-tools-26.0.2 - - android-26 - - extra-android-m2repository - - extra-android-support - licenses: - - android-sdk-license-.+ - - '.+' - -before_install: - - chmod +x gradlew - - mkdir "$ANDROID_HOME/licenses" || true - - echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license" - - echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license" - -script: - - ./gradlew assembleRelease diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..3774c8999 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,37 @@ +# Repository Guidelines + +## Project Structure & Module Organization +This is an Android Gradle project with Kotlin DSL build files. `settings.gradle` includes two modules: + +- `library/`: the reusable RecyclerView adapter library published as `io.github.cymchad:BaseRecyclerViewAdapterHelper4`. +- `app/`: the sample Android application demonstrating library usage. + +Main source lives under `app/src/main/java` and `library/src/main/java`. Android resources are under each module's `src/main/res`. Keep public library APIs in the `com.chad.library.adapter4` namespace and sample-only code in `com.chad.baserecyclerviewadapterhelper`. + +## Build, Test, and Development Commands +Use the Gradle wrapper from the repository root: + +- `./gradlew assembleDebug`: builds debug artifacts for all modules. +- `./gradlew :app:assembleDebug`: builds the sample app. +- `./gradlew :library:assembleRelease`: builds the release AAR for the library. +- `./gradlew clean`: removes generated build output. +- `./gradlew test`: runs JVM unit tests when test sources exist. +- `./gradlew connectedAndroidTest`: runs instrumentation tests on a connected device or emulator when present. + +The project targets Java 17 via Gradle toolchains. Dependencies and plugin versions are centralized in `gradle/libs.versions.toml`. + +## Coding Style & Naming Conventions +Use Kotlin for new code unless working in an existing Java file. Follow Android/Kotlin conventions: 4-space indentation, `UpperCamelCase` classes, `lowerCamelCase` functions and properties, and package names matching module namespaces. Prefer clear adapter, view holder, and load-state names that match existing patterns such as `BaseQuickAdapter`, `QuickViewHolder`, and `DefaultTrailingLoadStateAdapter`. + +Keep resources lowercase with underscores, for example `brvah_trailing_load_more.xml`. Avoid unrelated formatting churn in mixed Java/Kotlin files. + +## Testing Guidelines +No test directories are currently checked in. Add unit tests under `module/src/test` and Android tests under `module/src/androidTest` when changing behavior. Name tests after the unit under test and expected behavior, for example `BaseDifferAdapterTest`. Run `./gradlew test` before submitting logic changes, and use `connectedAndroidTest` for RecyclerView or UI behavior that needs Android runtime coverage. + +## Commit & Pull Request Guidelines +Recent history uses Conventional Commit-style messages, often scoped, such as `fix(adapter): ...`, `refactor(loadState): ...`, and `docs(README): ...`. Keep commits focused and use scopes that match affected areas. + +Pull requests should include a concise description, linked issues when applicable, test results, and screenshots or recordings for sample app UI changes. For library API changes, document migration notes and update README or wiki references when needed. + +## Security & Configuration Tips +Do not commit `local.properties`, signing keys, Sonatype credentials, or generated publishing output. Publishing credentials are loaded from local properties or environment-specific configuration. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..0eb76d141 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,81 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project + +BRVAH (BaseRecyclerViewAdapterHelper) — a RecyclerView Adapter helper library for Android (current major version: **v4.x**, published as `io.github.cymchad:BaseRecyclerViewAdapterHelper4`). v4 was rewritten to be fully compatible with `ConcatAdapter`, to split functionality into modules, and to support flexible multi-type layouts plus strengthened up/down load-more. + +The repository contains **two Gradle modules**: +- `:library` — the published library (namespace `com.chad.library.adapter4`). This is the artifact. +- `:app` — the demo application that exercises every library feature (`com.chad.baserecyclerviewadapterhelper`). `demo/` holds a prebuilt APK only. + +## Build & Toolchain + +Gradle with Kotlin DSL (`settings.gradle`, `build.gradle.kts`, `gradle/libs.versions.toml`). Toolchain and SDK versions are pinned per module: + +- **JDK 17** toolchain for both modules (CI uses temurin 17). +- `:library` — `compileSdk = 35`, `minSdk = 19`, depends only on `androidx.annotation`, `androidx.recyclerview`, and `compileOnly` `databinding-runtime`. No AndroidX app deps — it is a pure library. +- `:app` — `compileSdk/targetSdk = 36`, `minSdk = 23`, uses viewBinding + dataBinding, Moshi (KSP codegen). All third-party demo deps live here, never in `:library`. + +Common commands (run from repo root): + +```bash +./gradlew :library:compileDebugKotlin # what CI runs — fastest library sanity check +./gradlew :library:assembleRelease # build the AAR +./gradlew :app:assembleDebug # build the demo APK +./gradlew clean +``` + +There is **no test source set** — there are no unit or instrumented tests in either module. Verify changes by compiling and/or running the demo app. + +### Publishing / versioning +- Library version lives in `library/build.gradle.kts` as `val versionName` (currently `4.4.1`). The `:app` `versionName` (`4.3.2`) is independent — update them separately. +- Publishing is configured with `maven-publish` + `signing`. Credentials/signing keys are read from `local.properties` (`signing.keyId`, `signing.password`, `signing.secretKeyRingFile`, `ossrhUsername`, `ossrhPassword`). The active publish repository is the local `$rootDir/Repo` folder (Maven Central upload block is commented out). +- ProGuard consumer rules ship via `consumerProguardFiles("proguard-rules.pro")` in `:library`, so consumers auto-import them; the file itself is mostly a placeholder. + +## Library architecture + +Everything is under `com.chad.library.adapter4`. The design centers on one abstract base plus adapter composition via `ConcatAdapter`. + +### `BaseQuickAdapter` (the base class) +`BaseQuickAdapter.kt` is the foundation for all adapters. Two things define it: + +1. **Two data modes**, decided at construction by whether a `DiffUtil.ItemCallback`/`AsyncDifferConfig` is supplied: + - *Diff mode* — backs `items` with `AsyncListDiffer` (async diffing, no jank). Mutating ops (`submitList`, `add`, `set`, `removeAt`, `swap`, `move`, …) rebuild a mutable list and re-submit. + - *Plain mode* (`mDiffer == null`) — backs `items` with a plain `List` and calls the corresponding `notifyItem*` directly. + Every mutating method branches on `mDiffer == null`; when touching one, update **both** branches. + +2. **Sealed RecyclerView.Adapter overrides.** `getItemCount()`, `getItemViewType()`, `onCreateViewHolder()`, and `onBindViewHolder()` are `final`. Subclasses implement the **protected** variants instead (`onCreateViewHolder(context, parent, viewType)`, `onBindViewHolder(holder, position, item[, payloads])`, `getItemCount(items)`, `getItemViewType(position, list)`). Do not try to override the final ones. + +Other base-class responsibilities: optional **state/empty view** (`isStateViewEnable` + `stateView`, shown when `items` is empty via `StateLayoutVH`), item **animations** (`animationEnable` + `itemAnimation`/`setItemAnimation(AnimationType)`), and click listeners (item / item-child by view id, stored in a `SparseArray`). `items` setter is `@Deprecated` at **ERROR level** — use `submitList()` to replace data. + +### Adapter variants (all extend `BaseQuickAdapter`) +- **`BaseMultiItemAdapter`** — multi view-type layouts. Register each type with `addItemType(viewType, OnMultiItemAdapterListener)` and decide types via `onItemViewType { position, list -> }`. The listener (or `OnMultiItem` subclass, which grants `adapter`/`context`) provides `onCreate`/`onBind` per type. +- **`BaseNodeAdapter`** — tree/expandable lists. Subclasses implement `getChildNodeList()` and `isInitialOpen()`; `open()`/`close()`/`openOrClose()`/`closeAll()` drive expansion. Open/closed state is tracked by a custom `NodeSet` matched through `isSameNode()` (override for value-based nodes; default is `===`). See the bilingual KDoc on `isSameNode` — it must uniquely identify a node or expand/collapse state leaks across nodes. +- **`BaseSingleItemAdapter`** — exactly one item (headers/footers). All list mutation methods throw; use `item`/`setItem()` only. +- **`BaseDifferAdapter`** — deprecated; `BaseQuickAdapter` now subsumes it. + +### Composition: `QuickAdapterHelper` +`QuickAdapterHelper` wraps a content adapter in a `ConcatAdapter` and exposes `helper.adapter` to set on the `RecyclerView`. Layout order: `LeadingLoadStateAdapter` → before-adapters → **content adapter** → after-adapters → `TrailingLoadStateAdapter`. Built via `QuickAdapterHelper.Builder(contentAdapter)` with optional leading/trailing load-more, then `.build()` or `.attachTo(recyclerView)`. This is the canonical way to get header/footer and up/down load-more in v4 — header/footer are separate small adapters prepended/appended, not built-in fields of the base adapter. + +### Load more (`loadState/`) +- `LoadState` — sealed type: `None`, `NotLoading(endOfPaginationReached)`, `Loading`, `Error`. +- `LoadStateAdapter` — base for a load-more adapter; toggles its single item on/off via `displayLoadStateAsItem()`. +- `TrailingLoadStateAdapter` (tail) / `LeadingLoadStateAdapter` (head), each with a `Default…` implementation. Trailing supports `isAutoLoadMore`, `preloadSize`, and `checkDisableLoadMoreIfNotFullPage()`. + +### Supporting utilities +- `viewholder/QuickViewHolder` — convenience `ViewHolder` with cached `findViewById` and chained setters (`setText`, `setVisible`, …). +- `layoutmanager/QuickGridLayoutManager` — `GridLayoutManager` that grants full span to adapters implementing `FullSpanAdapterType`, and to `BaseQuickAdapter` view types for which `isFullSpanItem(type)` is true (the empty/state view is full-span by default). Use it (or your own `SpanSizeLookup`) when an item must span all columns. +- `dragswipe/QuickDragAndSwipe` + `DragSwipeExt.kt` — drag-and-swipe on top of `ItemTouchHelper`. +- `animation/*` — `ItemAnimator` implementations (`AlphaIn`, `ScaleIn`, `SlideIn{Left,Right,Bottom}`). +- `util/AdapterUtils.kt` — `ViewGroup.getItemView(layoutResId)` and `ViewHolder.asStaggeredGridFullSpan()`. + +### Internal resource IDs +The library declares IDs in `library/src/main/res/values/ids.xml` (e.g. `BaseQuickAdapter_empty_view`, `BaseQuickAdapter_key_multi`) used for internal view tagging and the empty-view `viewType`. The `EMPTY_VIEW` companion constant points at `R.id.BaseQuickAdapter_empty_view`. + +## Conventions + +- **Bilingual KDoc.** Public API documentation is written in **both Chinese and English** (Chinese typically first, then English). Match this style when adding or editing public APIs. +- **Builder/`apply` chaining.** Setters in `BaseQuickAdapter` and `QuickAdapterHelper.Builder` return `apply`/the builder for fluent config. +- Keep `:library` dependency-free of UI libs — it should only depend on AndroidX `annotation`/`recyclerview` (plus `compileOnly` databinding). Put demo-only dependencies in `:app`. diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..7948c9d34 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 陈宇明 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README-cn.md b/README-cn.md deleted file mode 100644 index 3d95317dc..000000000 --- a/README-cn.md +++ /dev/null @@ -1,418 +0,0 @@ ->RecyclerView作为Android最常用的控件,受益群体几乎是所有Android开发者,希望更多开发者能够一起来维护这个项目,把这个项目做得更好,帮助更多人。**Star我的项目可加Q群558178792,申请的时候把GitHub的账号名字备注上否则不予通过,谢谢配合。**中国有句古话叫“授人以鱼不如授人以渔”,不仅仅提供使用,还写了如何实现的原理: -- 「[RecyclerView.Adapter优化了吗?](http://www.jianshu.com/p/411ab861034f)」 -- 「[BaseRecyclerAdapter之添加动画](http://www.jianshu.com/p/fa3f97c19263)」 -- 「[BaseRecyclerAdapter之添加不同布局(头部尾部)](http://www.jianshu.com/p/9d75c22f0964)」 -- 「[BaseRecyclerAdapter之添加不同布局(优化篇)](http://www.jianshu.com/p/cf29d4e45536)」 -- 「[BaseRecyclerAdapter之分组功能原理分析](http://www.jianshu.com/p/87a49f732724)」 -- 「[RecyclerView相关优秀文集](https://github.com/CymChad/CymChad.github.io)」 -- 「[BRVAH分享吧](https://github.com/CymChad/BRVAHST)」 - -[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-BaseRecyclerViewAdapterHelper-green.svg?style=true)](https://android-arsenal.com/details/1/3644) -[![](https://jitpack.io/v/CymChad/BaseRecyclerViewAdapterHelper.svg)](https://jitpack.io/#CymChad/BaseRecyclerViewAdapterHelper) - -# BaseRecyclerViewAdapterHelper -![logo](http://upload-images.jianshu.io/upload_images/972352-1d77e0a75a4a7c0a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) -一个强大并且灵活的RecyclerViewAdapter,欢迎使用。(喜欢的可以**Star**一下) -## Google Play Demo - -[![Get it on Google Play](https://developer.android.com/images/brand/en_generic_rgb_wo_60.png)](https://play.google.com/store/apps/details?id=com.chad.baserecyclerviewadapterhelper) -# 它能做什么?([下载 apk](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/raw/master/demo_res/demo.apk)) -- **优化Adapter代码(减少百分之70%代码)** -- **添加点击item点击、长按事件、以及item子控件的点击事件** -- **添加加载动画(一行代码轻松切换5种默认动画)** -- **添加头部、尾部、下拉刷新、上拉加载(感觉又回到ListView时代)** -- **设置自定义的加载更多布局** -- **添加分组(随心定义分组头部)** -- **自定义不同的item类型(简单配置、无需重写额外方法)** -- **设置空布局(比Listview的setEmptyView还要好用!)** -- **添加拖拽item** - -# 扩展库 -[PinnedSectionItemDecoration](https://github.com/oubowu/PinnedSectionItemDecoration) -# 如何使用它? -先在 build.gradle 的 repositories 添加: -``` - allprojects { - repositories { - ... - maven { url "https://jitpack.io" } - } - } -``` -然后在dependencies添加: -``` - dependencies { - compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:v1.9.7' - } -``` - -# 如何使用它来创建Adapter? -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/item_view.png) -```java -public class QuickAdapter extends BaseQuickAdapter { - public QuickAdapter() { - super(R.layout.tweet, DataServer.getSampleData()); - } - - @Override - protected void convert(BaseViewHolder helper, Status item) { - helper.setText(R.id.tweetName, item.getUserName()) - .setText(R.id.tweetText, item.getText()) - .setText(R.id.tweetDate, item.getCreatedAt()) - .setVisible(R.id.tweetRT, item.isRetweet()) - .linkify(R.id.tweetText); - Glide.with(mContext).load(item.getUserAvatar()).crossFade().into((ImageView) helper.getView(R.id.iv)); - } -} -``` -Adapter -```java -mRecyclerView.addOnItemTouchListener(new OnItemClickListener( ){ - - @Override - public void SimpleOnItemClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); - - } - }); - -``` -# 设置 item click 新增添加子布局多个控件的点击事件 -# 设置 it item child click -首先需要添加需要点击触发的 childview id -``` - @Override - protected void convert(BaseViewHolder helper, Status item) { - helper.setText(R.id.tweetName, item.getUserName()) - .setText(R.id.tweetText, item.getText()) - .setText(R.id.tweetDate, item.getCreatedAt()) - .setVisible(R.id.tweetRT, item.isRetweet()) - .addOnClickListener(R.id.tweetAvatar) - .addOnClickListener(R.id.tweetName) - .addOnLongClickListener(R.id.tweetText) - .linkify(R.id.tweetText); - Glide.with(mContext).load(item.getUserAvatar()).crossFade().placeholder(R.mipmap.def_head).transform(new GlideCircleTransform(mContext)).into((ImageView) helper.getView(R.id.tweetAvatar)); - } -``` -Activity -```java - mRecyclerView.addOnItemTouchListener(new OnItemChildClickListener( ) { - @Override - public void SimpleOnItemChildClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); - - } - }); -``` -# 设置 it item long click -```java - mRecyclerView.addOnItemTouchListener(new OnItemLongClickListener( ) { - @Override - public void SimpleOnItemLongClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); - - } - }); -``` -# 设置 it item child long click -首先需要添加需要点击触发的 childview id -``` - @Override - protected void convert(BaseViewHolder helper, Status item) { - helper.setText(R.id.tweetName, item.getUserName()) - .setText(R.id.tweetText, item.getText()) - .setText(R.id.tweetDate, item.getCreatedAt()) - .setVisible(R.id.tweetRT, item.isRetweet()) - .addOnClickListener(R.id.tweetAvatar) - .addOnClickListener(R.id.tweetName) - .addOnLongClickListener(R.id.tweetText) - .linkify(R.id.tweetText); - Glide.with(mContext).load(item.getUserAvatar()).crossFade().placeholder(R.mipmap.def_head).transform(new GlideCircleTransform(mContext)).into((ImageView) helper.getView(R.id.tweetAvatar)); - } -``` -然后 -```java - mRecyclerView.addOnItemTouchListener(new OnItemChildLongClickListener( ) { - @Override - public void SimpleOnItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); - } - }); -``` -# 如果你想实现多种点击事件,你可以实现 SimpleClickListener类。提供了丰富的事件点击封装 -```java - mRecyclerView.addOnItemTouchListener(new SimpleClickListener() { - @Override - public void onItemClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); - } - - @Override - public void onItemLongClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); - } - - @Override - public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); - } - - @Override - public void onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(RecyclerClickItemActivity.this, "" + Integer.toString(position), Toast.LENGTH_SHORT).show(); - } - }); -``` - - -# 如何使用它添加动画? -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/animation.gif) -```java -// 一行代码搞定(默认为渐显效果) -quickAdapter.openLoadAnimation(); -``` -不喜欢渐显动画可以这样更换 -```java -// 默认提供5种方法(渐显、缩放、从下到上,从左到右、从右到左) -quickAdapter.openLoadAnimation(BaseQuickAdapter.ALPHAIN); -``` -还是没你喜欢的,你可以自定义 -```java -// 自定义动画如此轻松 -quickAdapter.openLoadAnimation(new BaseAnimation() { - @Override - public Animator[] getAnimators(View view) { - return new Animator[]{ - ObjectAnimator.ofFloat(view, "scaleY", 1, 1.1f, 1), - ObjectAnimator.ofFloat(view, "scaleX", 1, 1.1f, 1) - }; - } - }); -``` -# 使用它添加头部添加尾部 -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/header_footer.gif) -```java -// add -mQuickAdapter.addHeaderView(getView()); -mQuickAdapter.addFooterView(getView()); -// remove -removeHeaderView(getView); -removeFooterView(getView); -// or -removeAllHeaderView(); -removeAllFooterView(); -``` -# 使用它加载更多 -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/load_more.gif) -```java -mQuickAdapter.openLoadMore(PAGE_SIZE, true); -mQuickAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() { - @Override - public void onLoadMoreRequested() { - mRecyclerView.post(new Runnable() { - @Override - public void run() { - if (mCurrentCounter >= TOTAL_COUNTER) { - mQuickAdapter.notifyDataChangedAfterLoadMore(false); - } else { - mQuickAdapter.notifyDataChangedAfterLoadMore(DataServer.getSampleData(PAGE_SIZE), true); - mCurrentCounter = mQuickAdapter.getItemCount(); - } - } - - }); - } - }); -``` -# 设置自定义加载更多布局 -```java -mQuickAdapter.setLoadingView(customView); -``` -# 使用分组 -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/section_headers.gif) -```java -public class SectionAdapter extends BaseSectionQuickAdapter { - public SectionAdapter(int layoutResId, int sectionHeadResId, List data) { - super(layoutResId, sectionHeadResId, data); - } - @Override - protected void convert(BaseViewHolder helper, MySection item) { - helper.setImageUrl(R.id.iv, (String) item.t); - } - @Override - protected void convertHead(BaseViewHolder helper,final MySection item) { - helper.setText(R.id.header, item.header); - - helper.setOnClickListener(R.id.more, new View.OnClickListener() { - @Override - public void onClick(View v) { - Toast.makeText(context,item.header+"more..",Toast.LENGTH_LONG).show(); - } - }); - } -``` -# 如何添加多种类型item? -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/multiple_item.gif) -```java -public class MultipleItemQuickAdapter extends BaseMultiItemQuickAdapter { - - public MultipleItemQuickAdapter(List data) { - super(data); - addItemType(MultipleItem.TEXT, R.layout.text_view); - addItemType(MultipleItem.IMG, R.layout.image_view); - } - - @Override - protected void convert(BaseViewHolder helper, MultipleItem item) { - switch (helper.getItemViewType()) { - case MultipleItem.TEXT: - helper.setImageUrl(R.id.tv, item.getContent()); - break; - case MultipleItem.IMG: - helper.setImageUrl(R.id.iv, item.getContent()); - break; - } - } - -} -``` -# 使用setEmptyView -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/empty_view.gif) -```java -mQuickAdapter.setEmptyView(getView()); -``` -# 使用拖拽与滑动删除 -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/drag_item.gif) -```java -OnItemDragListener onItemDragListener = new OnItemDragListener() { - @Override - public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos){} - @Override - public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {} - @Override - public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {} -} - -OnItemSwipeListener onItemSwipeListener = new OnItemSwipeListener() { - @Override - public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {} - @Override - public void clearView(RecyclerView.ViewHolder viewHolder, int pos) {} - @Override - public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {} -}; - -public class ItemDragAdapter extends BaseItemDraggableAdapter { - public ItemDragAdapter(List data) { - super(R.layout.item_draggable_view, data); - } - - @Override - protected void convert(BaseViewHolder helper, String item) { - helper.setText(R.id.tv, item); - } -} - -mAdapter = new ItemDragAdapter(mData); - -ItemDragAndSwipeCallback itemDragAndSwipeCallback = new ItemDragAndSwipeCallback(mAdapter); -ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemDragAndSwipeCallback); -itemTouchHelper.attachToRecyclerView(mRecyclerView); - -// 开启拖拽 -mAdapter.enableDragItem(itemTouchHelper, R.id.textView, true); -mAdapter.setOnItemDragListener(onItemDragListener); - -// 开启滑动删除 -mAdapter.enableSwipeItem(); -mAdapter.setOnItemSwipeListener(onItemSwipeListener); -``` - -# Expandable Item -![demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/demo_res/expandable_item.gif) -```Java -// 如果不想使用继承,可以只实现IExpandable接口 -// AbstractExpandableItem只是个帮助类 -public class Level0Item extends AbstractExpandableItem {...} -public class Level1Item extends AbstractExpandableItem {...} -public class Person {...} -``` -in adapter code -```Java - -public class ExpandableItemAdapter extends BaseMultiItemQuickAdapter { - public ExpandableItemAdapter(List data) { - super(data); - addItemType(TYPE_LEVEL_0, R.layout.item_expandable_lv0); - addItemType(TYPE_LEVEL_1, R.layout.item_expandable_lv1); - addItemType(TYPE_PERSON, R.layout.item_text_view); - } - @Override - protected void convert(final BaseViewHolder holder, final MultiItemEntity item) { - switch (holder.getItemViewType()) { - case TYPE_LEVEL_0: - .... - //set view content - holder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - int pos = holder.getAdapterPosition(); - if (lv0.isExpanded()) { - collapse(pos); - } else { - expand(pos); - } - }}); - break; - case TYPE_LEVEL_1: - // similar with level 0 - break; - case TYPE_PERSON: - //just set the content - break; - } -} -``` -In activity code -```Java -public class ExpandableUseActivity extends Activity { - @Override - protected void onCreate(Bundle savedInstanceState) { - ... - ArrayList list = generateData(); - ExpandableItemAdapter adapter = new ExpandableItemAdapter(list); - mRecyclerView.setAdapter(adapter); - } - - private ArrayList generateData() { - ArrayList res = new ArrayList<>(); - for (int i = 0; i < lv0Count; i++) { - Level0Item lv0 = new Level0Item(...); - for (int j = 0; j < lv1Count; j++) { - Level1Item lv1 = new Level1Item(...); - for (int k = 0; k < personCount; k++) { - lv1.addSubItem(new Person()); - } - lv0.addSubItem(lv1); - } - res.add(lv0); - } - return res; - } -} -``` - -Use Custom BaseViewHolder -```Java - -// 当使用自定义的BaseViewHolder时,需要重写此函数以创建ViewHolder -protected K createBaseViewHolder(View view) { - return (K) new BaseViewHolder(view); -} - -``` - ->**持续更新!,所以推荐Star项目** - -# 感谢 -[JoanZapata / base-adapter-helper](https://github.com/JoanZapata/base-adapter-helper) diff --git a/README.md b/README.md index 2d210c794..56aea862e 100644 --- a/README.md +++ b/README.md @@ -1,57 +1,48 @@ ![](https://user-images.githubusercontent.com/7698209/33198075-ef8f2230-d123-11e7-85a3-4cb9b22f877d.png) -[![](https://jitpack.io/v/CymChad/BaseRecyclerViewAdapterHelper.svg)](https://jitpack.io/#CymChad/BaseRecyclerViewAdapterHelper)![](https://travis-ci.org/CymChad/BaseRecyclerViewAdapterHelper.svg?branch=master)[![API](https://img.shields.io/badge/API-14%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=14)[![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)[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2302d0084d0048eaa0f9bac4350837a0)](https://www.codacy.com/app/CymChad/BaseRecyclerViewAdapterHelper?utm_source=github.com&utm_medium=referral&utm_content=CymChad/BaseRecyclerViewAdapterHelper&utm_campaign=Badge_Grade)[![](https://img.shields.io/badge/%E4%BD%9C%E8%80%85-%E9%99%88%E5%AE%87%E6%98%8E-7AD6FD.svg)](http://www.jianshu.com/u/f958e66439f0) +[![](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 Build](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/actions/workflows/build.yml) [![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/CymChad/BaseRecyclerViewAdapterHelper) [![Context7](https://img.shields.io/badge/Context7-AI-5D5FEC.svg)](https://context7.com/cymchad/baserecyclerviewadapterhelper) [![](https://img.shields.io/badge/%E4%BD%9C%E8%80%85-%E9%99%88%E5%AE%87%E6%98%8E-7AD6FD.svg)](https://mp.weixin.qq.com/s/U4QAPlu5WDm8U5Ljc7TuAQ) [![](https://img.shields.io/badge/%E4%BD%9C%E8%80%85-limuyang2-7AD6FD)](https://github.com/limuyang2) # BRVAH -http://www.recyclerview.org/ -Powerful and flexible RecyclerAdapter, + +Powerful and flexible RecyclerView Adapter, Please feel free to use this. (Welcome to **Star** and **Fork**) -kotlin demo :[BRVAH_kotlin](https://github.com/AllenCoder/BRVAH_kotlin) -# Document -- [English](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki) -- [中文](http://www.jianshu.com/p/b343fcff51b0) +强大而灵活的RecyclerView Adapter(欢迎 **Star** 和 **Fork**) -## [UI](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues/694) -## Demo +​ +新版4.x.x已发布,完美兼容`ConcatAdapter`,解决了许多遗留问题,拆分了功能模块,BaseAdapter更加简洁干净。“多类型布局”更加灵活。向上、向下加载得到极大加强。 +v4版本已经上传 maven 中央仓库,不需要再引入三方仓库配置了。欢迎尝试。 -[![Get it on Google Play](https://developer.android.com/images/brand/en_generic_rgb_wo_60.png)](https://play.google.com/store/apps/details?id=com.chad.baserecyclerviewadapterhelper) -[国内下载地址](https://fir.im/s91g) -# proguard-rules.pro +Of course, you can continue to use the [2.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/2.x) version. + +当然,你也可以继续使用[2.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/2.x) 版本、[3.x](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/3.x/readme/0-BaseRecyclerViewAdapterHelper.md)版本。 + +# Document +- English Writing ... +- [3.0版本 中文](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/3.x/readme/0-BaseRecyclerViewAdapterHelper.md) +- [4.0版本 中文](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki) + + +(由于各位项目成员工作较为繁忙,请各位同学谅解) + +## v4 版本 +[wiki](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/wiki) ``` --keep class com.chad.library.adapter.** { -*; -} --keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter --keep public class * extends com.chad.library.adapter.base.BaseViewHolder --keepclassmembers class **$** extends com.chad.library.adapter.base.BaseViewHolder { - (...); -} +implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.4.1") ``` -# Extension library -[PinnedSectionItemDecoration](https://github.com/oubowu/PinnedSectionItemDecoration) -[EasyRefreshLayout](https://github.com/anzaizai/EasyRefreshLayout) -[EasySwipeMenuLayout](https://github.com/anzaizai/EasySwipeMenuLayout) +## [demo](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/tree/master/demo) -# Thanks -[JoanZapata / base-adapter-helper](https://github.com/JoanZapata/base-adapter-helper) +# proguard-rules.pro +> 此资源库自带混淆规则,并且会自动导入,正常情况下无需手动导入。 -# License -``` -Copyright 2016 陈宇明 +> The library comes with `proguard-rules.pro` rules and is automatically imported. Normally no manual import is required. +> You can also go here to view [proguard-rules](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/library/proguard-rules.pro) -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -``` -# 推荐 -![](https://user-images.githubusercontent.com/7698209/33198309-4908849a-d125-11e7-80eb-a80c64d61c77.jpeg) + +# Thanks +[JoanZapata / base-adapter-helper](https://github.com/JoanZapata/base-adapter-helper) + +# [License](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/blob/master/LICENSE) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..05c872e35 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,17 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| -------- | ------------------ | +| 4.3.x | :white_check_mark: | +| < 4.0.0 | :x: | + +## Reporting a Vulnerability + +If you discover a security vulnerability, please report it by opening an issue on [GitHub Issues](https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues). + +- Provide a clear description of the vulnerability and steps to reproduce it. +- We will acknowledge your report within 7 business days and keep you updated on the progress. +- Once confirmed, we will release a fix as soon as possible depending on the severity. +- If the report is declined, we will explain the reason. diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index f54b0c599..000000000 --- a/app/build.gradle +++ /dev/null @@ -1,36 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 26 - - defaultConfig { - applicationId "com.chad.baserecyclerviewadapterhelper" - minSdkVersion 14 - targetSdkVersion 26 - versionCode 5 - versionName "2.1" - } - buildTypes { - release { - minifyEnabled true - zipAlignEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - - } - dataBinding { - enabled = true - } -} - -dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation project(path: ':library') - implementation project(':material-spinner-1.0.5') - implementation 'com.github.bumptech.glide:glide:3.7.0' - implementation 'com.android.support:design:26.1.0' - implementation 'com.android.support:cardview-v7:26.1.0' - implementation 'com.android.support:appcompat-v7:26.1.0' - implementation 'com.kyleduo.switchbutton:library:1.4.4' - implementation 'com.orhanobut:logger:2.1.1' -} diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 000000000..4c836bfd1 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,60 @@ +plugins { + id("com.android.application") + id("com.google.devtools.ksp") +} + +android { + compileSdk = 36 + + defaultConfig { + applicationId = "com.chad.baserecyclerviewadapterhelper" + minSdk = 23 + targetSdk = 36 + versionCode = 21 + versionName = "4.3.2" + } + buildTypes { + release { + isMinifyEnabled = true + isShrinkResources = true + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + debug { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + buildFeatures { + viewBinding = true + dataBinding = true + } + namespace = "com.chad.baserecyclerviewadapterhelper" +} + +kotlin { + jvmToolchain(17) +} + +dependencies { + implementation(fileTree(mapOf("include" to listOf("*.jar", "*.aar"), "dir" to "libs"))) + implementation(project(":library")) + implementation(libs.google.material) + implementation(libs.androidx.cardview) + implementation(libs.androidx.appcompat) + implementation(libs.androidx.core.ktx) + + implementation(libs.kyleduo.switchbutton) + implementation(libs.androidx.recyclerview) + implementation(libs.androidx.swiperefreshlayout) + + implementation(libs.moshi) + ksp(libs.moshi.kotlin.codegen) + + implementation(libs.jaredrummler.material.spinner) +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index aad001d60..743dfc188 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -16,11 +16,3 @@ # public *; #} #BaseRecyclerViewAdapterHelper --keep class com.chad.library.adapter.** { -*; -} --keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter --keep public class * extends com.chad.library.adapter.base.BaseViewHolder --keepclassmembers public class * extends com.chad.library.adapter.base.BaseViewHolder { - (android.view.View); -} diff --git a/app/src/androidTest/java/com/chad/baserecyclerviewadapterhelper/ApplicationTest.java b/app/src/androidTest/java/com/chad/baserecyclerviewadapterhelper/ApplicationTest.java deleted file mode 100644 index c03cfebe5..000000000 --- a/app/src/androidTest/java/com/chad/baserecyclerviewadapterhelper/ApplicationTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } - public void test() { - - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a1b6bf0c1..50ba5042a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,38 +1,75 @@ - + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/AnimationUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/AnimationUseActivity.java deleted file mode 100644 index dad382d42..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/AnimationUseActivity.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.app.Activity; -import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.widget.CompoundButton; -import android.widget.ImageView; -import android.widget.Toast; - -import com.chad.baserecyclerviewadapterhelper.adapter.AnimationAdapter; -import com.chad.baserecyclerviewadapterhelper.animation.CustomAnimation; -import com.chad.baserecyclerviewadapterhelper.entity.Status; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.jaredrummler.materialspinner.MaterialSpinner; -import com.kyleduo.switchbutton.SwitchButton; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - *

- * modify by AllenCoder - */ -public class AnimationUseActivity extends Activity { - private RecyclerView mRecyclerView; - private AnimationAdapter mAnimationAdapter; - private ImageView mImgBtn; - private int mFirstPageItemCount = 3; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_adapter_use); - mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - initAdapter(); - initMenu(); - initView(); - } - - private void initView() { - - mImgBtn = (ImageView) findViewById(R.id.img_back); - mImgBtn.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(final View v) { - finish(); - } - }); - } - - private void initAdapter() { - mAnimationAdapter = new AnimationAdapter(); - mAnimationAdapter.openLoadAnimation(); - mAnimationAdapter.setNotDoAnimationCount(mFirstPageItemCount); - mAnimationAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() { - @Override - public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { - String content = null; - Status status = (Status) adapter.getItem(position); - switch (view.getId()) { - case R.id.img: - content = "img:" + status.getUserAvatar(); - Toast.makeText(AnimationUseActivity.this, content, Toast.LENGTH_LONG).show(); - break; - case R.id.tweetName: - content = "name:" + status.getUserName(); - Toast.makeText(AnimationUseActivity.this, content, Toast.LENGTH_LONG).show(); - break; - case R.id.tweetText: - content = "tweetText:" + status.getUserName(); - Toast.makeText(AnimationUseActivity.this, content, Toast.LENGTH_LONG).show(); - // you have set clickspan .so there should not solve any click event ,just empty - break; - - } - } - }); - mRecyclerView.setAdapter(mAnimationAdapter); - } - - private void initMenu() { - MaterialSpinner spinner = (MaterialSpinner) findViewById(R.id.spinner); - spinner.setItems("AlphaIn", "ScaleIn", "SlideInBottom", "SlideInLeft", "SlideInRight", "Custom"); - spinner.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener() { - - @Override - public void onItemSelected(MaterialSpinner view, int position, long id, String item) { - switch (position) { - case 0: - mAnimationAdapter.openLoadAnimation(BaseQuickAdapter.ALPHAIN); - break; - case 1: - mAnimationAdapter.openLoadAnimation(BaseQuickAdapter.SCALEIN); - break; - case 2: - mAnimationAdapter.openLoadAnimation(BaseQuickAdapter.SLIDEIN_BOTTOM); - break; - case 3: - mAnimationAdapter.openLoadAnimation(BaseQuickAdapter.SLIDEIN_LEFT); - break; - case 4: - mAnimationAdapter.openLoadAnimation(BaseQuickAdapter.SLIDEIN_RIGHT); - break; - case 5: - mAnimationAdapter.openLoadAnimation(new CustomAnimation()); - break; - default: - break; - } - mRecyclerView.setAdapter(mAnimationAdapter); - } - }); - mAnimationAdapter.isFirstOnly(false);//init firstOnly state - SwitchButton switchButton = (SwitchButton) findViewById(R.id.switch_button); - switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) { - if (isChecked) { - mAnimationAdapter.isFirstOnly(true); - } else { - mAnimationAdapter.isFirstOnly(false); - } - mAnimationAdapter.notifyDataSetChanged(); - } - }); - - } - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/DataBindingUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/DataBindingUseActivity.java deleted file mode 100644 index 3acf9acbb..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/DataBindingUseActivity.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; - -import com.chad.baserecyclerviewadapterhelper.adapter.DataBindingUseAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.entity.Movie; -import com.chad.baserecyclerviewadapterhelper.util.ToastUtils; -import com.chad.library.adapter.base.BaseQuickAdapter; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -public class DataBindingUseActivity extends BaseActivity { - - RecyclerView mRecyclerView; - DataBindingUseAdapter mAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setBackBtn(); - setTitle("DataBinding Use"); - setContentView(R.layout.activity_data_binding_use); - - mRecyclerView = (RecyclerView) findViewById(R.id.rv); - mAdapter = new DataBindingUseAdapter(R.layout.item_movie, genData()); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - mRecyclerView.setAdapter(mAdapter); - mAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { - @Override - public void onItemClick(BaseQuickAdapter adapter, View view, int position) { - ToastUtils.showShortToast("onItemClick"); - } - }); - mAdapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() { - @Override - public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { - ToastUtils.showShortToast("onItemChildLongClick"); - return true; - } - }); - mAdapter.setOnItemLongClickListener(new BaseQuickAdapter.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) { - ToastUtils.showShortToast("onItemLongClick"); - return true; - } - }); - } - - - private List genData() { - ArrayList list = new ArrayList<>(); - Random random = new Random(); - for (int i = 0; i < 10; i++) { - String name = "Chad"; - int price = random.nextInt(10) + 10; - int len = random.nextInt(80) + 60; - Movie movie = new Movie(name, len, price, "He was one of Australia's most distinguished artistes"); - list.add(movie); - } - return list; - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/EmptyViewUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/EmptyViewUseActivity.java deleted file mode 100644 index 59b01d54b..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/EmptyViewUseActivity.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.os.Bundle; -import android.os.Handler; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.view.ViewGroup; - -import com.chad.baserecyclerviewadapterhelper.adapter.QuickAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; - -public class EmptyViewUseActivity extends BaseActivity implements View.OnClickListener { - private RecyclerView mRecyclerView; - private QuickAdapter mQuickAdapter; - private View notDataView; - private View errorView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setBackBtn(); - setTitle("EmptyView Use"); - setContentView(R.layout.activity_empty_view_use); - findViewById(R.id.btn_reset).setOnClickListener(this); - mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); - mRecyclerView.setHasFixedSize(true); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - - notDataView = getLayoutInflater().inflate(R.layout.empty_view, (ViewGroup) mRecyclerView.getParent(), false); - notDataView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onRefresh(); - } - }); - errorView = getLayoutInflater().inflate(R.layout.error_view, (ViewGroup) mRecyclerView.getParent(), false); - errorView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onRefresh(); - } - }); - initAdapter(); - onRefresh(); - } - - private void initAdapter() { - mQuickAdapter = new QuickAdapter(0); - mRecyclerView.setAdapter(mQuickAdapter); - } - - @Override - public void onClick(View v) { - mError = true; - mNoData = true; - mQuickAdapter.setNewData(null); - onRefresh(); - } - - private boolean mError = true; - private boolean mNoData = true; - - private void onRefresh() { - mQuickAdapter.setEmptyView(R.layout.loading_view, (ViewGroup) mRecyclerView.getParent()); - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - if (mError) { - mQuickAdapter.setEmptyView(errorView); - mError = false; - } else { - if (mNoData) { - mQuickAdapter.setEmptyView(notDataView); - mNoData = false; - } else { - mQuickAdapter.setNewData(DataServer.getSampleData(10)); - } - } - } - }, 1000); - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ExpandableUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ExpandableUseActivity.java deleted file mode 100644 index 5afccd64e..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ExpandableUseActivity.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.os.Bundle; -import android.support.v7.widget.GridLayoutManager; -import android.support.v7.widget.RecyclerView; - -import com.chad.baserecyclerviewadapterhelper.adapter.ExpandableItemAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.entity.Level0Item; -import com.chad.baserecyclerviewadapterhelper.entity.Level1Item; -import com.chad.baserecyclerviewadapterhelper.entity.Person; -import com.chad.library.adapter.base.entity.MultiItemEntity; - -import java.util.ArrayList; -import java.util.Random; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class ExpandableUseActivity extends BaseActivity { - RecyclerView mRecyclerView; - ExpandableItemAdapter adapter; - ArrayList list; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setBackBtn(); - setTitle("ExpandableItem Activity"); - setContentView(R.layout.activity_expandable_item_use); - - mRecyclerView = (RecyclerView) findViewById(R.id.rv); - - list = generateData(); - adapter = new ExpandableItemAdapter(list); - - final GridLayoutManager manager = new GridLayoutManager(this, 3); - manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { - @Override - public int getSpanSize(int position) { - return adapter.getItemViewType(position) == ExpandableItemAdapter.TYPE_PERSON ? 1 : manager.getSpanCount(); - } - }); - - mRecyclerView.setAdapter(adapter); - // important! setLayoutManager should be called after setAdapter - mRecyclerView.setLayoutManager(manager); - adapter.expandAll(); - } - - private ArrayList generateData() { - int lv0Count = 9; - int lv1Count = 3; - int personCount = 5; - - String[] nameList = {"Bob", "Andy", "Lily", "Brown", "Bruce"}; - Random random = new Random(); - - ArrayList res = new ArrayList<>(); - for (int i = 0; i < lv0Count; i++) { - Level0Item lv0 = new Level0Item("This is " + i + "th item in Level 0", "subtitle of " + i); - for (int j = 0; j < lv1Count; j++) { - Level1Item lv1 = new Level1Item("Level 1 item: " + j, "(no animation)"); - for (int k = 0; k < personCount; k++) { - lv1.addSubItem(new Person(nameList[k], random.nextInt(40))); - } - lv0.addSubItem(lv1); - } - res.add(lv0); - } - res.add(new Level0Item("This is " + lv0Count + "th item in Level 0", "subtitle of " + lv0Count)); - return res; - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HeaderAndFooterUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HeaderAndFooterUseActivity.java deleted file mode 100644 index fba78f959..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HeaderAndFooterUseActivity.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.Toast; - -import com.chad.baserecyclerviewadapterhelper.adapter.HeaderAndFooterAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.library.adapter.base.BaseQuickAdapter; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class HeaderAndFooterUseActivity extends BaseActivity { - - private RecyclerView mRecyclerView; - private HeaderAndFooterAdapter headerAndFooterAdapter; - private static final int PAGE_SIZE = 3; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setBackBtn(); - setTitle("HeaderAndFooter Use"); - - setContentView(R.layout.activity_header_and_footer_use); - mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - initAdapter(); - - View headerView = getHeaderView(0, new View.OnClickListener() { - @Override - public void onClick(View v) { - headerAndFooterAdapter.addHeaderView(getHeaderView(1, getRemoveHeaderListener()), 0); - } - }); - headerAndFooterAdapter.addHeaderView(headerView); - - - View footerView = getFooterView(0, new View.OnClickListener() { - @Override - public void onClick(View v) { - headerAndFooterAdapter.addFooterView(getFooterView(1, getRemoveFooterListener()), 0); - } - }); - headerAndFooterAdapter.addFooterView(footerView, 0); - - mRecyclerView.setAdapter(headerAndFooterAdapter); - - } - - - private View getHeaderView(int type, View.OnClickListener listener) { - View view = getLayoutInflater().inflate(R.layout.head_view, (ViewGroup) mRecyclerView.getParent(), false); - if (type == 1) { - ImageView imageView = (ImageView) view.findViewById(R.id.iv); - imageView.setImageResource(R.mipmap.rm_icon); - } - view.setOnClickListener(listener); - return view; - } - - private View getFooterView(int type, View.OnClickListener listener) { - View view = getLayoutInflater().inflate(R.layout.footer_view, (ViewGroup) mRecyclerView.getParent(), false); - if (type == 1) { - ImageView imageView = (ImageView) view.findViewById(R.id.iv); - imageView.setImageResource(R.mipmap.rm_icon); - } - view.setOnClickListener(listener); - return view; - } - - private View.OnClickListener getRemoveHeaderListener() { - return new View.OnClickListener() { - @Override - public void onClick(View v) { - headerAndFooterAdapter.removeHeaderView(v); - } - }; - } - - - private View.OnClickListener getRemoveFooterListener() { - return new View.OnClickListener() { - @Override - public void onClick(View v) { - headerAndFooterAdapter.removeFooterView(v); - } - }; - } - - private void initAdapter() { - headerAndFooterAdapter = new HeaderAndFooterAdapter(PAGE_SIZE); - headerAndFooterAdapter.openLoadAnimation(); - mRecyclerView.setAdapter(headerAndFooterAdapter); -// mRecyclerView.addOnItemTouchListener(new OnItemClickListener() { -// @Override -// public void onSimpleItemClick(BaseQuickAdapter adapter, View view, int position) { -// Toast.makeText(HeaderAndFooterUseActivity.this, "" + Integer.toString(position), Toast.LENGTH_LONG).show(); -// } -// }); - headerAndFooterAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { - @Override - public void onItemClick(BaseQuickAdapter adapter, View view, int position) { - adapter.setNewData(DataServer.getSampleData(PAGE_SIZE)); - Toast.makeText(HeaderAndFooterUseActivity.this, "" + Integer.toString(position), Toast.LENGTH_LONG).show(); - } - }); - - } - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HomeActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HomeActivity.java deleted file mode 100644 index 1cfaa02a4..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/HomeActivity.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.content.Intent; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.GridLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.view.ViewGroup; - -import com.chad.baserecyclerviewadapterhelper.adapter.HomeAdapter; -import com.chad.baserecyclerviewadapterhelper.entity.HomeItem; -import com.chad.library.adapter.base.BaseQuickAdapter; - -import java.util.ArrayList; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class HomeActivity extends AppCompatActivity { - private static final Class[] ACTIVITY = {AnimationUseActivity.class, MultipleItemUseActivity.class, HeaderAndFooterUseActivity.class, PullToRefreshUseActivity.class, SectionUseActivity.class, EmptyViewUseActivity.class, ItemDragAndSwipeUseActivity.class, ItemClickActivity.class, ExpandableUseActivity.class, DataBindingUseActivity.class,UpFetchUseActivity.class}; - private static final String[] TITLE = {"Animation", "MultipleItem", "Header/Footer", "PullToRefresh", "Section", "EmptyView", "DragAndSwipe", "ItemClick", "ExpandableItem", "DataBinding", "UpFetchData"}; - private static final int[] IMG = {R.mipmap.gv_animation, R.mipmap.gv_multipleltem, R.mipmap.gv_header_and_footer, R.mipmap.gv_pulltorefresh, R.mipmap.gv_section, R.mipmap.gv_empty, R.mipmap.gv_drag_and_swipe, R.mipmap.gv_item_click, R.mipmap.gv_expandable, R.mipmap.gv_databinding,R.drawable.gv_up_fetch}; - private ArrayList mDataList; - private RecyclerView mRecyclerView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_home); - initView(); - initData(); - initAdapter(); - } - - private void initView() { - mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); - mRecyclerView.setLayoutManager(new GridLayoutManager(this, 2)); - } - - @SuppressWarnings("unchecked") - private void initAdapter() { - BaseQuickAdapter homeAdapter = new HomeAdapter(R.layout.home_item_view, mDataList); - homeAdapter.openLoadAnimation(); - View top = getLayoutInflater().inflate(R.layout.top_view, (ViewGroup) mRecyclerView.getParent(), false); - homeAdapter.addHeaderView(top); - homeAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { - @Override - public void onItemClick(BaseQuickAdapter adapter, View view, int position) { - Intent intent = new Intent(HomeActivity.this, ACTIVITY[position]); - startActivity(intent); - } - }); - - mRecyclerView.setAdapter(homeAdapter); - } - - private void initData() { - mDataList = new ArrayList<>(); - for (int i = 0; i < TITLE.length; i++) { - HomeItem item = new HomeItem(); - item.setTitle(TITLE[i]); - item.setActivity(ACTIVITY[i]); - item.setImageResource(IMG[i]); - mDataList.add(item); - } - } - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ItemClickActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ItemClickActivity.java deleted file mode 100644 index a8f97b1ea..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ItemClickActivity.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; -import android.widget.Toast; - -import com.chad.baserecyclerviewadapterhelper.adapter.ItemClickAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.entity.ClickEntity; -import com.chad.library.adapter.base.BaseQuickAdapter; - -import java.util.ArrayList; -import java.util.List; - -public class ItemClickActivity extends BaseActivity { - - private RecyclerView mRecyclerView; - private ItemClickAdapter adapter; - private static final int PAGE_SIZE = 10; - private static String TAG = "ItemClickActivity"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setBackBtn(); - setTitle("ItemClickActivity Activity"); - setContentView(R.layout.activity_item_click); - mRecyclerView = (RecyclerView) findViewById(R.id.list); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - initAdapter(); - adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { - @Override - public void onItemClick(BaseQuickAdapter adapter, View view, int position) { - Log.d(TAG, "onItemClick: "); - Toast.makeText(ItemClickActivity.this, "onItemClick" + position, Toast.LENGTH_SHORT).show(); - } - }); - adapter.setOnItemLongClickListener(new BaseQuickAdapter.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) { - Log.d(TAG, "onItemLongClick: "); - Toast.makeText(ItemClickActivity.this, "onItemLongClick" + position, Toast.LENGTH_SHORT).show(); - return true; - } - }); - adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() { - @Override - public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { - Log.d(TAG, "onItemChildClick: "); - Toast.makeText(ItemClickActivity.this, "onItemChildClick" + position, Toast.LENGTH_SHORT).show(); - } - }); - adapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() { - @Override - public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) { - Log.d(TAG, "onItemChildLongClick: "); - Toast.makeText(ItemClickActivity.this, "onItemChildLongClick" + position, Toast.LENGTH_SHORT).show(); - return true; - } - }); -/** - * you can also use this way to solve your click Event - */ -// mRecyclerView.addOnItemTouchListener(new OnItemClickListener() { -// /** -// * Callback method to be invoked when an item in this AdapterView has -// * been clicked. -// * -// * @param view The view within the AdapterView that was clicked (this -// * will be a view provided by the adapter) -// * @param position The position of the view in the adapter. -// */ -// @Override -// public void onSimpleItemClick(final BaseQuickAdapter adapter, final View view, final int position) { -// Log.d(TAG, "SimpleOnItemClick: "); -// -// } -// /** -// * callback method to be invoked when an chidview in this view has been -// * click and held -// * -// * @param view The view whihin the AbsListView that was clicked -// * @param position The position of the view int the adapter -// * @return true if the callback consumed the long click ,false otherwise -// */ -// @Override -// public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { -// Logger.d("onItemChildClick "+position+" be click"); -// Toast.makeText(ItemClickActivity.this, "onItemChildClick" + position, Toast.LENGTH_SHORT).show(); -// -// } -// -// /** -// * Callback method to be invoked when an item in this view has been clicked and held. -// * @param adapter -// * @param view -// * @param position -// */ -// @Override -// public void onItemLongClick(final BaseQuickAdapter adapter, final View view, final int position) { -// Toast.makeText(ItemClickActivity.this, "onItemLongClick" + position, Toast.LENGTH_SHORT).show(); -// } -// /** -// * Callback method to be invoked when an itemchild in this view has been clicked and held. -// * @param adapter -// * @param view -// * @param position -// */ -// @Override -// public void onItemChildLongClick(final BaseQuickAdapter adapter, final View view, final int position) { -// Toast.makeText(ItemClickActivity.this, "onItemChildLongClick" + position, Toast.LENGTH_SHORT).show(); -// } -// }); - - - } - - private void initAdapter() { - List data = new ArrayList<>(); - data.add(new ClickEntity(ClickEntity.CLICK_ITEM_VIEW)); - data.add(new ClickEntity(ClickEntity.CLICK_ITEM_CHILD_VIEW)); - data.add(new ClickEntity(ClickEntity.LONG_CLICK_ITEM_VIEW)); - data.add(new ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)); - data.add(new ClickEntity(ClickEntity.NEST_CLICK_ITEM_CHILD_VIEW)); - adapter = new ItemClickAdapter(data); - adapter.openLoadAnimation(); - mRecyclerView.setAdapter(adapter); - } - - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - return super.dispatchTouchEvent(ev); - } - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ItemDragAndSwipeUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ItemDragAndSwipeUseActivity.java deleted file mode 100644 index 9d9abcb52..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/ItemDragAndSwipeUseActivity.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.os.Bundle; -import android.support.v4.content.ContextCompat; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.helper.ItemTouchHelper; -import android.util.Log; -import android.view.View; - -import com.chad.baserecyclerviewadapterhelper.adapter.ItemDragAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.util.ToastUtils; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; -import com.chad.library.adapter.base.callback.ItemDragAndSwipeCallback; -import com.chad.library.adapter.base.listener.OnItemDragListener; -import com.chad.library.adapter.base.listener.OnItemSwipeListener; - -import java.util.ArrayList; -import java.util.List; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class ItemDragAndSwipeUseActivity extends BaseActivity { - private static final String TAG = ItemDragAndSwipeUseActivity.class.getSimpleName(); - private RecyclerView mRecyclerView; - private List mData; - private ItemDragAdapter mAdapter; - private ItemTouchHelper mItemTouchHelper; - private ItemDragAndSwipeCallback mItemDragAndSwipeCallback; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_item_touch_use); - setBackBtn(); - setTitle("ItemDrag And Swipe"); - mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - mData = generateData(50); - OnItemDragListener listener = new OnItemDragListener() { - @Override - public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos) { - Log.d(TAG, "drag start"); - BaseViewHolder holder = ((BaseViewHolder) viewHolder); -// holder.setTextColor(R.id.tv, Color.WHITE); - } - - @Override - public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) { - Log.d(TAG, "move from: " + source.getAdapterPosition() + " to: " + target.getAdapterPosition()); - } - - @Override - public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) { - Log.d(TAG, "drag end"); - BaseViewHolder holder = ((BaseViewHolder) viewHolder); -// holder.setTextColor(R.id.tv, Color.BLACK); - } - }; - final Paint paint = new Paint(); - paint.setAntiAlias(true); - paint.setTextSize(20); - paint.setColor(Color.BLACK); - OnItemSwipeListener onItemSwipeListener = new OnItemSwipeListener() { - @Override - public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) { - Log.d(TAG, "view swiped start: " + pos); - BaseViewHolder holder = ((BaseViewHolder) viewHolder); -// holder.setTextColor(R.id.tv, Color.WHITE); - } - - @Override - public void clearView(RecyclerView.ViewHolder viewHolder, int pos) { - Log.d(TAG, "View reset: " + pos); - BaseViewHolder holder = ((BaseViewHolder) viewHolder); -// holder.setTextColor(R.id.tv, Color.BLACK); - } - - @Override - public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) { - Log.d(TAG, "View Swiped: " + pos); - } - - @Override - public void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) { - canvas.drawColor(ContextCompat.getColor(ItemDragAndSwipeUseActivity.this, R.color.color_light_blue)); -// canvas.drawText("Just some text", 0, 40, paint); - } - }; - - mAdapter = new ItemDragAdapter(mData); - mItemDragAndSwipeCallback = new ItemDragAndSwipeCallback(mAdapter); - mItemTouchHelper = new ItemTouchHelper(mItemDragAndSwipeCallback); - mItemTouchHelper.attachToRecyclerView(mRecyclerView); - - //mItemDragAndSwipeCallback.setDragMoveFlags(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN); - mItemDragAndSwipeCallback.setSwipeMoveFlags(ItemTouchHelper.START | ItemTouchHelper.END); - mAdapter.enableSwipeItem(); - mAdapter.setOnItemSwipeListener(onItemSwipeListener); - mAdapter.enableDragItem(mItemTouchHelper); - mAdapter.setOnItemDragListener(listener); -// mRecyclerView.addItemDecoration(new GridItemDecoration(this ,R.drawable.list_divider)); - - mRecyclerView.setAdapter(mAdapter); -// mRecyclerView.addOnItemTouchListener(new OnItemClickListener() { -// @Override -// public void onSimpleItemClick(final BaseQuickAdapter adapter, final View view, final int position) { -// ToastUtils.showShortToast("点击了" + position); -// } -// }); - mAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { - @Override - public void onItemClick(BaseQuickAdapter adapter, View view, int position) { - ToastUtils.showShortToast("点击了" + position); - } - }); - } - - private List generateData(int size) { - ArrayList data = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - data.add("item " + i); - } - return data; - } - - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MultipleItemUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MultipleItemUseActivity.java deleted file mode 100644 index 9bbfd0606..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MultipleItemUseActivity.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.os.Bundle; -import android.support.v4.widget.DrawerLayout; -import android.support.v7.widget.GridLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.view.ViewGroup; - -import com.chad.baserecyclerviewadapterhelper.adapter.MultipleItemQuickAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.baserecyclerviewadapterhelper.entity.MultipleItem; -import com.chad.library.adapter.base.BaseQuickAdapter; - -import java.util.List; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - * modify by AllenCoder - */ -public class MultipleItemUseActivity extends BaseActivity { - private RecyclerView mRecyclerView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_multiple_item_use); - setTitle("MultipleItem Use"); - setBackBtn(); - mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); - final List data = DataServer.getMultipleItemData(); - final MultipleItemQuickAdapter multipleItemAdapter = new MultipleItemQuickAdapter(this, data); - final GridLayoutManager manager = new GridLayoutManager(this, 4); - mRecyclerView.setLayoutManager(manager); - multipleItemAdapter.setSpanSizeLookup(new BaseQuickAdapter.SpanSizeLookup() { - @Override - public int getSpanSize(GridLayoutManager gridLayoutManager, int position) { - return data.get(position).getSpanSize(); - } - }); - mRecyclerView.setAdapter(multipleItemAdapter); - } - - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.kt similarity index 52% rename from app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.java rename to app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.kt index 4d613a431..34f0255ae 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/MyApplication.kt @@ -12,13 +12,10 @@ **------------------------------------------------------------------------------ ********************************End of Head************************************\ */ -package com.chad.baserecyclerviewadapterhelper; +package com.chad.baserecyclerviewadapterhelper -import android.app.Application; - -import com.chad.baserecyclerviewadapterhelper.util.Utils; -import com.orhanobut.logger.AndroidLogAdapter; -import com.orhanobut.logger.Logger; +import android.app.Application +import com.chad.baserecyclerviewadapterhelper.utils.AppUtils /** * 文 件 名: MyApplication @@ -28,22 +25,9 @@ * 修改时间: * 修改备注: */ -public class MyApplication extends Application { - private static MyApplication appContext; - - public static MyApplication getInstance() { - return appContext; - } - - @Override - public void onCreate() { - super.onCreate(); - appContext = this; - Utils.init(this); - if (BuildConfig.DEBUG) { - Logger.addLogAdapter(new AndroidLogAdapter()); - - - } +class MyApplication : Application() { + override fun onCreate() { + super.onCreate() + AppUtils.init(this) } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/PullToRefreshUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/PullToRefreshUseActivity.java deleted file mode 100644 index b4397c148..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/PullToRefreshUseActivity.java +++ /dev/null @@ -1,215 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.graphics.Color; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.support.v4.widget.SwipeRefreshLayout; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import android.widget.Toast; - -import com.chad.baserecyclerviewadapterhelper.adapter.PullToRefreshAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.baserecyclerviewadapterhelper.entity.Status; -import com.chad.baserecyclerviewadapterhelper.loadmore.CustomLoadMoreView; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.listener.OnItemClickListener; - -import java.util.List; - - -interface RequestCallBack { - void success(List data); - - void fail(Exception e); -} - -class Request extends Thread { - private static final int PAGE_SIZE = 6; - private int mPage; - private RequestCallBack mCallBack; - private Handler mHandler; - - private static boolean mFirstPageNoMore; - private static boolean mFirstError = true; - - public Request(int page, RequestCallBack callBack) { - mPage = page; - mCallBack = callBack; - mHandler = new Handler(Looper.getMainLooper()); - } - - @Override - public void run() { - try {Thread.sleep(500);} catch (InterruptedException e) {} - - if (mPage == 2 && mFirstError) { - mFirstError = false; - mHandler.post(new Runnable() { - @Override - public void run() { - mCallBack.fail(new RuntimeException("fail")); - } - }); - } else { - int size = PAGE_SIZE; - if (mPage == 1) { - if (mFirstPageNoMore) { - size = 1; - } - mFirstPageNoMore = !mFirstPageNoMore; - if (!mFirstError) { - mFirstError = true; - } - } else if (mPage == 4) { - size = 1; - } - - final int dataSize = size; - mHandler.post(new Runnable() { - @Override - public void run() { - mCallBack.success(DataServer.getSampleData(dataSize)); - } - }); - } - } -} - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class PullToRefreshUseActivity extends BaseActivity { - - private static final int PAGE_SIZE = 6; - - private RecyclerView mRecyclerView; - private SwipeRefreshLayout mSwipeRefreshLayout; - private PullToRefreshAdapter mAdapter; - - private int mNextRequestPage = 1; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); - mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeLayout); - mSwipeRefreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189)); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - setTitle("Pull TO Refresh Use"); - setBackBtn(); - initAdapter(); - addHeadView(); - initRefreshLayout(); - mSwipeRefreshLayout.setRefreshing(true); - refresh(); - } - - private void initAdapter() { - mAdapter = new PullToRefreshAdapter(); - mAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() { - @Override - public void onLoadMoreRequested() { - loadMore(); - } - }); - mAdapter.openLoadAnimation(BaseQuickAdapter.SLIDEIN_LEFT); -// mAdapter.setPreLoadNumber(3); - mRecyclerView.setAdapter(mAdapter); - - mRecyclerView.addOnItemTouchListener(new OnItemClickListener() { - @Override - public void onSimpleItemClick(final BaseQuickAdapter adapter, final View view, final int position) { - Toast.makeText(PullToRefreshUseActivity.this, Integer.toString(position), Toast.LENGTH_LONG).show(); - } - }); - } - - private void addHeadView() { - View headView = getLayoutInflater().inflate(R.layout.head_view, (ViewGroup) mRecyclerView.getParent(), false); - headView.findViewById(R.id.iv).setVisibility(View.GONE); - ((TextView) headView.findViewById(R.id.tv)).setText("change load view"); - headView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - mAdapter.setNewData(null); - mAdapter.setLoadMoreView(new CustomLoadMoreView()); - mRecyclerView.setAdapter(mAdapter); - Toast.makeText(PullToRefreshUseActivity.this, "change complete", Toast.LENGTH_LONG).show(); - - mSwipeRefreshLayout.setRefreshing(true); - refresh(); - } - }); - mAdapter.addHeaderView(headView); - } - - private void initRefreshLayout() { - mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - refresh(); - } - }); - } - - private void refresh() { - mNextRequestPage = 1; - mAdapter.setEnableLoadMore(false);//这里的作用是防止下拉刷新的时候还可以上拉加载 - new Request(mNextRequestPage, new RequestCallBack() { - @Override - public void success(List data) { - setData(true, data); - mAdapter.setEnableLoadMore(true); - mSwipeRefreshLayout.setRefreshing(false); - } - - @Override - public void fail(Exception e) { - Toast.makeText(PullToRefreshUseActivity.this, R.string.network_err, Toast.LENGTH_LONG).show(); - mAdapter.setEnableLoadMore(true); - mSwipeRefreshLayout.setRefreshing(false); - } - }).start(); - } - - private void loadMore() { - new Request(mNextRequestPage, new RequestCallBack() { - @Override - public void success(List data) { - setData(false, data); - } - - @Override - public void fail(Exception e) { - mAdapter.loadMoreFail(); - Toast.makeText(PullToRefreshUseActivity.this, R.string.network_err, Toast.LENGTH_LONG).show(); - } - }).start(); - } - - private void setData(boolean isRefresh, List data) { - mNextRequestPage++; - final int size = data == null ? 0 : data.size(); - if (isRefresh) { - mAdapter.setNewData(data); - } else { - if (size > 0) { - mAdapter.addData(data); - } - } - if (size < PAGE_SIZE) { - //第一页如果不够一页就不显示没有更多数据布局 - mAdapter.loadMoreEnd(isRefresh); - Toast.makeText(this, "no more data", Toast.LENGTH_SHORT).show(); - } else { - mAdapter.loadMoreComplete(); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java deleted file mode 100644 index ae2987524..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.os.Bundle; -import android.support.v7.widget.GridLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.widget.Toast; - -import com.chad.baserecyclerviewadapterhelper.adapter.SectionAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.baserecyclerviewadapterhelper.entity.MySection; -import com.chad.library.adapter.base.BaseQuickAdapter; - -import java.util.List; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class SectionUseActivity extends BaseActivity { - private RecyclerView mRecyclerView; - private List mData; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_section_uer); - setBackBtn(); - setTitle("Section Use"); - mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); - mRecyclerView.setLayoutManager(new GridLayoutManager(this,2)); - mData = DataServer.getSampleData(); - SectionAdapter sectionAdapter = new SectionAdapter(R.layout.item_section_content, R.layout.def_section_head, mData); - - sectionAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() { - @Override - public void onItemClick(BaseQuickAdapter adapter, View view, int position) { - MySection mySection = mData.get(position); - if (mySection.isHeader) - Toast.makeText(SectionUseActivity.this, mySection.header, Toast.LENGTH_LONG).show(); - else - Toast.makeText(SectionUseActivity.this, mySection.t.getName(), Toast.LENGTH_LONG).show(); - } - }); - sectionAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() { - @Override - public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(SectionUseActivity.this, "onItemChildClick" + position, Toast.LENGTH_LONG).show(); - } - }); - mRecyclerView.setAdapter(sectionAdapter); - } - - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/UpFetchUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/UpFetchUseActivity.java deleted file mode 100644 index 22f9438e2..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/UpFetchUseActivity.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper; - -import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; - -import com.chad.baserecyclerviewadapterhelper.adapter.UpFetchAdapter; -import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; -import com.chad.baserecyclerviewadapterhelper.entity.Movie; -import com.chad.library.adapter.base.BaseQuickAdapter; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -/** - * Created by tysheng - * Date: 2017/5/25 10:41. - * Email: tyshengsx@gmail.com - */ - -public class UpFetchUseActivity extends BaseActivity { - RecyclerView mRecyclerView; - UpFetchAdapter mAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setBackBtn(); - setTitle("UpFetch Use"); - setContentView(R.layout.activity_data_binding_use); - - mRecyclerView = (RecyclerView) findViewById(R.id.rv); - mAdapter = new UpFetchAdapter(); - mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - mRecyclerView.setAdapter(mAdapter); - mAdapter.setNewData(genData()); - mAdapter.setUpFetchEnable(true); - /** - * start fetch when scroll to position 2, default is 1. - */ - mAdapter.setStartUpFetchPosition(2); - mAdapter.setUpFetchListener(new BaseQuickAdapter.UpFetchListener() { - @Override - public void onUpFetch() { - startUpFetch(); - } - }); - } - - private int count; - - private void startUpFetch() { - count++; - /** - * set fetching on when start network request. - */ - mAdapter.setUpFetching(true); - /** - * get data from internet. - */ - mRecyclerView.postDelayed(new Runnable() { - @Override - public void run() { - mAdapter.addData(0, genData()); - /** - * set fetching off when network request ends. - */ - mAdapter.setUpFetching(false); - /** - * set fetch enable false when you don't need anymore. - */ - if (count > 5) { - mAdapter.setUpFetchEnable(false); - } - } - }, 300); - } - - - private List genData() { - ArrayList list = new ArrayList<>(); - Random random = new Random(); - for (int i = 0; i < 10; i++) { - String name = "Chad"; - int price = random.nextInt(10) + 10; - int len = random.nextInt(80) + 60; - Movie movie = new Movie(name, len, price, "He was one of Australia's most distinguished artistes"); - list.add(movie); - } - return list; - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/WelcomeActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/WelcomeActivity.java similarity index 67% rename from app/src/main/java/com/chad/baserecyclerviewadapterhelper/WelcomeActivity.java rename to app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/WelcomeActivity.java index ec0f87a2b..491cbb8a3 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/WelcomeActivity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/WelcomeActivity.java @@ -1,9 +1,13 @@ -package com.chad.baserecyclerviewadapterhelper; +package com.chad.baserecyclerviewadapterhelper.activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; -import android.support.v7.app.AppCompatActivity; + +import androidx.appcompat.app.AppCompatActivity; + +import com.chad.baserecyclerviewadapterhelper.R; +import com.chad.baserecyclerviewadapterhelper.activity.home.HomeActivity; public class WelcomeActivity extends AppCompatActivity { @@ -14,10 +18,10 @@ protected void onCreate(Bundle savedInstanceState) { new Handler().postDelayed(new Runnable() { @Override public void run() { - Intent intent = new Intent(WelcomeActivity.this,HomeActivity.class); + Intent intent = new Intent(WelcomeActivity.this, HomeActivity.class); startActivity(intent); finish(); } - },2000); + }, 1000); } } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/AnimationUseActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/AnimationUseActivity.kt new file mode 100644 index 000000000..6d2f252e3 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/AnimationUseActivity.kt @@ -0,0 +1,88 @@ +package com.chad.baserecyclerviewadapterhelper.activity.animation + +import android.os.Bundle +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import com.chad.baserecyclerviewadapterhelper.activity.animation.adapter.AnimationAdapter +import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation1 +import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation2 +import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation3 +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityAnimationUseBinding +import com.chad.library.adapter4.BaseQuickAdapter + +/** + * https://github.com/CymChad/BaseRecyclerViewAdapterHelper + * + * + * modify by AllenCoder + */ +class AnimationUseActivity : BaseViewBindingActivity() { + + private val mAnimationAdapter: AnimationAdapter = AnimationAdapter().apply { + // 打开 Adapter 的动画 + animationEnable = true + // 是否是首次显示时候加载动画 + isAnimationFirstOnly = false + } + + override fun initBinding(): ActivityAnimationUseBinding { + return ActivityAnimationUseBinding.inflate(layoutInflater) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + viewBinding.titleBar.title = "Animation Use" + viewBinding.titleBar.setOnBackListener { finish() } + + viewBinding.rv.adapter = mAnimationAdapter + + initMenu() + } + + /** + * Init menu + * 初始化下拉菜单 + */ + private fun initMenu() { + viewBinding.spinner.setItems( + "AlphaIn", + "ScaleIn", + "SlideInBottom", + "SlideInLeft", + "SlideInRight", + "Custom1", + "Custom2", + "Custom3" + ) + viewBinding.spinner.setOnItemSelectedListener { _, position, _, _ -> + when (position) { + 0 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.AlphaIn) + 1 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.ScaleIn) + 2 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInBottom) + 3 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInLeft) + 4 -> mAnimationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.SlideInRight) + 5 -> mAnimationAdapter.itemAnimation = CustomAnimation1() + 6 -> mAnimationAdapter.itemAnimation = CustomAnimation2() + 7 -> mAnimationAdapter.itemAnimation = CustomAnimation3() + else -> {} + } + mAnimationAdapter.notifyDataSetChanged() + + } + + //init firstOnly state + viewBinding.switchButton.setOnCheckedChangeListener { _, isChecked -> + mAnimationAdapter.isAnimationFirstOnly = isChecked + mAnimationAdapter.notifyDataSetChanged() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/adapter/AnimationAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/adapter/AnimationAdapter.kt new file mode 100644 index 000000000..cd780526a --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/animation/adapter/AnimationAdapter.kt @@ -0,0 +1,73 @@ +package com.chad.baserecyclerviewadapterhelper.activity.animation.adapter + +import android.content.Context +import android.text.TextPaint +import android.text.style.ClickableSpan +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.core.text.buildSpannedString +import androidx.core.text.inSpans +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.data.DataServer +import com.chad.baserecyclerviewadapterhelper.entity.Status +import com.chad.baserecyclerviewadapterhelper.utils.ClickableMovementMethod +import com.chad.baserecyclerviewadapterhelper.utils.Tips +import com.chad.library.adapter4.BaseQuickAdapter +import com.chad.library.adapter4.viewholder.QuickViewHolder + +/** + * 文 件 名: AnimationAdapter + * 创 建 人: Allen + * 创建日期: 16/12/24 15:33 + * 邮 箱: AllenCoder@126.com + * 修改时间: + * 修改备注: + */ +class AnimationAdapter : + BaseQuickAdapter(DataServer.getSampleData(100)) { + override fun onCreateViewHolder( + context: Context, + parent: ViewGroup, + viewType: Int + ): QuickViewHolder { + return QuickViewHolder(R.layout.layout_animation, parent) + } + + override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: Status?) { + when (holder.layoutPosition % 3) { + 0 -> holder.setImageResource(R.id.img, R.mipmap.animation_img1) + 1 -> holder.setImageResource(R.id.img, R.mipmap.animation_img2) + 2 -> holder.setImageResource(R.id.img, R.mipmap.animation_img3) + else -> {} + } + holder.setText(R.id.tweetName, "Hoteis in Rio de Janeiro") + val msg = + "\"He was one of Australia's most of distinguished artistes, renowned for his portraits\"" + + + + holder.getView(R.id.tweetText).text = buildSpannedString { + append(msg) + inSpans(clickableSpan) { + append("landscapes and nedes") + } + } + holder.getView(R.id.tweetText).movementMethod = ClickableMovementMethod.getInstance() + holder.getView(R.id.tweetText).isFocusable = false + holder.getView(R.id.tweetText).isClickable = false + holder.getView(R.id.tweetText).isLongClickable = false + } + + private val clickableSpan: ClickableSpan = object : ClickableSpan() { + override fun onClick(widget: View) { + Tips.show("事件触发了 landscapes and nedes") + } + + override fun updateDrawState(ds: TextPaint) { + ds.color = ContextCompat.getColor(context, R.color.clickspan_color) + ds.isUnderlineText = true + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/DataBindingUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/DataBindingUseActivity.java new file mode 100644 index 000000000..fc6f0c21d --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/DataBindingUseActivity.java @@ -0,0 +1,85 @@ +package com.chad.baserecyclerviewadapterhelper.activity.databinding; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.graphics.Insets; +import androidx.core.view.OnApplyWindowInsetsListener; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.chad.baserecyclerviewadapterhelper.activity.databinding.adapter.DataBindingAdapter; +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity; +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding; +import com.chad.baserecyclerviewadapterhelper.entity.Movie; +import com.chad.baserecyclerviewadapterhelper.utils.Tips; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * @author limuyang + * @date 2019-12-05 + * @description + */ +public final class DataBindingUseActivity extends BaseViewBindingActivity { + + private final DataBindingAdapter adapter = new DataBindingAdapter(); + + @NonNull + @Override + public ActivityUniversalRecyclerBinding initBinding() { + return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater()); + } + + @Override + public void onPointerCaptureChanged(boolean hasCapture) { + super.onPointerCaptureChanged(hasCapture); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() { + @Override + public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) { + Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + getViewBinding().titleBar.updateFakeBarHeight(bar.top); + return insets; + } + }); + + getViewBinding().titleBar.setTitle("DataBinding Use"); + getViewBinding().titleBar.setOnBackListener(v -> finish()); + + + getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this)); + getViewBinding().rv.setAdapter(adapter); + + + //item 点击事件 + adapter.setOnItemClickListener((movieBaseQuickAdapter, view, position) -> { + Tips.show("onItemClick: " + position); + }); + + //设置数据 + adapter.submitList(genData()); + } + + private List genData() { + ArrayList list = new ArrayList<>(); + Random random = new Random(); + for (int i = 0; i < 10; i++) { + String name = "Chad " + i; + int price = random.nextInt(10) + 10; + int len = random.nextInt(80) + 60; + Movie movie = new Movie(name, len, price, "He was one of Australia's most distinguished artistes"); + list.add(movie); + } + return list; + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/adapter/DataBindingAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/adapter/DataBindingAdapter.java new file mode 100644 index 000000000..693cafcc6 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/databinding/adapter/DataBindingAdapter.java @@ -0,0 +1,42 @@ +package com.chad.baserecyclerviewadapterhelper.activity.databinding.adapter; + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.chad.baserecyclerviewadapterhelper.R; +import com.chad.baserecyclerviewadapterhelper.databinding.ItemMovieBinding; +import com.chad.baserecyclerviewadapterhelper.entity.Movie; +import com.chad.baserecyclerviewadapterhelper.entity.MoviePresenter; +import com.chad.library.adapter4.BaseQuickAdapter; +import com.chad.library.adapter4.viewholder.DataBindingHolder; + +/** + * @author: limuyang + * @date: 2019-12-05 + * @Description: DataBinding Adapter + * + */ +public class DataBindingAdapter extends BaseQuickAdapter> { + + private final MoviePresenter mPresenter = new MoviePresenter(); + + @NonNull + @Override + protected DataBindingHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { + return new DataBindingHolder<>(R.layout.item_movie, parent); + } + + @Override + protected void onBindViewHolder(@NonNull DataBindingHolder holder, int position, @Nullable Movie item) { + if (item == null) return; + + // 获取 Binding + ItemMovieBinding binding = holder.getBinding(); + binding.setMovie(item); + binding.setPresenter(mPresenter); + binding.executePendingBindings(); + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/DifferActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/DifferActivity.java new file mode 100644 index 000000000..fa80cec21 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/DifferActivity.java @@ -0,0 +1,150 @@ +package com.chad.baserecyclerviewadapterhelper.activity.differ; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.graphics.Insets; +import androidx.core.view.OnApplyWindowInsetsListener; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; + +import com.chad.baserecyclerviewadapterhelper.R; +import com.chad.baserecyclerviewadapterhelper.activity.differ.adapter.DiffUtilAdapter; +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity; +import com.chad.baserecyclerviewadapterhelper.data.DataServer; +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityDiffutilBinding; +import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by limuyang + * Date: 2019/7/14O + */ +public final class DifferActivity extends BaseViewBindingActivity { + + private final DiffUtilAdapter mAdapter = new DiffUtilAdapter(); + + @NonNull + @Override + public ActivityDiffutilBinding initBinding() { + return ActivityDiffutilBinding.inflate(getLayoutInflater()); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() { + @Override + public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) { + Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + getViewBinding().titleBar.updateFakeBarHeight(bar.top); + return insets; + } + }); + + getViewBinding().titleBar.setTitle("DiffUtil Use"); + getViewBinding().titleBar.setOnBackListener(v -> finish()); + + initRv(); + initClick(); + } + + @Override + protected void onStart() { + super.onStart(); + + // 增加延迟,模拟网络加载 + getViewBinding().diffRv.postDelayed(() -> mAdapter.submitList(DataServer.getDiffUtilDemoEntities()), 1500); + } + + + private void initRv() { + // 打开空布局功能 + mAdapter.setStateViewEnable(true); + // 传入 空布局 layout id + mAdapter.setStateViewLayout(this, R.layout.loading_view); + + getViewBinding().diffRv.setAdapter(mAdapter); + } + + private int idAdd = 0; + + private void initClick() { + getViewBinding().btnChange.setOnClickListener(v -> { + List newData = getNewList(); + mAdapter.submitList(newData); + }); + + getViewBinding().btnAdd.setOnClickListener(v -> { + mAdapter.add(2, new DiffEntity( + 1000 + idAdd, + "add - 😊😊Item " + 1000 + idAdd, + "Item " + 0 + " content have change (notifyItemChanged)", + "06-12")); + idAdd++; + }); + + getViewBinding().btnRemove.setOnClickListener(v -> { + if (2 >= mAdapter.getItems().size()) { + return; + } + mAdapter.removeAt(2); + }); + } + + + /** + * get new data + */ + private List getNewList() { + List list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + /* + Simulate deletion of data No. 1 and No. 3 + 模拟删除1号和3号数据 + */ + if (i == 1 || i == 3) { + continue; + } + + /* + Simulate modification title of data No. 0 + 模拟修改0号数据的title + */ + if (i == 0) { + list.add(new DiffEntity( + i, + "😊Item " + i, + "This item " + i + " content", + "06-12") + ); + continue; + } + + /* + Simulate modification content of data No. 4 + 模拟修改4号数据的content发生变化 + */ + if (i == 4) { + list.add(new DiffEntity( + i, + "Item " + i, + "Oh~~~~~~, Item " + i + " content have change", + "06-12") + ); + continue; + } + + list.add(new DiffEntity( + i, + "Item " + i, + "This item " + i + " content", + "06-12") + ); + } + return list; + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffEntityCallback.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffEntityCallback.java new file mode 100644 index 000000000..583d81d2d --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffEntityCallback.java @@ -0,0 +1,60 @@ +package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.DiffUtil; + +import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity; + +/** + * Create DiffCallback + */ +public class DiffEntityCallback extends DiffUtil.ItemCallback { + + /** + * Determine if it is the same item + *

+ * 判断是否是同一个item + * + * @param oldItem New data + * @param newItem old Data + * @return + */ + @Override + public boolean areItemsTheSame(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) { + return oldItem.getId() == newItem.getId(); + } + + /** + * When it is the same item, judge whether the content has changed. + *

+ * 当是同一个item时,再判断内容是否发生改变 + * + * @param oldItem New data + * @param newItem old Data + * @return + */ + @Override + public boolean areContentsTheSame(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) { + return oldItem.getTitle().equals(newItem.getTitle()) + && oldItem.getContent().equals(newItem.getContent()) + && oldItem.getDate().equals(newItem.getDate()); + } + + /** + * Optional implementation + * Implement this method if you need to precisely modify the content of a view. + * If this method is not implemented, or if null is returned, the entire item will be refreshed. + * + * 可选实现 + * 如果需要精确修改某一个view中的内容,请实现此方法。 + * 如果不实现此方法,或者返回null,将会直接刷新整个item。 + * + * @param oldItem Old data + * @param newItem New data + * @return Payload info. if return null, the entire item will be refreshed. + */ + @Override + public Object getChangePayload(@NonNull DiffEntity oldItem, @NonNull DiffEntity newItem) { + return null; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffUtilAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffUtilAdapter.java new file mode 100644 index 000000000..3b41a1c7d --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/differ/adapter/DiffUtilAdapter.java @@ -0,0 +1,36 @@ +package com.chad.baserecyclerviewadapterhelper.activity.differ.adapter; + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.chad.baserecyclerviewadapterhelper.R; +import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity; +import com.chad.library.adapter4.BaseQuickAdapter; +import com.chad.library.adapter4.viewholder.QuickViewHolder; + +/** + * Create adapter + */ +public class DiffUtilAdapter extends BaseQuickAdapter { + + public DiffUtilAdapter() { + super(new DiffEntityCallback()); + } + + + @NonNull + @Override + protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { + return new QuickViewHolder(R.layout.layout_animation, parent); + } + + @Override + protected void onBindViewHolder(@NonNull QuickViewHolder holder, int position, DiffEntity item) { + holder.setText(R.id.tweetName, item.getTitle()) + .setText(R.id.tweetText, item.getContent()) + .setText(R.id.tweetDate, item.getDate()); + } + +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DefaultDragAndSwipeActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DefaultDragAndSwipeActivity.kt new file mode 100644 index 000000000..f702ec80e --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DefaultDragAndSwipeActivity.kt @@ -0,0 +1,163 @@ +package com.chad.baserecyclerviewadapterhelper.activity.dragswipe + +import android.animation.ValueAnimator +import android.graphics.Canvas +import android.graphics.Color +import android.os.Build +import android.os.Bundle +import android.util.Log +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.DragAndSwipeAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding +import com.chad.baserecyclerviewadapterhelper.utils.Tips +import com.chad.baserecyclerviewadapterhelper.utils.vibrate +import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe +import com.chad.library.adapter4.dragswipe.listener.OnItemDragListener +import com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener +import com.chad.library.adapter4.viewholder.QuickViewHolder + +/** + * 默认实现拖动与侧滑效果 + * Drag and Drag effects are implemented by default + */ +class DefaultDragAndSwipeActivity : BaseViewBindingActivity() { + + private val mAdapter: DragAndSwipeAdapter = DragAndSwipeAdapter() + + private val quickDragAndSwipe = QuickDragAndSwipe() + .setDragMoveFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN or + ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) + .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) + + override fun initBinding(): ActivityUniversalRecyclerBinding = + ActivityUniversalRecyclerBinding.inflate(layoutInflater) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + viewBinding.titleBar.title = "Default Drag And Swipe" + viewBinding.titleBar.setOnBackListener { finish() } + + viewBinding.rv.layoutManager = GridLayoutManager(this,3) + viewBinding.rv.adapter = mAdapter + + val mData = generateData(50) + mAdapter.submitList(mData) + + // 拖拽监听 + val listener: OnItemDragListener = object : OnItemDragListener { + override fun onItemDragStart(viewHolder: RecyclerView.ViewHolder?, pos: Int) { + vibrate() + Log.d(TAG, "drag start") + val holder = viewHolder as QuickViewHolder? ?: return + // 开始时,item背景色变化,demo这里使用了一个动画渐变,使得自然 + val startColor = Color.WHITE + val endColor = Color.rgb(245, 245, 245) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val v = ValueAnimator.ofArgb(startColor, endColor) + v.addUpdateListener { animation: ValueAnimator -> + holder.itemView.setBackgroundColor( + animation.animatedValue as Int + ) + } + v.duration = 300 + v.start() + } + } + + override fun onItemDragMoving( + source: RecyclerView.ViewHolder, + from: Int, + target: RecyclerView.ViewHolder, + to: Int + ) { + Log.d( + TAG, + "move from: " + source.bindingAdapterPosition + " to: " + target.bindingAdapterPosition + ) + } + + override fun onItemDragEnd(viewHolder: RecyclerView.ViewHolder, pos: Int) { + Log.d(TAG, "drag end") + val holder = viewHolder as QuickViewHolder + // 结束时,item背景色变化,demo这里使用了一个动画渐变,使得自然 + val startColor = Color.rgb(245, 245, 245) + val endColor = Color.WHITE + // 动画 + val v = ValueAnimator.ofArgb(startColor, endColor) + v.addUpdateListener { animation: ValueAnimator -> + holder.itemView.setBackgroundColor( + animation.animatedValue as Int + ) + } + v.duration = 300 + v.start() + + mAdapter.items.forEach { + Log.d( + TAG, + "-------->> w 顺序 ${it} " + ) + } + + } + } + val swipeListener: OnItemSwipeListener = object : OnItemSwipeListener { + override fun onItemSwipeStart(viewHolder: RecyclerView.ViewHolder?, bindingAdapterPosition: Int) { + Log.d(TAG, "onItemSwipeStart") + } + + override fun onItemSwipeEnd(viewHolder: RecyclerView.ViewHolder, bindingAdapterPosition: Int) { + Log.d(TAG, "onItemSwipeEnd: " + bindingAdapterPosition) + } + + override fun onItemSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int, bindingAdapterPosition: Int) { + Log.d(TAG, "onItemSwiped") + } + + override fun onItemSwipeMoving( + canvas: Canvas, + viewHolder: RecyclerView.ViewHolder, + dX: Float, + dY: Float, + isCurrentlyActive: Boolean + ) { + Log.d(TAG, "onItemSwipeMoving") + } + } + + // 滑动事件 + quickDragAndSwipe.attachToRecyclerView(viewBinding.rv) + .setDataCallback(mAdapter) + .setItemDragListener(listener) + .setItemSwipeListener(swipeListener) + + // 点击事件 + mAdapter.setOnItemClickListener { adapter, view, position -> + Tips.show("点击了:$position") + } + } + + private fun generateData(size: Int): List { + val data = ArrayList(size) + for (i in 0 until size) { + data.add("item $i") + } + return data + } + + companion object { + private const val TAG = "Default Drag And Swipe" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeDifferActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeDifferActivity.kt new file mode 100644 index 000000000..7daefb848 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeDifferActivity.kt @@ -0,0 +1,164 @@ +package com.chad.baserecyclerviewadapterhelper.activity.dragswipe + +import android.animation.ValueAnimator +import android.graphics.Canvas +import android.graphics.Color +import android.os.Build +import android.os.Bundle +import android.util.Log +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.DiffDragAndSwipeAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.data.DataServer +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding +import com.chad.baserecyclerviewadapterhelper.utils.vibrate +import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe +import com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback +import com.chad.library.adapter4.dragswipe.listener.OnItemDragListener +import com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener +import com.chad.library.adapter4.viewholder.QuickViewHolder + +/** + * Created by limuyang + * Date: 2019/7/14O + * + * DiffAdapter DragAndSwipe + */ +class DragAndSwipeDifferActivity : BaseViewBindingActivity() { + + private var mAdapter: DiffDragAndSwipeAdapter = DiffDragAndSwipeAdapter() + + private var quickDragAndSwipe = QuickDragAndSwipe() + .setDragMoveFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN) + .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) + + override fun initBinding(): ActivityUniversalRecyclerBinding = + ActivityUniversalRecyclerBinding.inflate(layoutInflater) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + viewBinding.titleBar.title = "Diff Drag Swipe Use" + viewBinding.titleBar.setOnBackListener { finish() } + + viewBinding.rv.layoutManager = LinearLayoutManager(this) + initRv() + + initDrag() + } + + private fun initRv() { + viewBinding.rv.adapter = mAdapter + + mAdapter.submitList(DataServer.diffUtilDemoEntities) + } + + + private fun initDrag() { + // 拖拽监听 + val listener: OnItemDragListener = object : + OnItemDragListener { + override fun onItemDragStart(viewHolder: RecyclerView.ViewHolder?, pos: Int) { + vibrate() + Log.d(TAG, "drag start") + val holder = viewHolder as QuickViewHolder + // 开始时,item背景色变化,demo这里使用了一个动画渐变,使得自然 + val startColor = Color.WHITE + val endColor = Color.rgb(245, 245, 245) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val v = ValueAnimator.ofArgb(startColor, endColor) + v.addUpdateListener { animation: ValueAnimator -> + holder.itemView.setBackgroundColor( + animation.animatedValue as Int + ) + } + v.duration = 300 + v.start() + } + } + + override fun onItemDragMoving( + source: RecyclerView.ViewHolder, + from: Int, + target: RecyclerView.ViewHolder, + to: Int + ) { + Log.d( + TAG, "move from: " + source.bindingAdapterPosition + " to: " + target.bindingAdapterPosition + ) + } + + override fun onItemDragEnd(viewHolder: RecyclerView.ViewHolder, pos: Int) { + Log.d(TAG, "drag end") + val holder = viewHolder as QuickViewHolder + // 结束时,item背景色变化,demo这里使用了一个动画渐变,使得自然 + val startColor = Color.rgb(245, 245, 245) + val endColor = Color.WHITE + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + val v = ValueAnimator.ofArgb(startColor, endColor) + v.addUpdateListener { animation: ValueAnimator -> + holder.itemView.setBackgroundColor( + animation.animatedValue as Int + ) + } + v.duration = 300 + v.start() + } + } + } + + val swipeListener: OnItemSwipeListener = object : + OnItemSwipeListener { + override fun onItemSwipeStart(viewHolder: RecyclerView.ViewHolder?, bindingAdapterPosition: Int) { + Log.d(TAG, "onItemSwipeStart") + } + + override fun onItemSwipeEnd(viewHolder: RecyclerView.ViewHolder, bindingAdapterPosition: Int) { + Log.d(TAG, "onItemSwipeEnd") + } + + override fun onItemSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int, bindingAdapterPosition: Int) { + Log.d(TAG, "onItemSwiped") + } + + override fun onItemSwipeMoving( + canvas: Canvas, + viewHolder: RecyclerView.ViewHolder, + dX: Float, + dY: Float, + isCurrentlyActive: Boolean + ) { + Log.d(TAG, "onItemSwipeMoving") + } + } + + + + quickDragAndSwipe.attachToRecyclerView(viewBinding.rv) + .setDataCallback(object : DragAndSwipeDataCallback { + override fun dataMove(fromPosition: Int, toPosition: Int) { + mAdapter.swap(fromPosition, toPosition) + } + + override fun dataRemoveAt(position: Int) { + mAdapter.removeAt(position) + } + }) + .setItemDragListener(listener) + .setItemSwipeListener(swipeListener) + } + + companion object { + private const val TAG = "Diff Drag Swipe Use" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeUseActivity.java new file mode 100644 index 000000000..1365e5361 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/DragAndSwipeUseActivity.java @@ -0,0 +1,70 @@ +package com.chad.baserecyclerviewadapterhelper.activity.dragswipe; + + +import android.content.Intent; +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.core.graphics.Insets; +import androidx.core.view.OnApplyWindowInsetsListener; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.chad.baserecyclerviewadapterhelper.R; +import com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeAdapter; +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity; +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding; +import com.chad.baserecyclerviewadapterhelper.entity.HomeEntity; + +import java.util.ArrayList; + + +public class DragAndSwipeUseActivity extends BaseViewBindingActivity { + private final ArrayList homeItemData = new ArrayList<>(); + + @NonNull + @Override + public ActivityUniversalRecyclerBinding initBinding() { + return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater()); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() { + @Override + public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) { + Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + getViewBinding().titleBar.updateFakeBarHeight(bar.top); + return insets; + } + }); + + getViewBinding().titleBar.setTitle("Drag And Swipe"); + getViewBinding().titleBar.setOnBackListener(v -> finish()); + + // 设置数据 + homeItemData.add(new HomeEntity("Default Drag And Swipe", DefaultDragAndSwipeActivity.class, R.mipmap.gv_drag_and_swipe, "")); + homeItemData.add(new HomeEntity("Manual Drag And Swipe", ManualDragAndSwipeUseActivity.class, R.mipmap.gv_drag_and_swipe, "")); + homeItemData.add(new HomeEntity("Head Drag And Swipe", HeaderDragAndSwipeActivity.class, R.mipmap.gv_drag_and_swipe, "")); + homeItemData.add(new HomeEntity("Diff Drag And Swipe", DragAndSwipeDifferActivity.class, R.mipmap.gv_drag_and_swipe, "")); + + /* + * RV适配器 + */ + HomeAdapter mAdapter = new HomeAdapter(homeItemData); + + + getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this)); + getViewBinding().rv.setAdapter(mAdapter); + + mAdapter.setOnItemClickListener((adapter, view, position) -> { + HomeEntity item = adapter.getItems().get(position); + if (!item.isSection()) { + startActivity(new Intent(DragAndSwipeUseActivity.this, item.getActivity())); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipe.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipe.kt new file mode 100644 index 000000000..fd0732e88 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipe.kt @@ -0,0 +1,28 @@ +package com.chad.baserecyclerviewadapterhelper.activity.dragswipe + +import androidx.recyclerview.widget.ConcatAdapter +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.HeaderDragAndSwipeAdapter +import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe + +/** + * 重写拖拽类,根据itemType 设置某个类型的是否允许拖拽 + */ +class HeaderDragAndSwipe : QuickDragAndSwipe() { + + override fun getMovementFlags( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder + ): Int { + if (recyclerView.adapter is ConcatAdapter) { + val adapter = recyclerView.adapter as ConcatAdapter + val absoluteAdapter = + adapter.getWrappedAdapterAndPosition(viewHolder.absoluteAdapterPosition).first + if (absoluteAdapter is HeaderDragAndSwipeAdapter) { + return super.getMovementFlags(recyclerView, viewHolder) + } + return makeMovementFlags(0, 0) + } + return makeMovementFlags(0, 0) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipeActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipeActivity.kt new file mode 100644 index 000000000..16c44d011 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/HeaderDragAndSwipeActivity.kt @@ -0,0 +1,242 @@ +package com.chad.baserecyclerviewadapterhelper.activity.dragswipe + +import android.animation.ValueAnimator +import android.graphics.Color +import android.os.Build +import android.os.Bundle +import android.util.Log +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.LinearLayoutManager +import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.HeaderDragAndSwipeAdapter +import com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeTopHeaderAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding +import com.chad.baserecyclerviewadapterhelper.utils.vibrate +import com.chad.library.adapter4.QuickAdapterHelper +import com.chad.library.adapter4.dragswipe.setItemDragListener +import com.chad.library.adapter4.dragswipe.setItemSwipeListener +import com.chad.library.adapter4.loadState.LoadState.NotLoading +import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter +import com.chad.library.adapter4.viewholder.QuickViewHolder +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * 带头部局以及带加载下一页的,拖拽demo + */ +class HeaderDragAndSwipeActivity : BaseViewBindingActivity() { + + + private val pageInfo = PageInfo() + + internal class PageInfo { + var page = 0 + fun nextPage() { + page++ + } + + fun reset() { + page = 0 + } + + val isFirstPage: Boolean + get() = page == 0 + } + + var headerDragAndSwipe = HeaderDragAndSwipe() + .setDragMoveFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN) + .setSwipeMoveFlags(ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) + + private val mAdapter: HeaderDragAndSwipeAdapter = HeaderDragAndSwipeAdapter() + private lateinit var helper: QuickAdapterHelper + + override fun initBinding(): ActivityUniversalRecyclerBinding = + ActivityUniversalRecyclerBinding.inflate(layoutInflater) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + viewBinding.titleBar.title = "Head Drag And Swipe" + viewBinding.titleBar.setOnBackListener { finish() } + + viewBinding.rv.layoutManager = LinearLayoutManager(this) + + + helper = QuickAdapterHelper.Builder(mAdapter) + .setTrailingLoadStateAdapter( + object : TrailingLoadStateAdapter.OnTrailingListener { + override fun onLoad() { + loadMore() + } + + override fun onFailRetry() { + } + + override fun isAllowLoading(): Boolean { + return true + } + }) + .build() + .addBeforeAdapter(HomeTopHeaderAdapter()) + + headerDragAndSwipe.attachToRecyclerView(viewBinding.rv) + .setDataCallback(mAdapter) + .setItemDragListener( + onItemDragStart = { viewHolder, pos -> + Log.d(TAG, "drag start") + vibrate() + val holder = viewHolder as QuickViewHolder + // 开始时,item背景色变化,demo这里使用了一个动画渐变,使得自然 + val startColor = Color.WHITE + val endColor = Color.rgb(245, 245, 245) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + ValueAnimator.ofArgb(startColor, endColor).apply { + addUpdateListener { animation: ValueAnimator -> + holder.itemView.setBackgroundColor( + animation.animatedValue as Int + ) + } + duration = 300 + start() + } + } + }, + onItemDragMoving = { source, from, target, to -> + Log.d(TAG, "move from: $from to: $to") + }, + onItemDragEnd = { viewHolder, pos -> + Log.d(TAG, "drag end") + val holder = viewHolder as QuickViewHolder + // 结束时,item背景色变化,demo这里使用了一个动画渐变,使得自然 + val startColor = Color.rgb(245, 245, 245) + val endColor = Color.WHITE + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + ValueAnimator.ofArgb(startColor, endColor).apply { + addUpdateListener { animation: ValueAnimator -> + holder.itemView.setBackgroundColor( + animation.animatedValue as Int + ) + } + duration = 300 + start() + } + } + } + + ) + .setItemSwipeListener( + onItemSwipeStart = { viewHolder, pos -> + Log.d(TAG, "onItemSwipeStart") + }, + onItemSwipeMoving = { canvas, viewHolder, dX, dY, isCurrentlyActive -> + Log.d(TAG, "onItemSwipeMoving") + }, + onItemSwiped = { viewHolder, _, pos -> + Log.d(TAG, "onItemSwiped") + }, + onItemSwipeEnd = { viewHolder, pos -> + Log.d(TAG, "onItemSwipeEnd") + } + ) + viewBinding.rv.adapter = helper.adapter + loadMore() + } + + + private fun loadMore() { + Request(pageInfo.page, object : RequestCallBack { + override fun success(data: List) { + if (pageInfo.page == 0) { + mAdapter.submitList(data) + } else { + mAdapter.addAll(data) + } + + helper.trailingLoadState = NotLoading(false) + // page加一 + pageInfo.nextPage() + } + + override fun fail(e: Exception?) { + + } + + override fun end() { + helper.trailingLoadState = NotLoading(true) + } + }).loadMore() + } + + /** + * 模拟加载数据的类,不用特别关注 + */ + internal class Request( + private val mPage: Int, + private val mCallBack: RequestCallBack + ) { + + fun loadMore() { + GlobalScope.launch(Dispatchers.IO) { + if (mPage != 0) { + delay(1500) + } + withContext(Dispatchers.Main) { + val size = PAGE_SIZE + if (mPage == 3) { + mCallBack.end() + } else { + val starIndex = mPage.times(size) + mCallBack.success(generateData(starIndex, size)) + } + } + } + } + + private fun generateData(starIndex: Int, size: Int): List { + val data = java.util.ArrayList(size) + val endIndex = starIndex.plus(size) + for (i in starIndex until endIndex) { + data.add("item $i") + } + return data + } + + } + + internal interface RequestCallBack { + /** + * 模拟加载成功 + * + * @param data 数据 + */ + fun success(data: List) + + /** + * 模拟加载失败 + * + * @param e 错误信息 + */ + fun fail(e: Exception?) + + /** + * 模拟加载结束 + */ + fun end() + } + + companion object { + private const val PAGE_SIZE = 20 + private const val TAG = "Default Drag And Swipe" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/ManualDragAndSwipeUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/ManualDragAndSwipeUseActivity.java new file mode 100644 index 000000000..7fdaa9edd --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/ManualDragAndSwipeUseActivity.java @@ -0,0 +1,173 @@ +package com.chad.baserecyclerviewadapterhelper.activity.dragswipe; + +import android.animation.ValueAnimator; +import android.graphics.Canvas; +import android.graphics.Color; +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.graphics.Insets; +import androidx.core.view.OnApplyWindowInsetsListener; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter.DragAndSwipeAdapter; +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity; +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding; +import com.chad.baserecyclerviewadapterhelper.utils.Tips; +import com.chad.baserecyclerviewadapterhelper.utils.VibratorUtilsKt; +import com.chad.library.adapter4.QuickAdapterHelper; +import com.chad.library.adapter4.dragswipe.QuickDragAndSwipe; +import com.chad.library.adapter4.dragswipe.listener.OnItemDragListener; +import com.chad.library.adapter4.dragswipe.listener.OnItemSwipeListener; +import com.chad.library.adapter4.viewholder.QuickViewHolder; + +import java.util.ArrayList; +import java.util.List; + +/** + * 手动实现拖动与侧滑效果 + * Manual drag and Drag effects + */ +public class ManualDragAndSwipeUseActivity extends BaseViewBindingActivity { + + private final String TAG = "Manual Drag And Swipe"; + + private DragAndSwipeAdapter mAdapter; + private QuickAdapterHelper helper; + + QuickDragAndSwipe quickDragAndSwipe = new QuickDragAndSwipe() + .setDragMoveFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN) + .setSwipeMoveFlags(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) + .setItemViewSwipeEnabled(true) + .setLongPressDragEnabled(false);//关闭默认的长按拖拽功能,通过自定义长按事件进行拖拽 + + @NonNull + @Override + public ActivityUniversalRecyclerBinding initBinding() { + return ActivityUniversalRecyclerBinding.inflate(getLayoutInflater()); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ViewCompat.setOnApplyWindowInsetsListener(getViewBinding().getRoot(), new OnApplyWindowInsetsListener() { + @Override + public @NonNull WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat insets) { + Insets bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + getViewBinding().titleBar.updateFakeBarHeight(bar.top); + return insets; + } + }); + + getViewBinding().titleBar.setTitle("Manual Drag And Swipe"); + getViewBinding().titleBar.setOnBackListener(v -> finish()); + + + getViewBinding().rv.setLayoutManager(new LinearLayoutManager(this)); + + // 拖拽监听 + OnItemDragListener listener = new OnItemDragListener() { + @Override + public void onItemDragStart(@Nullable RecyclerView.ViewHolder viewHolder, int pos) { + VibratorUtilsKt.vibrate(getApplicationContext()); + Log.d(TAG, "drag start"); + final QuickViewHolder holder = ((QuickViewHolder) viewHolder); + if (holder == null) return; + // 开始时,item背景色变化,demo这里使用了一个动画渐变,使得自然 + int startColor = Color.WHITE; + int endColor = Color.rgb(245, 245, 245); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { + ValueAnimator v = ValueAnimator.ofArgb(startColor, endColor); + v.addUpdateListener(animation -> holder.itemView.setBackgroundColor((int) animation.getAnimatedValue())); + v.setDuration(300); + v.start(); + } + } + + @Override + public void onItemDragMoving(@NonNull RecyclerView.ViewHolder source, int from, @NonNull RecyclerView.ViewHolder target, int to) { + Log.d(TAG, "move from: " + source.getBindingAdapterPosition() + " to: " + target.getBindingAdapterPosition()); + } + + @Override + public void onItemDragEnd(@NonNull RecyclerView.ViewHolder viewHolder, int pos) { + Log.d(TAG, "drag end"); + final QuickViewHolder holder = ((QuickViewHolder) viewHolder); + // 结束时,item背景色变化,demo这里使用了一个动画渐变,使得自然 + int startColor = Color.rgb(245, 245, 245); + int endColor = Color.WHITE; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { + ValueAnimator v = ValueAnimator.ofArgb(startColor, endColor); + v.addUpdateListener(animation -> holder.itemView.setBackgroundColor((int) animation.getAnimatedValue())); + v.setDuration(300); + v.start(); + } + } + }; + + OnItemSwipeListener swipeListener = new OnItemSwipeListener() { + @Override + public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int bindingAdapterPosition) { + Log.d(TAG, "onItemSwipeStart"); + } + + @Override + public void onItemSwipeEnd(@NonNull RecyclerView.ViewHolder viewHolder, int bindingAdapterPosition) { + Log.d(TAG, "onItemSwipeEnd " + bindingAdapterPosition); + } + + @Override + public void onItemSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction, int bindingAdapterPosition) { + Log.d(TAG, "onItemSwiped"); + } + + @Override + public void onItemSwipeMoving(@NonNull Canvas canvas, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) { + Log.d(TAG, "onItemSwipeMoving"); + } + }; + + List mData = generateData(50); + mAdapter = new DragAndSwipeAdapter(); + helper = new QuickAdapterHelper.Builder(mAdapter) + .build(); + getViewBinding().rv.setAdapter(helper.getAdapter()); + mAdapter.submitList(mData); + quickDragAndSwipe.attachToRecyclerView(getViewBinding().rv) + .setDataCallback(mAdapter) + .setItemDragListener(listener) + .setItemSwipeListener(swipeListener); + mAdapter.setOnItemClickListener((adapter, view, position) -> { + Tips.show("点击了:" + position + ",侧滑可进行删除" + position); + quickDragAndSwipe.startSwipe(position); + }); + mAdapter.setOnItemLongClickListener((adapter, view, position) -> { + /* + * 长按默认可拖动,可不进行设置此方法 + * 此方法可以做特殊使用进行调用 + * 如:长按此条position对应的item,触发 position+1 对应的item + * 此处使用,关闭了默认长按拖拽功能 + */ + Tips.show("长按了:" + position + ",现在拖动可进行变换位置"); + quickDragAndSwipe.startDrag(position); + return false; + }); + } + + private List generateData(int size) { + ArrayList data = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + data.add("item " + i); + } + return data; + } +} + + diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DiffDragAndSwipeAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DiffDragAndSwipeAdapter.kt new file mode 100644 index 000000000..386436e3e --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DiffDragAndSwipeAdapter.kt @@ -0,0 +1,32 @@ +package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter + +import android.content.Context +import android.view.ViewGroup +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.activity.differ.adapter.DiffEntityCallback +import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity +import com.chad.library.adapter4.BaseQuickAdapter +import com.chad.library.adapter4.viewholder.QuickViewHolder + +/** + * Create adapter + */ +class DiffDragAndSwipeAdapter : + BaseQuickAdapter(DiffEntityCallback()) { + + override fun onCreateViewHolder( + context: Context, parent: ViewGroup, viewType: Int + ): QuickViewHolder { + return QuickViewHolder(R.layout.layout_animation, parent) + } + + override fun onBindViewHolder( + holder: QuickViewHolder, position: Int, item: DiffEntity? + ) { + if (item == null) return + + holder.setText(R.id.tweetName, item.title) + .setText(R.id.tweetText, item.content) + .setText(R.id.tweetDate, item.date) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DragAndSwipeAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DragAndSwipeAdapter.java new file mode 100644 index 000000000..95b77bf4c --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/DragAndSwipeAdapter.java @@ -0,0 +1,43 @@ +package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter; + + +import android.content.Context; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import com.chad.baserecyclerviewadapterhelper.R; +import com.chad.library.adapter4.BaseQuickAdapter; +import com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback; +import com.chad.library.adapter4.viewholder.QuickViewHolder; + +public class DragAndSwipeAdapter extends BaseQuickAdapter implements DragAndSwipeDataCallback { + + @NonNull + @Override + protected QuickViewHolder onCreateViewHolder(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { + return new QuickViewHolder(R.layout.item_draggable_view, parent); + } + + @Override + protected void onBindViewHolder(@NonNull QuickViewHolder holder, int position, String item) { + switch (holder.getLayoutPosition() % 3) { + case 0 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img0); + case 1 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img1); + case 2 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img2); + default -> { + } + } + holder.setText(R.id.tv, item); + } + + @Override + public void dataMove(int fromPosition, int toPosition) { + move(fromPosition, toPosition); + } + + @Override + public void dataRemoveAt(int position) { + removeAt(position); + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/HeaderDragAndSwipeAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/HeaderDragAndSwipeAdapter.kt new file mode 100644 index 000000000..f5d5f561b --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/dragswipe/adapter/HeaderDragAndSwipeAdapter.kt @@ -0,0 +1,41 @@ +package com.chad.baserecyclerviewadapterhelper.activity.dragswipe.adapter + +import android.content.Context +import android.view.ViewGroup +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.library.adapter4.BaseQuickAdapter +import com.chad.library.adapter4.viewholder.QuickViewHolder +import com.chad.library.adapter4.dragswipe.listener.DragAndSwipeDataCallback + +/** + * kotlin方式集成案例 + */ +open class HeaderDragAndSwipeAdapter : BaseQuickAdapter(), + DragAndSwipeDataCallback { + + override fun onCreateViewHolder( + context: Context, + parent: ViewGroup, + viewType: Int + ): QuickViewHolder { + return QuickViewHolder(R.layout.item_draggable_view, parent) + } + + override fun onBindViewHolder(holder: QuickViewHolder, position: Int, item: String?) { + when (holder.layoutPosition % 3) { + 0 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img0) + 1 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img1) + 2 -> holder.setImageResource(R.id.iv_head, R.mipmap.head_img2) + else -> {} + } + holder.setText(R.id.tv, item) + } + + override fun dataMove(fromPosition: Int, toPosition: Int) { + move(fromPosition, toPosition) + } + + override fun dataRemoveAt(position: Int) { + removeAt(position) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/EmptyViewUseActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/EmptyViewUseActivity.kt new file mode 100644 index 000000000..e70413057 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/EmptyViewUseActivity.kt @@ -0,0 +1,91 @@ +package com.chad.baserecyclerviewadapterhelper.activity.emptyview + +import android.os.Bundle +import android.view.View +import android.widget.FrameLayout +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.StaggeredGridLayoutManager +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.activity.emptyview.adapter.EmptyViewAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.data.DataServer +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityEmptyViewUseBinding + +class EmptyViewUseActivity : BaseViewBindingActivity() { + + private val mAdapter = EmptyViewAdapter() + + private var mError = true + private var mNoData = true + + override fun initBinding(): ActivityEmptyViewUseBinding = + ActivityEmptyViewUseBinding.inflate(layoutInflater) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + viewBinding.titleBar.title = "EmptyView Use" + viewBinding.titleBar.setOnBackListener { finish() } + + viewBinding.btnReset.setOnClickListener { reset() } + + viewBinding.rvList.adapter = mAdapter + viewBinding.rvList.layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL) + + // 打开空布局功能 + mAdapter.isStateViewEnable = true + mAdapter.isUseStateViewSize = true + + onRefresh() + } + + private fun reset() { + mError = true + mNoData = true + mAdapter.submitList(null) + onRefresh() + } + + private val emptyDataView: View + get() { + val notDataView = layoutInflater.inflate(R.layout.empty_view, FrameLayout(this), false) + notDataView.setOnClickListener { onRefresh() } + return notDataView + } + + private val errorView: View + get() { + val errorView = layoutInflater.inflate(R.layout.error_view, FrameLayout(this), false) + errorView.setOnClickListener { onRefresh() } + return errorView + } + + private fun onRefresh() { + // 方式一:直接传入 layout id + mAdapter.setStateViewLayout(this, R.layout.loading_view) + + viewBinding.rvList.postDelayed({ + if (mError) { // 模拟网络错误 + // 方式二:传入View + mAdapter.stateView = errorView + + mError = false + } else { + if (mNoData) { // 模拟接口没有数据 + mAdapter.stateView = emptyDataView + mNoData = false + } else { + // 模拟正常数据返回 + mAdapter.submitList(DataServer.getSampleData(10)) + } + } + }, 1000) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/adapter/EmptyViewAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/adapter/EmptyViewAdapter.kt new file mode 100644 index 000000000..b61e79a4b --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/emptyview/adapter/EmptyViewAdapter.kt @@ -0,0 +1,31 @@ +package com.chad.baserecyclerviewadapterhelper.activity.emptyview.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.databinding.LayoutAnimationBinding +import com.chad.baserecyclerviewadapterhelper.entity.Status +import com.chad.library.adapter4.BaseQuickAdapter + +class EmptyViewAdapter : BaseQuickAdapter() { + + class VH( + parent: ViewGroup, + val binding: LayoutAnimationBinding = LayoutAnimationBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ), + ) : RecyclerView.ViewHolder(binding.root) + + override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { + return VH(parent) + } + + override fun onBindViewHolder(holder: VH, position: Int, item: Status?) { + if (item == null) return + holder.binding.img.setImageResource(item.userAvatar) + holder.binding.tweetName.text = item.userName + holder.binding.tweetText.text = "O ever youthful,O ever weeping" + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/HeaderAndFooterUseActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/HeaderAndFooterUseActivity.kt new file mode 100644 index 000000000..f9175549a --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/HeaderAndFooterUseActivity.kt @@ -0,0 +1,76 @@ +package com.chad.baserecyclerviewadapterhelper.activity.headerfooter + +import android.os.Bundle +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.LinearLayoutManager +import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.FooterAdapter +import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter +import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAndFooterAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.data.DataServer +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding +import com.chad.baserecyclerviewadapterhelper.utils.Tips +import com.chad.library.adapter4.QuickAdapterHelper + +/** + * https://github.com/CymChad/BaseRecyclerViewAdapterHelper + */ +class HeaderAndFooterUseActivity : BaseViewBindingActivity() { + + private lateinit var helper: QuickAdapterHelper + + override fun initBinding(): ActivityUniversalRecyclerBinding = + ActivityUniversalRecyclerBinding.inflate(layoutInflater) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + viewBinding.titleBar.title = "Header And Footer Use" + viewBinding.titleBar.setOnBackListener { finish() } + + + val adapter = HeaderAndFooterAdapter(DataServer.getSampleData(PAGE_SIZE)) + adapter.setOnItemClickListener { _, _, position -> + Tips.show("position: $position") + } + + + helper = QuickAdapterHelper.Builder(adapter) + .build() + + viewBinding.rv.layoutManager = LinearLayoutManager(this) + viewBinding.rv.adapter = helper.adapter + addHeader() + + helper.addAfterAdapter( + FooterAdapter(false).setOnItemClickListener { _, _, _ -> + addFooter() + } + ) + } + + private fun addHeader() { + helper.addBeforeAdapter(0, HeaderAdapter().apply { + setOnItemClickListener { _, _, _ -> + addHeader() + } + }) + } + + private fun addFooter() { + helper.addAfterAdapter(FooterAdapter(true).setOnItemClickListener{ adapter, _, _ -> + helper.removeAdapter(adapter) + }) + } + + companion object { + private const val PAGE_SIZE = 3 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/FooterAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/FooterAdapter.kt new file mode 100644 index 000000000..5d4e0830a --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/FooterAdapter.kt @@ -0,0 +1,22 @@ +package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter + +import android.content.Context +import android.view.ViewGroup +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.library.adapter4.BaseSingleItemAdapter +import com.chad.library.adapter4.viewholder.QuickViewHolder + +class FooterAdapter( + private val isDelete: Boolean +) : BaseSingleItemAdapter() { + + override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): QuickViewHolder { + return QuickViewHolder(R.layout.footer_view, parent) + } + + override fun onBindViewHolder(holder: QuickViewHolder, item: Any?) { + if (isDelete) { + holder.setImageResource(R.id.iv, R.mipmap.rm_icon) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAdapter.kt new file mode 100644 index 000000000..a09207776 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAdapter.kt @@ -0,0 +1,23 @@ +package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.library.adapter4.BaseSingleItemAdapter + +class HeaderAdapter: BaseSingleItemAdapter() { + + class VH(view: View): RecyclerView.ViewHolder(view) + + override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { + val view = LayoutInflater.from(parent.context).inflate(R.layout.head_view, parent, false) + return VH(view) + } + + override fun onBindViewHolder(holder: VH, item: Any?) { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAndFooterAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAndFooterAdapter.kt new file mode 100644 index 000000000..aabb6f447 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/headerfooter/adapter/HeaderAndFooterAdapter.kt @@ -0,0 +1,34 @@ +package com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.databinding.ItemHeaderAndFooterBinding +import com.chad.baserecyclerviewadapterhelper.entity.Status +import com.chad.library.adapter4.BaseQuickAdapter + +/** + * https://github.com/CymChad/BaseRecyclerViewAdapterHelper + */ +class HeaderAndFooterAdapter(list: List) : + BaseQuickAdapter(list) { + + class VH(var binding: ItemHeaderAndFooterBinding) : RecyclerView.ViewHolder(binding.root) + + override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { + val binding = + ItemHeaderAndFooterBinding.inflate(LayoutInflater.from(context), parent, false) + return VH(binding) + } + + override fun onBindViewHolder(holder: VH, position: Int, item: Status?) { + when (holder.layoutPosition % 3) { + 0 -> holder.binding.iv.setImageResource(R.mipmap.animation_img1) + 1 -> holder.binding.iv.setImageResource(R.mipmap.animation_img2) + 2 -> holder.binding.iv.setImageResource(R.mipmap.animation_img3) + else -> {} + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/HomeActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/HomeActivity.kt new file mode 100644 index 000000000..6032cee93 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/HomeActivity.kt @@ -0,0 +1,99 @@ +package com.chad.baserecyclerviewadapterhelper.activity.home + +import android.content.Intent +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.activity.animation.AnimationUseActivity +import com.chad.baserecyclerviewadapterhelper.activity.databinding.DataBindingUseActivity +import com.chad.baserecyclerviewadapterhelper.activity.differ.DifferActivity +import com.chad.baserecyclerviewadapterhelper.activity.dragswipe.DragAndSwipeUseActivity +import com.chad.baserecyclerviewadapterhelper.activity.emptyview.EmptyViewUseActivity +import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.HeaderAndFooterUseActivity +import com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeAdapter +import com.chad.baserecyclerviewadapterhelper.activity.home.adapter.HomeTopHeaderAdapter +import com.chad.baserecyclerviewadapterhelper.activity.itemclick.ItemClickActivity +import com.chad.baserecyclerviewadapterhelper.activity.loadmore.AutoLoadMoreRefreshUseActivity +import com.chad.baserecyclerviewadapterhelper.activity.loadmore.NoAutoAutoLoadMoreRefreshUseActivity +import com.chad.baserecyclerviewadapterhelper.activity.node.NodeActivity +import com.chad.baserecyclerviewadapterhelper.activity.scene.GroupDemoActivity +import com.chad.baserecyclerviewadapterhelper.activity.upfetch.UpFetchUseActivity +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityHomeBinding +import com.chad.baserecyclerviewadapterhelper.entity.HomeEntity +import com.chad.library.adapter4.BaseQuickAdapter +import com.chad.library.adapter4.QuickAdapterHelper + +class HomeActivity : AppCompatActivity(), BaseQuickAdapter.OnItemClickListener { + + private lateinit var binding: ActivityHomeBinding + + /** + * RV适配器 + */ + private val homeAdapter by lazy(LazyThreadSafetyMode.NONE) { + HomeAdapter(homeItemData) + } + + private val helper by lazy(LazyThreadSafetyMode.NONE) { + QuickAdapterHelper.Builder(homeAdapter) + .build() + .addBeforeAdapter(HomeTopHeaderAdapter()) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityHomeBinding.inflate(layoutInflater) + setContentView(binding.root) + + // 从 QuickAdapterHelper 获取 adapter,设置给 RecycleView + binding.recyclerView.adapter = helper.adapter + + // 设置点击事件 + homeAdapter.setOnItemClickListener(this) + } + + /** + * item 点击事件 + * + * @param adapter + * @param view + * @param position + */ + override fun onClick( + adapter: BaseQuickAdapter, + view: View, + position: Int, + ) { + val item = adapter.getItem(position) + if (!item.isSection) { + startActivity(Intent(this@HomeActivity, item.activity)) + } + } + + private val homeItemData: ArrayList + get() = arrayListOf( + HomeEntity(sectionTitle = "BaseQuickAdapter 基础功能"), + HomeEntity("Animation", AnimationUseActivity::class.java, R.mipmap.gv_animation), + HomeEntity( + "Header/Footer", + HeaderAndFooterUseActivity::class.java, + R.mipmap.gv_header_and_footer + ), + HomeEntity("EmptyView", EmptyViewUseActivity::class.java, R.mipmap.gv_empty), + HomeEntity("ItemClick", ItemClickActivity::class.java, R.mipmap.gv_item_click), + HomeEntity("DataBinding", DataBindingUseActivity::class.java, R.mipmap.gv_databinding), + HomeEntity("DiffUtil", DifferActivity::class.java, R.mipmap.gv_databinding), + HomeEntity("Multi-node", NodeActivity::class.java, R.mipmap.gv_databinding), +// + HomeEntity(sectionTitle = "功能模块"), + HomeEntity("LoadMore(Auto)", AutoLoadMoreRefreshUseActivity::class.java, R.mipmap.gv_pulltorefresh), + HomeEntity("LoadMore", NoAutoAutoLoadMoreRefreshUseActivity::class.java, R.mipmap.gv_pulltorefresh), + HomeEntity("DragAndSwipe", DragAndSwipeUseActivity::class.java, R.mipmap.gv_drag_and_swipe), + HomeEntity("UpFetch", UpFetchUseActivity::class.java, R.drawable.gv_up_fetch), + + + HomeEntity(sectionTitle = "场景演示"), + HomeEntity("Group(ConcatAdapter)", GroupDemoActivity::class.java, R.mipmap.gv_animation), + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeAdapter.kt new file mode 100644 index 000000000..ff07fe740 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeAdapter.kt @@ -0,0 +1,66 @@ +package com.chad.baserecyclerviewadapterhelper.activity.home.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.databinding.DefSectionHeadBinding +import com.chad.baserecyclerviewadapterhelper.databinding.HomeItemViewBinding +import com.chad.baserecyclerviewadapterhelper.entity.HomeEntity +import com.chad.library.adapter4.BaseMultiItemAdapter + +/** + * https://github.com/CymChad/BaseRecyclerViewAdapterHelper + */ +class HomeAdapter(data: List) : BaseMultiItemAdapter(data) { + + class ItemVH(val viewBinding: HomeItemViewBinding) : RecyclerView.ViewHolder(viewBinding.root) + + class HeaderVH(val viewBinding: DefSectionHeadBinding) : RecyclerView.ViewHolder(viewBinding.root) + + init { + addItemType(ITEM_TYPE, object : OnMultiItemAdapterListener { + override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): ItemVH { + val viewBinding = + HomeItemViewBinding.inflate(LayoutInflater.from(context), parent, false) + return ItemVH(viewBinding) + } + + override fun onBind(holder: ItemVH, position: Int, item: HomeEntity?) { + if (item == null) return + holder.viewBinding.textView.text = item.name + holder.viewBinding.icon.setImageResource(item.imageResource) + } + }).addItemType(SECTION_TYPE, object : OnMultiItemAdapterListener { + override fun onCreate(context: Context, parent: ViewGroup, viewType: Int): HeaderVH { + val viewBinding = + DefSectionHeadBinding.inflate(LayoutInflater.from(context), parent, false) + return HeaderVH(viewBinding) + } + + override fun onBind(holder: HeaderVH, position: Int, item: HomeEntity?) { + if (item == null) return + + holder.viewBinding.more.visibility = View.GONE + holder.viewBinding.header.text = item.sectionTitle + } + + override fun isFullSpanItem(itemType: Int): Boolean { + return true + } + + }).onItemViewType { position, list -> + if (list[position].isSection) { + SECTION_TYPE + } else { + ITEM_TYPE + } + } + } + + companion object { + private const val ITEM_TYPE = 10 + private const val SECTION_TYPE = 11 + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeTopHeaderAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeTopHeaderAdapter.kt new file mode 100644 index 000000000..e9f14dc01 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/home/adapter/HomeTopHeaderAdapter.kt @@ -0,0 +1,33 @@ +package com.chad.baserecyclerviewadapterhelper.activity.home.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.library.adapter4.BaseSingleItemAdapter +import com.chad.library.adapter4.fullspan.FullSpanAdapterType + +class HomeTopHeaderAdapter : BaseSingleItemAdapter(), + FullSpanAdapterType { + + companion object { + val HEAD_VIEWTYPE = 0x10000556 + } + + class VH(view: View) : RecyclerView.ViewHolder(view) + + override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { + return VH(LayoutInflater.from(parent.context).inflate(R.layout.top_view, parent, false)) + } + + override fun onBindViewHolder(holder: VH, item: Any?) { + } + + override fun getItemViewType(position: Int, list: List): Int { + return HEAD_VIEWTYPE + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/ItemClickActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/ItemClickActivity.kt new file mode 100644 index 000000000..3346b936e --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/ItemClickActivity.kt @@ -0,0 +1,98 @@ +package com.chad.baserecyclerviewadapterhelper.activity.itemclick + +import android.os.Bundle +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.LinearLayoutManager +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.activity.itemclick.adapter.ItemClickAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding +import com.chad.baserecyclerviewadapterhelper.entity.ClickEntity +import com.chad.baserecyclerviewadapterhelper.utils.Tips +import com.chad.library.adapter4.util.addOnDebouncedChildClick +import com.chad.library.adapter4.util.setOnDebouncedItemClick + +/** + * @author Allen + */ +class ItemClickActivity : BaseViewBindingActivity() { + + private val adapter: ItemClickAdapter by lazy(LazyThreadSafetyMode.NONE) { + // 创建数据 + val data = ArrayList().apply { + add(ClickEntity(ClickEntity.CLICK_ITEM_VIEW)) + add(ClickEntity(ClickEntity.CLICK_ITEM_CHILD_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)) + add(ClickEntity(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW)) + } + // 创建Adapter + ItemClickAdapter(data) + } + + override fun initBinding(): ActivityUniversalRecyclerBinding = + ActivityUniversalRecyclerBinding.inflate(layoutInflater) + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + viewBinding.titleBar.title = "Item Click Use" + viewBinding.titleBar.setOnBackListener { finish() } + viewBinding.rv.layoutManager = LinearLayoutManager(this) + viewBinding.rv.adapter = adapter + + // 设置点击事件 + adapter.setOnItemClickListener { _, _, position -> + Tips.show("onItemClick $position") + } + // 去除点击抖动的扩展方法 + adapter.setOnDebouncedItemClick {adapter, view, position -> + Tips.show("onItemClick $position") + } + + // 设置item 长按事件 + adapter.setOnItemLongClickListener { _, _, position -> + Tips.show("onItemLongClick $position") + true + } + + // 添加子 view 的点击事件 + adapter.addOnItemChildClickListener(R.id.btn) { adapter, view, position -> + Tips.show("onItemChildClick: $position") + } + adapter.addOnItemChildClickListener(R.id.iv_num_reduce) { adapter, view, position -> + Tips.show("onItemChildClick: reduce $position") + } + adapter.addOnItemChildClickListener(R.id.iv_num_add) { adapter, view, position -> + Tips.show("onItemChildClick: add $position") + adapter.removeAt(position) + } + + // 添加子 view 的点击事件(去除点击抖动的扩展方法) + adapter.addOnDebouncedChildClick(R.id.btn) { adapter, view, position -> + Tips.show("onItemChildClick: $position") + } + + // 设置子 view 长按事件 + adapter.addOnItemChildLongClickListener(R.id.btn_long) { adapter, view, position -> + Tips.show("onItemChildLongClick $position") + true + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/adapter/ItemClickAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/adapter/ItemClickAdapter.java new file mode 100755 index 000000000..f49a4853c --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/itemclick/adapter/ItemClickAdapter.java @@ -0,0 +1,147 @@ +package com.chad.baserecyclerviewadapterhelper.activity.itemclick.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.chad.baserecyclerviewadapterhelper.databinding.ItemClickChildviewBinding; +import com.chad.baserecyclerviewadapterhelper.databinding.ItemClickViewBinding; +import com.chad.baserecyclerviewadapterhelper.databinding.ItemLongClickChildviewBinding; +import com.chad.baserecyclerviewadapterhelper.databinding.ItemLongClickViewBinding; +import com.chad.baserecyclerviewadapterhelper.entity.ClickEntity; +import com.chad.library.adapter4.BaseMultiItemAdapter; + +import java.util.List; + +/** + * + */ +public class ItemClickAdapter extends BaseMultiItemAdapter { + + static class ItemViewVH extends RecyclerView.ViewHolder { + + ItemClickViewBinding viewBinding; + + public ItemViewVH(@NonNull ItemClickViewBinding viewBinding) { + super(viewBinding.getRoot()); + this.viewBinding = viewBinding; + } + + public ItemViewVH(@NonNull ViewGroup parent) { + this(ItemClickViewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + } + + static class ItemChildVH extends RecyclerView.ViewHolder { + + ItemClickChildviewBinding viewBinding; + + public ItemChildVH(@NonNull ItemClickChildviewBinding viewBinding) { + super(viewBinding.getRoot()); + this.viewBinding = viewBinding; + } + + public ItemChildVH(@NonNull ViewGroup parent) { + this(ItemClickChildviewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + } + + static class ItemLongClickVH extends RecyclerView.ViewHolder { + + ItemLongClickViewBinding viewBinding; + + public ItemLongClickVH(@NonNull ItemLongClickViewBinding viewBinding) { + super(viewBinding.getRoot()); + this.viewBinding = viewBinding; + } + + public ItemLongClickVH(@NonNull ViewGroup parent) { + this(ItemLongClickViewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + } + + static class ItemChildLongClickVH extends RecyclerView.ViewHolder { + + ItemLongClickChildviewBinding viewBinding; + + public ItemChildLongClickVH(@NonNull ItemLongClickChildviewBinding viewBinding) { + super(viewBinding.getRoot()); + this.viewBinding = viewBinding; + } + + public ItemChildLongClickVH(@NonNull ViewGroup parent) { + this(ItemLongClickChildviewBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false)); + } + } + + /** + * 构造方法 + */ + public ItemClickAdapter(List data) { + super(data); + + addItemType(ClickEntity.CLICK_ITEM_VIEW, new OnMultiItemAdapterListener() { + + @NonNull + @Override + public ItemViewVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { + return new ItemViewVH(parent); + } + + @Override + public void onBind(@NonNull ItemViewVH holder, int position, ClickEntity item) { + } + + @Override + public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) { + if (holder instanceof ItemViewVH) { + System.out.println("---------------------- >> onViewDetachedFromWindow ItemViewVH"); + } + } + }).addItemType(ClickEntity.CLICK_ITEM_CHILD_VIEW, new OnMultiItemAdapterListener() { + + @NonNull + @Override + public ItemChildVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { + return new ItemChildVH(parent); + } + + @Override + public void onBind(@NonNull ItemChildVH holder, int position, ClickEntity item) { + } + }).addItemType(ClickEntity.LONG_CLICK_ITEM_VIEW, new OnMultiItemAdapterListener() { + + @NonNull + @Override + public ItemLongClickVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { + return new ItemLongClickVH(parent); + } + + @Override + public void onBind(@NonNull ItemLongClickVH holder, int position, ClickEntity item) { + } + }).addItemType(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW, new OnMultiItemAdapterListener() { + + @NonNull + @Override + public ItemChildLongClickVH onCreate(@NonNull Context context, @NonNull ViewGroup parent, int viewType) { + return new ItemChildLongClickVH(parent); + } + + @Override + public void onBind(@NonNull ItemChildLongClickVH holder, int position, ClickEntity item) { + } + }).onItemViewType(new OnItemViewTypeListener() { + @Override + public int onItemViewType(int position, @NonNull List list) { + return list.get(position).getItemType(); + } + }); + + } + + +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/AutoLoadMoreRefreshUseActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/AutoLoadMoreRefreshUseActivity.kt new file mode 100644 index 000000000..d72cd8a53 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/AutoLoadMoreRefreshUseActivity.kt @@ -0,0 +1,229 @@ +package com.chad.baserecyclerviewadapterhelper.activity.loadmore + +import android.graphics.Color +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.LinearLayoutManager +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter +import com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter.RecyclerViewAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.data.DataServer +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityLoadMoreBinding +import com.chad.baserecyclerviewadapterhelper.entity.Status +import com.chad.baserecyclerviewadapterhelper.utils.Tips +import com.chad.library.adapter4.QuickAdapterHelper +import com.chad.library.adapter4.loadState.LoadState +import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter.OnTrailingListener + +/** + * 自动加载更多 + */ +class AutoLoadMoreRefreshUseActivity : BaseViewBindingActivity() { + internal class PageInfo { + var page = 0 + fun nextPage() { + page++ + } + + fun reset() { + page = 0 + } + + val isFirstPage: Boolean + get() = page == 0 + } + + private val pageInfo = PageInfo() + + private val mAdapter: RecyclerViewAdapter = RecyclerViewAdapter() + private lateinit var helper: QuickAdapterHelper + + override fun initBinding(): ActivityLoadMoreBinding = + ActivityLoadMoreBinding.inflate(layoutInflater) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + viewBinding.rvList.updatePadding(bottom = bar.bottom) + insets + } + + viewBinding.titleBar.title = "Auto LoadMore Use" + viewBinding.titleBar.setOnBackListener { finish() } + + + viewBinding.rvList.layoutManager = LinearLayoutManager(this) + initAdapter() + addHeadView() + initRefreshLayout() + } + + override fun onStart() { + super.onStart() + // 进入页面,先显示加载状态布局 + mAdapter.setEmptyViewLayout(this, R.layout.loading_view) + viewBinding.refreshLayout.isRefreshing = true + refresh() + } + + private fun initAdapter() { + // 使用默认的"加载更多"的样式 + helper = QuickAdapterHelper.Builder(mAdapter) + .setTrailingLoadStateAdapter(object : OnTrailingListener { + override fun onLoad() { + request() + } + + override fun onFailRetry() { + request() + } + + override fun isAllowLoading(): Boolean { + return !viewBinding.refreshLayout.isRefreshing + } + }) + .setTrailPreloadSize(0) // 预加载(默认值为0) + .isTrailAutoLoadMore(true) // 是否自动加载更多(默认为true) + .build() + + // 设置预加载,请调用以下方法 + // helper.trailingLoadStateAdapter?.preloadSize = 1 + viewBinding.rvList.adapter = helper.adapter + } + + private fun addHeadView() { + val headerAdapter = HeaderAdapter() + headerAdapter.setOnItemClickListener { _, _, _ -> + addHeadView() + } + helper.addBeforeAdapter(0, headerAdapter) + } + + private fun initRefreshLayout() { + viewBinding.refreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189)) + viewBinding.refreshLayout.setOnRefreshListener { refresh() } + } + + /** + * 刷新 + */ + private fun refresh() { + // 下拉刷新,需要重置页数 + pageInfo.reset() + // 重置“加载更多”时状态 + helper.trailingLoadState = LoadState.None + request() + } + + /** + * 请求数据 + */ + private fun request() { + + Request(pageInfo.page, object : RequestCallBack { + override fun success(data: List) { + viewBinding.refreshLayout.isRefreshing = false + if (pageInfo.isFirstPage) { + // 如果是加载的第一页数据,用 submitList() + // If it is the first page of data loaded, use submitList(). + mAdapter.submitList(data) + } else { + //不是第一页,则用add + mAdapter.addAll(data) + } + + // 如果在数据不满足一屏时,暂停加载更多,请调用下面方法 + // helper.trailingLoadStateAdapter?.checkDisableLoadMoreIfNotFullPage() + + if (pageInfo.page >= PAGE_SIZE) { + /* + Set the status to not loaded, and there is no paging data. + 设置状态为未加载,并且没有分页数据了 + */ + helper.trailingLoadState = LoadState.NotLoading(true) + Tips.show("no more data") + } else { + /* + Set the state to not loaded, and there is also paginated data + 设置状态为未加载,并且还有分页数据 + */ + helper.trailingLoadState = LoadState.NotLoading(false) + } + + // page加一 + pageInfo.nextPage() + } + + override fun fail(e: Exception) { + Tips.show(resources.getString(R.string.network_err)) + viewBinding.refreshLayout.isRefreshing = false + helper.trailingLoadState = LoadState.Error(e) + } + }).start() + } + + /** + * 模拟加载数据的类,不用特别关注 + */ + internal class Request(private val mPage: Int, private val mCallBack: RequestCallBack) : Thread() { + private val mHandler: Handler = Handler(Looper.getMainLooper()) + + override fun run() { + try { + sleep(800) // 模拟网络延迟 + } catch (ignored: InterruptedException) { + } + if (mPage == 2 && mFirstError) { + mFirstError = false + mHandler.post { mCallBack.fail(RuntimeException("load fail")) } + } else { + var size = PAGE_SIZE + if (mPage == 1) { + if (mFirstPageNoMore) { + size = 1 + } + mFirstPageNoMore = !mFirstPageNoMore + if (!mFirstError) { + mFirstError = true + } + } else if (mPage == 4) { + size = 1 + } + val dataSize = size + mHandler.post { mCallBack.success(DataServer.getSampleData(dataSize)) } + } + } + + companion object { + private var mFirstPageNoMore = false + private var mFirstError = true + } + } + + internal interface RequestCallBack { + /** + * 模拟加载成功 + * + * @param data 数据 + */ + fun success(data: List) + + /** + * 模拟加载失败 + * + * @param e 错误信息 + */ + fun fail(e: Exception) + } + + companion object { + private const val PAGE_SIZE = 5 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/NoAutoAutoLoadMoreRefreshUseActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/NoAutoAutoLoadMoreRefreshUseActivity.kt new file mode 100644 index 000000000..2476179be --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/NoAutoAutoLoadMoreRefreshUseActivity.kt @@ -0,0 +1,236 @@ +package com.chad.baserecyclerviewadapterhelper.activity.loadmore + +import android.graphics.Color +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.LinearLayoutManager +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.activity.headerfooter.adapter.HeaderAdapter +import com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter.CustomLoadMoreAdapter +import com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter.RecyclerViewAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.data.DataServer +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityLoadMoreBinding +import com.chad.baserecyclerviewadapterhelper.entity.Status +import com.chad.baserecyclerviewadapterhelper.utils.Tips +import com.chad.library.adapter4.QuickAdapterHelper +import com.chad.library.adapter4.loadState.LoadState +import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter.OnTrailingListener + +/** + * 不进行自动加载更多 + */ +class NoAutoAutoLoadMoreRefreshUseActivity : BaseViewBindingActivity() { + internal class PageInfo { + var page = 0 + fun nextPage() { + page++ + } + + fun reset() { + page = 0 + } + + val isFirstPage: Boolean + get() = page == 0 + } + + private val pageInfo = AutoLoadMoreRefreshUseActivity.PageInfo() + + private val mAdapter: RecyclerViewAdapter = RecyclerViewAdapter() + private lateinit var helper: QuickAdapterHelper + + override fun initBinding(): ActivityLoadMoreBinding = + ActivityLoadMoreBinding.inflate(layoutInflater) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + viewBinding.rvList.updatePadding(bottom = bar.bottom) + insets + } + + viewBinding.titleBar.title = "No Auto LoadMore Use" + viewBinding.titleBar.setOnBackListener { finish() } + + + viewBinding.rvList.layoutManager = LinearLayoutManager(this) + initAdapter() + addHeadView() + initRefreshLayout() + } + + override fun onStart() { + super.onStart() + // 进入页面,刷新数据 + mAdapter.setEmptyViewLayout(this, R.layout.loading_view) + viewBinding.refreshLayout.isRefreshing = true + refresh() + } + + private fun initAdapter() { + // 自定义"加载更多"的样式 + val loadMoreAdapter = CustomLoadMoreAdapter() + loadMoreAdapter.setOnLoadMoreListener(object : OnTrailingListener { + override fun onLoad() { + request() + } + + override fun onFailRetry() { + request() + } + + override fun isAllowLoading(): Boolean { + // 下拉刷新的适合,不允许进行"加载更多" + return !viewBinding.refreshLayout.isRefreshing + } + }) + + //—————————————————————————————————————————————————————————— + // 可选,监听加载状态的变化。 + //—————————————————————————————————————————————————————————— + loadMoreAdapter.addLoadStateListener { previousState, currentState -> + // 你的业务逻辑 + println("----------- previousState: $previousState - currentState: $currentState ") + } + + //—————————————————————————————————————————————————————————— + // 关闭"自动加载更多" + //—————————————————————————————————————————————————————————— + loadMoreAdapter.isAutoLoadMore = false + helper = QuickAdapterHelper.Builder(mAdapter) + .setTrailingLoadStateAdapter(loadMoreAdapter) + .build() + viewBinding.rvList.adapter = helper.adapter + } + + private fun addHeadView() { + val headerAdapter = HeaderAdapter() + headerAdapter.setOnItemClickListener { _, _, _ -> + addHeadView() + } + helper.addBeforeAdapter(headerAdapter) + } + + private fun initRefreshLayout() { + viewBinding.refreshLayout.setColorSchemeColors(Color.rgb(47, 223, 189)) + viewBinding.refreshLayout.setOnRefreshListener { refresh() } + } + + /** + * 刷新 + */ + private fun refresh() { + // 下拉刷新,需要重置页数 + pageInfo.reset() + request() + } + + /** + * 请求数据 + */ + private fun request() { + + Request(pageInfo.page, object : RequestCallBack { + override fun success(data: List) { + viewBinding.refreshLayout.isRefreshing = false + if (pageInfo.isFirstPage) { + // 如果是加载的第一页数据,用 submitList() + // If it is the first page of data loaded, use submitList(). + mAdapter.submitList(data) + } else { + //不是第一页,则用add + mAdapter.addAll(data) + } + if (pageInfo.page >= PAGE_SIZE) { + /* + Set the status to not loaded, and there is no paging data. + 设置状态为未加载,并且没有分页数据了 + */ + helper.trailingLoadState = LoadState.NotLoading(true) + Tips.show("no more data") + } else { + /* + Set the state to not loaded, and there is also paginated data + 设置状态为未加载,并且还有分页数据 + */ + helper.trailingLoadState = LoadState.NotLoading(false) + } + + // page加一 + pageInfo.nextPage() + } + + override fun fail(e: Exception) { + Tips.show(resources.getString(R.string.network_err)) + viewBinding.refreshLayout.isRefreshing = false + helper.trailingLoadState = LoadState.Error(e) + } + }).start() + } + + /** + * 模拟加载数据的类,不用特别关注 + */ + internal class Request(private val mPage: Int, private val mCallBack: RequestCallBack) : + Thread() { + private val mHandler: Handler = Handler(Looper.getMainLooper()) + + override fun run() { + try { + sleep(1000) // 模拟网络延迟 + } catch (ignored: InterruptedException) { + } + if (mPage == 2 && mFirstError) { + mFirstError = false + mHandler.post { mCallBack.fail(RuntimeException("load fail")) } + } else { + var size = PAGE_SIZE + if (mPage == 1) { + if (mFirstPageNoMore) { + size = 1 + } + mFirstPageNoMore = !mFirstPageNoMore + if (!mFirstError) { + mFirstError = true + } + } else if (mPage == 4) { + size = 1 + } + val dataSize = size + mHandler.post { mCallBack.success(DataServer.getSampleData(dataSize)) } + } + } + + companion object { + private var mFirstPageNoMore = false + private var mFirstError = true + } + } + + internal interface RequestCallBack { + /** + * 模拟加载成功 + * + * @param data 数据 + */ + fun success(data: List) + + /** + * 模拟加载失败 + * + * @param e 错误信息 + */ + fun fail(e: Exception) + } + + companion object { + private const val PAGE_SIZE = 5 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/CustomLoadMoreAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/CustomLoadMoreAdapter.kt new file mode 100644 index 000000000..50cf3917b --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/CustomLoadMoreAdapter.kt @@ -0,0 +1,71 @@ +package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.databinding.ViewLoadMoreBinding +import com.chad.library.adapter4.loadState.LoadState +import com.chad.library.adapter4.loadState.trailing.TrailingLoadStateAdapter + +/** + * 自定义的"加载更多"。 + * 这里可以做很多事情,这里仅展示了更改自定义布局的使用。 + * + * There are many things that can be done here, only the use of changing custom layouts is shown here. + */ +class CustomLoadMoreAdapter : TrailingLoadStateAdapter() { + + override fun onCreateViewHolder(parent: ViewGroup, loadState: LoadState): CustomVH { + val viewBinding = ViewLoadMoreBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return CustomVH(viewBinding).apply { + viewBinding.loadMoreLoadFailView.setOnClickListener { + // 失败重试点击事件 + invokeFailRetry() + } + viewBinding.loadMoreLoadCompleteView.setOnClickListener { + // 加载更多,手动点击事件 + invokeLoadMore() + } + } + } + + override fun onBindViewHolder(holder: CustomVH, loadState: LoadState) { + when (loadState) { + is LoadState.NotLoading -> { + if (loadState.endOfPaginationReached) { + holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE + holder.viewBinding.loadMoreLoadingView.visibility = View.GONE + holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE + holder.viewBinding.loadMoreLoadEndView.visibility = View.VISIBLE + } else { + holder.viewBinding.loadMoreLoadCompleteView.visibility = View.VISIBLE + holder.viewBinding.loadMoreLoadingView.visibility = View.GONE + holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE + holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE + } + } + is LoadState.Loading -> { + holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE + holder.viewBinding.loadMoreLoadingView.visibility = View.VISIBLE + holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE + holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE + } + is LoadState.Error -> { + holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE + holder.viewBinding.loadMoreLoadingView.visibility = View.GONE + holder.viewBinding.loadMoreLoadFailView.visibility = View.VISIBLE + holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE + } + is LoadState.None -> { + holder.viewBinding.loadMoreLoadCompleteView.visibility = View.GONE + holder.viewBinding.loadMoreLoadingView.visibility = View.GONE + holder.viewBinding.loadMoreLoadFailView.visibility = View.GONE + holder.viewBinding.loadMoreLoadEndView.visibility = View.GONE + } + } + } + + + class CustomVH(val viewBinding: ViewLoadMoreBinding) : RecyclerView.ViewHolder(viewBinding.root) +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/RecyclerViewAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/RecyclerViewAdapter.kt new file mode 100644 index 000000000..89e612ef9 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/loadmore/adapter/RecyclerViewAdapter.kt @@ -0,0 +1,67 @@ +package com.chad.baserecyclerviewadapterhelper.activity.loadmore.adapter + +import android.content.Context +import android.text.TextPaint +import android.text.method.LinkMovementMethod +import android.text.style.ClickableSpan +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.core.content.ContextCompat +import androidx.core.text.buildSpannedString +import androidx.core.text.inSpans +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.databinding.LayoutAnimationBinding +import com.chad.baserecyclerviewadapterhelper.entity.Status +import com.chad.baserecyclerviewadapterhelper.utils.Tips +import com.chad.library.adapter4.BaseQuickAdapter + +/** + * @author: limuyang + * @date: 2019-12-04 + * @Description: + */ +class RecyclerViewAdapter : BaseQuickAdapter() { + class VH( + parent: ViewGroup, + val viewBinding: LayoutAnimationBinding = LayoutAnimationBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + ) : RecyclerView.ViewHolder(viewBinding.root) + + override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { + return VH(parent) + } + + protected override fun onBindViewHolder(holder: VH, position: Int, item: Status?) { + when (holder.layoutPosition % 3) { + 0 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img1) + 1 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img2) + 2 -> holder.viewBinding.img.setImageResource(R.mipmap.animation_img3) + else -> {} + } + holder.viewBinding.tweetName.text = + "Hoteis in Rio de Janeiro " + position + " " + item!!.userName + val msg = + "\"He was one of Australia's most of distinguished artistes, renowned for his portraits\"" + holder.viewBinding.tweetText.text = buildSpannedString { + append(msg) + inSpans(clickableSpan) { + append("landscapes and nedes") + } + } + holder.viewBinding.tweetText.movementMethod = LinkMovementMethod.getInstance() + } + + private val clickableSpan: ClickableSpan = object : ClickableSpan() { + override fun onClick(widget: View) { + Tips.show("事件触发了 landscapes and nedes") + } + + override fun updateDrawState(ds: TextPaint) { + ds.color = ContextCompat.getColor(context, R.color.clickspan_color) + ds.isUnderlineText = true + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/NodeActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/NodeActivity.kt new file mode 100644 index 000000000..2d8519854 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/NodeActivity.kt @@ -0,0 +1,51 @@ +package com.chad.baserecyclerviewadapterhelper.activity.node + +import android.os.Bundle +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import com.chad.baserecyclerviewadapterhelper.activity.node.adapter.NodeAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.data.DataServer +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityNodeBinding + +/** + * @author LiMuYang + * @date 2025/9/5 + * @description 多节点demo + */ +class NodeActivity : BaseViewBindingActivity() { + + private val adapter = NodeAdapter() + + override fun initBinding(): ActivityNodeBinding { + return ActivityNodeBinding.inflate(layoutInflater) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + viewBinding.titleBar.title = "Multi-node Use" + viewBinding.titleBar.setOnBackListener { finish() } + + viewBinding.rv.adapter = adapter + + adapter.submitList(DataServer.getNodeData()) + + + viewBinding.btnCloseAll.setOnClickListener { + adapter.closeAll() + } + viewBinding.btnRef.setOnClickListener { + adapter.submitList(DataServer.getNodeData()) + } + viewBinding.btnRefOnSave.setOnClickListener { + adapter.submitList(DataServer.getNodeData(), clearOpenStates = true) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/adapter/NodeAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/adapter/NodeAdapter.kt new file mode 100644 index 000000000..4382095aa --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/node/adapter/NodeAdapter.kt @@ -0,0 +1,204 @@ +package com.chad.baserecyclerviewadapterhelper.activity.node.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.Toast +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.databinding.ItemNodeLevel1Binding +import com.chad.baserecyclerviewadapterhelper.databinding.ItemNodeLevel2Binding +import com.chad.baserecyclerviewadapterhelper.databinding.ItemNodeLevel3Binding +import com.chad.baserecyclerviewadapterhelper.entity.NodeEntity +import com.chad.library.adapter4.BaseNodeAdapter + +/** + * @author LiMuYang + * @date 2025/9/5 + * @description + */ +class NodeAdapter : BaseNodeAdapter() { + + override fun getChildNodeList(position: Int, parent: Any): List? { + when (parent) { + is NodeEntity -> { + // 一级 + return parent.childNode + } + + is NodeEntity.Level2NodeEntity -> { + // 二级 + return parent.childNode + } + + is NodeEntity.Level2NodeEntity.Level3NodeEntity -> { + // 三级 没有子node + return null + } + + else -> return null + } + } + + override fun isInitialOpen(position: Int, item: Any): Boolean { + // 哪些数据需要默认展开 + if (item is NodeEntity) { + return item.title == "Item 1" + } else if (item is NodeEntity.Level2NodeEntity) { + // 二级 + return item.title.startsWith("Item 1", ignoreCase = true) + } + return false + } + + override fun isSameNode(item1: Any, item2: Any): Boolean { + return when (item1) { + is NodeEntity if item2 is NodeEntity -> { + item1.title == item2.title + } + + is NodeEntity.Level2NodeEntity if item2 is NodeEntity.Level2NodeEntity -> { + // 二级 + item1.title == item2.title + } + + is NodeEntity.Level2NodeEntity.Level3NodeEntity if item2 is NodeEntity.Level2NodeEntity.Level3NodeEntity -> { + // 三级 + item1.title == item2.title + } + + else -> { + false + } + } + } + + override fun getItemViewType(position: Int, list: List): Int { + val item = list[position] + when (item) { + is NodeEntity -> { + // 一级 + return 1 + } + + is NodeEntity.Level2NodeEntity -> { + // 二级 + return 2 + } + + is NodeEntity.Level2NodeEntity.Level3NodeEntity -> { + // 三级 + return 3 + } + + else -> return 0 + } + } + + override fun onCreateViewHolder( + context: Context, parent: ViewGroup, viewType: Int, + ): RecyclerView.ViewHolder { + return when (viewType) { + 1 -> { + Level1Hodler(parent).apply { + itemView.setOnClickListener { + openOrClose(bindingAdapterPosition) + } + } + } + + 2 -> { + Level2Hodler(parent).apply { + itemView.setOnClickListener { + openOrClose(bindingAdapterPosition) + } + } + } + + 3 -> { + Level3Hodler(parent).apply { + itemView.setOnClickListener { + Toast.makeText( + it.context, + "Level 3 _ index $bindingAdapterPosition", + Toast.LENGTH_SHORT + ).show() + } + } + } + + else -> { + Level1Hodler(parent) + } + } + } + + override fun onBindViewHolder( + holder: RecyclerView.ViewHolder, position: Int, item: Any?, + ) { + when (holder) { + is Level1Hodler -> { + // 一级 + val nodeEntity = item as NodeEntity + + holder.viewBinding.tvTitle.text = nodeEntity.title + + // 设置箭头图标 + if (nodeEntity.childNode.isNullOrEmpty()) { + holder.viewBinding.ivArrow.setBackgroundResource(0) + } else { + if (isOpened(item)) { + holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_down) + } else { + holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_right) + } + } + } + + is Level2Hodler -> { + // 二级 + val nodeEntity = item as NodeEntity.Level2NodeEntity + holder.viewBinding.tvTitle.text = nodeEntity.title + + // 设置箭头图标 + if (nodeEntity.childNode.isNullOrEmpty()) { + holder.viewBinding.ivArrow.setBackgroundResource(0) + } else { + if (isOpened(item)) { + holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_down) + } else { + holder.viewBinding.ivArrow.setBackgroundResource(R.drawable.ic_node_right) + } + } + } + + is Level3Hodler -> { + // 三级 + val nodeEntity = item as NodeEntity.Level2NodeEntity.Level3NodeEntity + holder.viewBinding.tvTitle.text = nodeEntity.title + } + } + } +} + + +class Level1Hodler( + parent: ViewGroup, + val viewBinding: ItemNodeLevel1Binding = ItemNodeLevel1Binding.inflate( + LayoutInflater.from(parent.context), parent, false + ), +) : RecyclerView.ViewHolder(viewBinding.root) + +class Level2Hodler( + parent: ViewGroup, + val viewBinding: ItemNodeLevel2Binding = ItemNodeLevel2Binding.inflate( + LayoutInflater.from(parent.context), parent, false + ), +) : RecyclerView.ViewHolder(viewBinding.root) + +class Level3Hodler( + parent: ViewGroup, + val viewBinding: ItemNodeLevel3Binding = ItemNodeLevel3Binding.inflate( + LayoutInflater.from(parent.context), parent, false + ), +) : RecyclerView.ViewHolder(viewBinding.root) \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/GroupDemoActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/GroupDemoActivity.kt new file mode 100644 index 000000000..ca278d803 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/GroupDemoActivity.kt @@ -0,0 +1,166 @@ +package com.chad.baserecyclerviewadapterhelper.activity.scene + +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.ConcatAdapter +import androidx.recyclerview.widget.LinearLayoutManager +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.activity.scene.adapter.GroupAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding +import com.chad.baserecyclerviewadapterhelper.entity.GroupDemoEntity +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import androidx.core.graphics.drawable.toDrawable + + +class GroupDemoActivity : BaseViewBindingActivity() { + + // 创建一个 ConcatAdapter,用来包裹 GroupAdapter + private val concatAdapter = ConcatAdapter() + + + override fun initBinding(): ActivityUniversalRecyclerBinding = + ActivityUniversalRecyclerBinding.inflate(layoutInflater) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + window.setBackgroundDrawable(ContextCompat.getColor(this, R.color.bg).toDrawable()) + + viewBinding.titleBar.title = "Group Scene(ConcatAdapter)" + viewBinding.titleBar.setOnBackListener { finish() } + + viewBinding.rv.layoutManager = LinearLayoutManager(this) + viewBinding.rv.adapter = concatAdapter + + /* + 往常,我们获得这样一个 List 嵌套 List 的结构时,需要展平数据成一个 List, + 然后用一个 Adapter 通过不同的ItemViewType 去做,非常繁琐,容易出错,而且不方便数据刷新 + + 现在我们不需要去对数据做处理了,直接使用! + */ + val list: List = jsonToList() + + + // 循环 list,有多少个数组,就创建多少个 GroupAdapter,就这么简单 + list.forEach { + val adapter = GroupAdapter() + adapter.submitList(it.groupList) + + // 创建好以后,直接扔进 ConcatAdapter + concatAdapter.addAdapter(adapter) + } + } + + /** + * 解析 Json,不用关注 + */ + private fun jsonToList(): List { + val moshi = Moshi.Builder().build() + val type = Types.newParameterizedType(List::class.java, GroupDemoEntity::class.java) + val jsonAdapter: JsonAdapter> = moshi.adapter(type) + return jsonAdapter.fromJson(JSON) ?: throw IllegalStateException("json 解析出错") + } + + companion object { + // 此种格式的json,在业务场景中比较常见 + private const val JSON = """ +[{ + "group_name": "1", + "group_list": [{ + "title": "patton", + "content": "this is content" + }, + { + "title": "nicole", + "content": "this is content" + }, + { + "title": "anthony", + "content": "this is content" + } + ] + }, + { + "group_name": "2", + "group_list": [{ + "title": "zane", + "content": "this is content" + }, + { + "title": "venus", + "content": "this is content" + }, + { + "title": "yahya", + "content": "this is content" + }, + { + "title": "starlight", + "content": "this is content" + }, + { + "title": "twinkle", + "content": "this is content" + } + ] + }, + { + "group_name": "3", + "group_list": [{ + "title": "esther", + "content": "this is content" + }, + { + "title": "asta", + "content": "this is content" + }, + { + "title": "gary", + "content": "this is content" + } + ] + }, + { + "group_name": "4", + "group_list": [{ + "title": "peter", + "content": "this is content" + }, + { + "title": "aldrich", + "content": "this is content" + } + ] + }, + { + "group_name": "5", + "group_list": [{ + "title": "edgar", + "content": "this is content" + }, + { + "title": "danika", + "content": "this is content" + }, + { + "title": "clement", + "content": "this is content" + } + ] + } +] + """ + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/adapter/GroupAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/adapter/GroupAdapter.kt new file mode 100644 index 000000000..291ea9e4c --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/scene/adapter/GroupAdapter.kt @@ -0,0 +1,59 @@ +package com.chad.baserecyclerviewadapterhelper.activity.scene.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import android.view.ViewGroup.MarginLayoutParams +import androidx.core.view.isVisible +import androidx.core.view.updateLayoutParams +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.databinding.ItemGroupTypeBinding +import com.chad.baserecyclerviewadapterhelper.entity.GroupDemoEntity +import com.chad.baserecyclerviewadapterhelper.utils.dp +import com.chad.library.adapter4.BaseQuickAdapter + +/** + * 每一组的Adapter + * + */ +class GroupAdapter : BaseQuickAdapter(){ + + class VH( + parent: ViewGroup, + val binding: ItemGroupTypeBinding = ItemGroupTypeBinding.inflate(LayoutInflater.from(parent.context), parent ,false) + ):RecyclerView.ViewHolder(binding.root) + + override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { + return VH(parent) + } + + override fun onBindViewHolder(holder: VH, position: Int, item: GroupDemoEntity.Group?) { + if (item == null) return + + holder.binding.tvTitle.text = item.title + holder.binding.tvContent.text = item.content + + holder.binding.lineView.isVisible = position > 0 + + when (position) { + 0 -> { + // 第一个item,设置上圆角背景 + holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_top_bg) + + // 设置点间距 + holder.binding.root.updateLayoutParams { + topMargin = 15.dp + } + } + items.size - 1 -> { + // 最后一个item,设置下圆角背景 + holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_bottom_bg) + } + else -> { + // 其他的,没有圆角的背景 + holder.binding.root.setBackgroundResource(R.drawable.ic_group_item_mid_bg) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/UpFetchUseActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/UpFetchUseActivity.kt new file mode 100644 index 000000000..48539e6eb --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/UpFetchUseActivity.kt @@ -0,0 +1,128 @@ +package com.chad.baserecyclerviewadapterhelper.activity.upfetch + +import android.os.Bundle +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import androidx.recyclerview.widget.LinearLayoutManager +import com.chad.baserecyclerviewadapterhelper.activity.upfetch.adapter.UpFetchAdapter +import com.chad.baserecyclerviewadapterhelper.base.BaseViewBindingActivity +import com.chad.baserecyclerviewadapterhelper.databinding.ActivityUniversalRecyclerBinding +import com.chad.baserecyclerviewadapterhelper.entity.Movie +import com.chad.library.adapter4.QuickAdapterHelper +import com.chad.library.adapter4.loadState.LoadState +import com.chad.library.adapter4.loadState.LoadState.NotLoading +import com.chad.library.adapter4.loadState.leading.LeadingLoadStateAdapter.OnLeadingListener +import java.util.* + +/** + * @author limuyang + * 2019-12-06 + */ +class UpFetchUseActivity : BaseViewBindingActivity() { + + private val mAdapter = UpFetchAdapter() + private lateinit var helper: QuickAdapterHelper + + override fun initBinding(): ActivityUniversalRecyclerBinding = + ActivityUniversalRecyclerBinding.inflate(layoutInflater) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ViewCompat.setOnApplyWindowInsetsListener(viewBinding.root) { view, insets -> + val bar = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + viewBinding.titleBar.updateFakeBarHeight(bar.top) + insets + } + + viewBinding.titleBar.title = "UpFetch Use" + viewBinding.titleBar.setOnBackListener { finish() } + + + viewBinding.rv.layoutManager = LinearLayoutManager(this) + + helper = QuickAdapterHelper.Builder(mAdapter) + .setLeadingLoadStateAdapter(object : OnLeadingListener { + override fun onLoad() { + requestUoFetch() + } + + override fun isAllowLoading(): Boolean { + return true + } + }) + .setLeadPreloadSize(0) // 预加载(默认值为0) + .build() + viewBinding.rv.adapter = helper.adapter + } + + override fun onStart() { + super.onStart() + requestUoFetch() + } + + private var count = 0 + private fun requestUoFetch() { + if (count == 0) { + count++ + // 首次进入页面,设置数据 + mAdapter.submitList(genData()) + scrollToBottom() + helper.leadingLoadState = NotLoading(false) + return + } + count++ + + /** + * When starting to request data from the network, set the status to loading. + * 当开始网络请求数据的时候,设置状态为加载中 + */ + helper.leadingLoadState = LoadState.Loading + + /* + * get data from internet. + * 从网络获取数据 + */ + viewBinding.rv.postDelayed({ + mAdapter.addAll(0, genData()) + if (count > 5) { + /* + * Set the status to not loaded, and there is no paging data. + * 设置状态为未加载,并且没有分页数据了 + */ + helper.leadingLoadState = NotLoading(true) + } else { + /** + * Set the state to not loaded, and there is also paginated data + * 设置状态为未加载,并且还有分页数据 + */ + helper.leadingLoadState = NotLoading(false) + } + }, 600) + } + + /** + * 滚动到底部(不带动画) + */ + private fun scrollToBottom() { + val ll = viewBinding.rv.layoutManager as LinearLayoutManager + ll.scrollToPositionWithOffset(bottomDataPosition, 0) + } + + private val bottomDataPosition: Int + get() = mAdapter.items.size - 1 + + private fun genData(): List { + val list = ArrayList() + val random = Random() + for (i in 0..9) { + val name = "Chad" + val price = random.nextInt(10) + 10 + val len = random.nextInt(80) + 60 + val movie = + Movie(name, len, price, "He was one of Australia's most distinguished artistes") + list.add(movie) + } + return list + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/adapter/UpFetchAdapter.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/adapter/UpFetchAdapter.kt new file mode 100644 index 000000000..75a42b135 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/activity/upfetch/adapter/UpFetchAdapter.kt @@ -0,0 +1,37 @@ +package com.chad.baserecyclerviewadapterhelper.activity.upfetch.adapter + +import android.content.Context +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.databinding.ItemHeaderAndFooterBinding +import com.chad.baserecyclerviewadapterhelper.entity.Movie +import com.chad.library.adapter4.BaseQuickAdapter + +/** + * @author: limuyang + * @date: 2019-12-06 + * @Description: + */ +class UpFetchAdapter : BaseQuickAdapter() { + class VH( + parent: ViewGroup, + val viewBinding: ItemHeaderAndFooterBinding = ItemHeaderAndFooterBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + ) : RecyclerView.ViewHolder(viewBinding.root) + + override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH { + return VH(parent) + } + + override fun onBindViewHolder(holder: VH, position: Int, item: Movie?) { + when (holder.layoutPosition % 3) { + 0 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img1) + 1 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img2) + 2 -> holder.viewBinding.iv.setImageResource(R.mipmap.animation_img3) + else -> {} + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/AnimationAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/AnimationAdapter.java deleted file mode 100644 index 99fd12b72..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/AnimationAdapter.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import android.text.TextPaint; -import android.text.style.ClickableSpan; -import android.view.View; -import android.widget.TextView; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.baserecyclerviewadapterhelper.entity.Status; -import com.chad.baserecyclerviewadapterhelper.util.ClickableMovementMethod; -import com.chad.baserecyclerviewadapterhelper.util.SpannableStringUtils; -import com.chad.baserecyclerviewadapterhelper.util.ToastUtils; -import com.chad.baserecyclerviewadapterhelper.util.Utils; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; - -/** - * 文 件 名: AnimationAdapter - * 创 建 人: Allen - * 创建日期: 16/12/24 15:33 - * 邮 箱: AllenCoder@126.com - * 修改时间: - * 修改备注: - */ -public class AnimationAdapter extends BaseQuickAdapter { - public AnimationAdapter() { - super(R.layout.layout_animation, DataServer.getSampleData(100)); - } - - @Override - protected void convert(BaseViewHolder helper, Status item) { - helper.addOnClickListener(R.id.img).addOnClickListener(R.id.tweetName); - switch (helper.getLayoutPosition() % - 3) { - case 0: - helper.setImageResource(R.id.img, R.mipmap.animation_img1); - break; - case 1: - helper.setImageResource(R.id.img, R.mipmap.animation_img2); - break; - case 2: - helper.setImageResource(R.id.img, R.mipmap.animation_img3); - break; - } - helper.setText(R.id.tweetName, "Hoteis in Rio de Janeiro"); - String msg = "\"He was one of Australia's most of distinguished artistes, renowned for his portraits\""; - ((TextView) helper.getView(R.id.tweetText)).setText(SpannableStringUtils.getBuilder(msg).append("landscapes and nedes").setClickSpan(clickableSpan).create()); - ((TextView) helper.getView(R.id.tweetText)).setMovementMethod(ClickableMovementMethod.getInstance()); - ((TextView) helper.getView(R.id.tweetText)).setFocusable(false); - ((TextView) helper.getView(R.id.tweetText)).setClickable(false); - ((TextView) helper.getView(R.id.tweetText)).setLongClickable(false); - } - - ClickableSpan clickableSpan = new ClickableSpan() { - @Override - public void onClick(View widget) { - ToastUtils.showShortToast("事件触发了 landscapes and nedes"); - } - - @Override - public void updateDrawState(TextPaint ds) { - ds.setColor(Utils.getContext().getResources().getColor(R.color.clickspan_color)); - ds.setUnderlineText(true); - } - }; -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/DataBindingUseAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/DataBindingUseAdapter.java deleted file mode 100644 index 6e5459927..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/DataBindingUseAdapter.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import android.databinding.DataBindingUtil; -import android.databinding.ViewDataBinding; -import android.view.View; -import android.view.ViewGroup; - -import com.chad.baserecyclerviewadapterhelper.BR; -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.entity.Movie; -import com.chad.baserecyclerviewadapterhelper.entity.MoviePresenter; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; - -import java.util.List; - -/** - * Created by luoxiongwen on 16/10/24. - */ - -public class DataBindingUseAdapter extends BaseQuickAdapter { - - private MoviePresenter mPresenter; - - public DataBindingUseAdapter(int layoutResId, List data) { - super(layoutResId, data); - - mPresenter = new MoviePresenter(); - } - - @Override - protected void convert(MovieViewHolder helper, Movie item) { - ViewDataBinding binding = helper.getBinding(); - binding.setVariable(BR.movie, item); - binding.setVariable(BR.presenter, mPresenter); - binding.executePendingBindings(); - switch (helper.getLayoutPosition() % - 2) { - case 0: - helper.setImageResource(R.id.iv, R.mipmap.m_img1); - break; - case 1: - helper.setImageResource(R.id.iv, R.mipmap.m_img2); - break; - - } - } - - /* @Override - protected MovieViewHolder createBaseViewHolder(View view) { - return new MovieViewHolder(view); - } - */ - @Override - protected View getItemView(int layoutResId, ViewGroup parent) { - ViewDataBinding binding = DataBindingUtil.inflate(mLayoutInflater, layoutResId, parent, false); - if (binding == null) { - return super.getItemView(layoutResId, parent); - } - View view = binding.getRoot(); - view.setTag(R.id.BaseQuickAdapter_databinding_support, binding); - return view; - } - - public static class MovieViewHolder extends BaseViewHolder { - - public MovieViewHolder(View view) { - super(view); - } - - public ViewDataBinding getBinding() { - return (ViewDataBinding) itemView.getTag(R.id.BaseQuickAdapter_databinding_support); - } - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/DefAdpater.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/DefAdpater.java deleted file mode 100644 index f840345c9..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/DefAdpater.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import android.content.Context; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import com.bumptech.glide.Glide; -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.baserecyclerviewadapterhelper.entity.Status; - -import java.util.List; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class DefAdpater extends RecyclerView.Adapter { - private final List sampleData = DataServer.getSampleData(100); - private Context mContext; - private LayoutInflater mLayoutInflater; - public DefAdpater(Context context) { - mContext = context; - mLayoutInflater = LayoutInflater.from(context); - } - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View item = mLayoutInflater.inflate(R.layout.layout_animation, parent, false); - return new ViewHolder(item); - } - - @Override - public void onBindViewHolder(ViewHolder holder, int position) { - Status status = sampleData.get(position); - holder.name.setText(status.getUserName()); - holder.text.setText(status.getText()); - holder.date.setText(status.getCreatedAt()); - } - - @Override - public int getItemCount() { - return sampleData.size(); - } - - public static class ViewHolder extends RecyclerView.ViewHolder { - - private TextView name; - private TextView date; - private TextView text; - - public ViewHolder(View itemView) { - super(itemView); - text = (TextView) itemView.findViewById(R.id.tweetText); - name = (TextView) itemView.findViewById(R.id.tweetName); - date = (TextView) itemView.findViewById(R.id.tweetDate); - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ExpandableItemAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ExpandableItemAdapter.java deleted file mode 100644 index 5fa79d0a8..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ExpandableItemAdapter.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import android.util.Log; -import android.view.View; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.entity.Level0Item; -import com.chad.baserecyclerviewadapterhelper.entity.Level1Item; -import com.chad.baserecyclerviewadapterhelper.entity.Person; -import com.chad.library.adapter.base.BaseMultiItemQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; -import com.chad.library.adapter.base.entity.MultiItemEntity; - -import java.util.List; - -/** - * Created by luoxw on 2016/8/9. - */ -public class ExpandableItemAdapter extends BaseMultiItemQuickAdapter { - private static final String TAG = ExpandableItemAdapter.class.getSimpleName(); - - public static final int TYPE_LEVEL_0 = 0; - public static final int TYPE_LEVEL_1 = 1; - public static final int TYPE_PERSON = 2; - - /** - * Same as QuickAdapter#QuickAdapter(Context,int) but with - * some initialization data. - * - * @param data A new list is created out of this one to avoid mutable list - */ - public ExpandableItemAdapter(List data) { - super(data); - addItemType(TYPE_LEVEL_0, R.layout.item_expandable_lv0); - addItemType(TYPE_LEVEL_1, R.layout.item_expandable_lv1); - addItemType(TYPE_PERSON, R.layout.item_expandable_lv2); - } - - - @Override - protected void convert(final BaseViewHolder holder, final MultiItemEntity item) { - switch (holder.getItemViewType()) { - case TYPE_LEVEL_0: - switch (holder.getLayoutPosition() % - 3) { - case 0: - holder.setImageResource(R.id.iv_head, R.mipmap.head_img0); - break; - case 1: - holder.setImageResource(R.id.iv_head, R.mipmap.head_img1); - break; - case 2: - holder.setImageResource(R.id.iv_head, R.mipmap.head_img2); - break; - } - final Level0Item lv0 = (Level0Item) item; - holder.setText(R.id.title, lv0.title) - .setText(R.id.sub_title, lv0.subTitle) - .setImageResource(R.id.iv, lv0.isExpanded() ? R.mipmap.arrow_b : R.mipmap.arrow_r); - holder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - int pos = holder.getAdapterPosition(); - Log.d(TAG, "Level 0 item pos: " + pos); - if (lv0.isExpanded()) { - collapse(pos); - } else { -// if (pos % 3 == 0) { -// expandAll(pos, false); -// } else { - expand(pos); -// } - } - } - }); - break; - case TYPE_LEVEL_1: - final Level1Item lv1 = (Level1Item) item; - holder.setText(R.id.title, lv1.title) - .setText(R.id.sub_title, lv1.subTitle) - .setImageResource(R.id.iv, lv1.isExpanded() ? R.mipmap.arrow_b : R.mipmap.arrow_r); - holder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - int pos = holder.getAdapterPosition(); - Log.d(TAG, "Level 1 item pos: " + pos); - if (lv1.isExpanded()) { - collapse(pos, false); - } else { - expand(pos, false); - } - } - }); - - holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - int pos = holder.getAdapterPosition(); - remove(pos); - return true; - } - }); - break; - case TYPE_PERSON: - final Person person = (Person) item; - holder.setText(R.id.tv, person.name + " parent pos: " + getParentPosition(person)); - holder.itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - int pos = holder.getAdapterPosition(); - remove(pos); - } - }); - break; - } - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/HeaderAndFooterAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/HeaderAndFooterAdapter.java deleted file mode 100644 index 3c49c38ab..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/HeaderAndFooterAdapter.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.baserecyclerviewadapterhelper.entity.Status; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class HeaderAndFooterAdapter extends BaseQuickAdapter { - - public HeaderAndFooterAdapter(int dataSize) { - super(R.layout.item_header_and_footer, DataServer.getSampleData(dataSize)); - } - - @Override - protected void convert(BaseViewHolder helper, Status item) { - switch (helper.getLayoutPosition()% - 3){ - case 0: - helper.setImageResource(R.id.iv,R.mipmap.animation_img1); - break; - case 1: - helper.setImageResource(R.id.iv,R.mipmap.animation_img2); - break; - case 2: - helper.setImageResource(R.id.iv,R.mipmap.animation_img3); - break; - } - } - - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/HomeAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/HomeAdapter.java deleted file mode 100644 index 4bf629b0c..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/HomeAdapter.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.entity.HomeItem; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; - -import java.util.List; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class HomeAdapter extends BaseQuickAdapter { - public HomeAdapter(int layoutResId, List data) { - super(layoutResId, data); - } - - @Override - protected void convert(BaseViewHolder helper, HomeItem item) { - helper.setText(R.id.text, item.getTitle()); - helper.setImageResource(R.id.icon, item.getImageResource()); - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ItemClickAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ItemClickAdapter.java deleted file mode 100755 index 1769b1ca9..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ItemClickAdapter.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.widget.Toast; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.entity.ClickEntity; -import com.chad.baserecyclerviewadapterhelper.util.Utils; -import com.chad.library.adapter.base.BaseMultiItemQuickAdapter; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; -import com.orhanobut.logger.Logger; - -import java.util.List; - -/** - * - */ -public class ItemClickAdapter extends BaseMultiItemQuickAdapter implements BaseQuickAdapter.OnItemClickListener, BaseQuickAdapter.OnItemChildClickListener { - NestAdapter nestAdapter; - - public ItemClickAdapter(List data) { - super(data); - addItemType(ClickEntity.CLICK_ITEM_VIEW, R.layout.item_click_view); - addItemType(ClickEntity.CLICK_ITEM_CHILD_VIEW, R.layout.item_click_childview); - addItemType(ClickEntity.LONG_CLICK_ITEM_VIEW, R.layout.item_long_click_view); - addItemType(ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW, R.layout.item_long_click_childview); - addItemType(ClickEntity.NEST_CLICK_ITEM_CHILD_VIEW, R.layout.item_nest_click); - - } - - - @Override - protected void convert(final BaseViewHolder helper, final ClickEntity item) { - switch (helper.getItemViewType()) { - case ClickEntity.CLICK_ITEM_VIEW: - helper.addOnClickListener(R.id.btn); - break; - case ClickEntity.CLICK_ITEM_CHILD_VIEW: - helper.addOnClickListener(R.id.iv_num_reduce).addOnClickListener(R.id.iv_num_add) - .addOnLongClickListener(R.id.iv_num_reduce).addOnLongClickListener(R.id.iv_num_add); - // set img data - break; - case ClickEntity.LONG_CLICK_ITEM_VIEW: - helper.addOnLongClickListener(R.id.btn); - break; - case ClickEntity.LONG_CLICK_ITEM_CHILD_VIEW: - helper.addOnLongClickListener(R.id.iv_num_reduce).addOnLongClickListener(R.id.iv_num_add) - .addOnClickListener(R.id.iv_num_reduce).addOnClickListener(R.id.iv_num_add); - break; - case ClickEntity.NEST_CLICK_ITEM_CHILD_VIEW: - helper.setNestView(R.id.item_click); // u can set nestview id - final RecyclerView recyclerView = helper.getView(R.id.nest_list); - recyclerView.setLayoutManager(new LinearLayoutManager(helper.itemView.getContext(), LinearLayoutManager.VERTICAL, false)); - recyclerView.setHasFixedSize(true); - - nestAdapter = new NestAdapter(); - nestAdapter.setOnItemClickListener(this); - nestAdapter.setOnItemChildClickListener(this); - recyclerView.setAdapter(nestAdapter); - break; - } - } - - @Override - public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { - Toast.makeText(Utils.getContext(), "childView click", Toast.LENGTH_SHORT).show(); - } - - @Override - public void onItemClick(BaseQuickAdapter adapter, View view, int position) { - Logger.d("嵌套RecycleView item 收到: " + "点击了第 " + position + " 一次"); - Toast.makeText(Utils.getContext(), "嵌套RecycleView item 收到: " + "点击了第 " + position + " 一次", Toast.LENGTH_SHORT).show(); - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ItemDragAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ItemDragAdapter.java deleted file mode 100644 index 613bdb463..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/ItemDragAdapter.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.library.adapter.base.BaseItemDraggableAdapter; -import com.chad.library.adapter.base.BaseViewHolder; - -import java.util.List; - -/** - * Created by luoxw on 2016/6/20. - */ -public class ItemDragAdapter extends BaseItemDraggableAdapter { - public ItemDragAdapter(List data) { - super(R.layout.item_draggable_view, data); - } - - @Override - protected void convert(BaseViewHolder helper, String item) { - switch (helper.getLayoutPosition() % - 3) { - case 0: - helper.setImageResource(R.id.iv_head, R.mipmap.head_img0); - break; - case 1: - helper.setImageResource(R.id.iv_head, R.mipmap.head_img1); - break; - case 2: - helper.setImageResource(R.id.iv_head, R.mipmap.head_img2); - break; - } - helper.setText(R.id.tv, item); - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/MultipleItemQuickAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/MultipleItemQuickAdapter.java deleted file mode 100644 index fdf54f7df..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/MultipleItemQuickAdapter.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import android.content.Context; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.entity.MultipleItem; -import com.chad.library.adapter.base.BaseMultiItemQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; - -import java.util.List; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - * modify by AllenCoder - */ -public class MultipleItemQuickAdapter extends BaseMultiItemQuickAdapter { - - public MultipleItemQuickAdapter(Context context, List data) { - super(data); - addItemType(MultipleItem.TEXT, R.layout.item_text_view); - addItemType(MultipleItem.IMG, R.layout.item_image_view); - addItemType(MultipleItem.IMG_TEXT, R.layout.item_img_text_view); - } - - @Override - protected void convert(BaseViewHolder helper, MultipleItem item) { - switch (helper.getItemViewType()) { - case MultipleItem.TEXT: - helper.setText(R.id.tv, item.getContent()); - break; - case MultipleItem.IMG_TEXT: - switch (helper.getLayoutPosition() % - 2) { - case 0: - helper.setImageResource(R.id.iv, R.mipmap.animation_img1); - break; - case 1: - helper.setImageResource(R.id.iv, R.mipmap.animation_img2); - break; - - } - break; - } - } - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/NestAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/NestAdapter.java deleted file mode 100644 index 4d452902c..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/NestAdapter.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import android.text.TextPaint; -import android.text.method.LinkMovementMethod; -import android.text.style.ClickableSpan; -import android.view.View; -import android.widget.TextView; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.baserecyclerviewadapterhelper.entity.Status; -import com.chad.baserecyclerviewadapterhelper.util.SpannableStringUtils; -import com.chad.baserecyclerviewadapterhelper.util.ToastUtils; -import com.chad.baserecyclerviewadapterhelper.util.Utils; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; - -/** - * 文 件 名: AnimationAdapter - * 创 建 人: Allen - * 创建日期: 16/12/24 15:33 - * 邮 箱: AllenCoder@126.com - * 修改时间: - * 修改备注: - */ -public class NestAdapter extends BaseQuickAdapter { - public NestAdapter() { - super( R.layout.layout_nest_item, DataServer.getSampleData(20)); - } - - @Override - protected void convert(BaseViewHolder helper, Status item) { - helper.addOnClickListener(R.id.tweetText); - switch (helper.getLayoutPosition()% - 3){ - case 0: - helper.setImageResource(R.id.img,R.mipmap.animation_img1); - break; - case 1: - helper.setImageResource(R.id.img,R.mipmap.animation_img2); - break; - case 2: - helper.setImageResource(R.id.img,R.mipmap.animation_img3); - break; - } - helper.setText(R.id.tweetName,"Hoteis in Rio de Janeiro"); - String msg="\"He was one of Australia's most of distinguished artistes, renowned for his portraits\""; - ( (TextView)helper.getView(R.id.tweetText)).setText(SpannableStringUtils.getBuilder(msg).append("landscapes and nedes").setClickSpan(clickableSpan).create()); - ( (TextView)helper.getView(R.id.tweetText)).setMovementMethod(LinkMovementMethod.getInstance()); - } - - ClickableSpan clickableSpan = new ClickableSpan() { - @Override - public void onClick(View widget) { - ToastUtils.showShortToast("事件触发了 landscapes and nedes"); - } - - @Override - public void updateDrawState(TextPaint ds) { - ds.setColor(Utils.getContext().getResources().getColor(R.color.clickspan_color)); - ds.setUnderlineText(true); - } - }; -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/PullToRefreshAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/PullToRefreshAdapter.java deleted file mode 100644 index ffd564d79..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/PullToRefreshAdapter.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import android.text.TextPaint; -import android.text.method.LinkMovementMethod; -import android.text.style.ClickableSpan; -import android.view.View; -import android.widget.TextView; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.entity.Status; -import com.chad.baserecyclerviewadapterhelper.util.SpannableStringUtils; -import com.chad.baserecyclerviewadapterhelper.util.ToastUtils; -import com.chad.baserecyclerviewadapterhelper.util.Utils; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; - -/** - * 文 件 名: PullToRefreshAdapter - * 创 建 人: Allen - * 创建日期: 16/12/24 19:55 - * 邮 箱: AllenCoder@126.com - * 修改时间: - * 修改备注: - */ -public class PullToRefreshAdapter extends BaseQuickAdapter { - public PullToRefreshAdapter() { - super( R.layout.layout_animation, null); - } - - @Override - protected void convert(BaseViewHolder helper, Status item) { - switch (helper.getLayoutPosition()% - 3){ - case 0: - helper.setImageResource(R.id.img,R.mipmap.animation_img1); - break; - case 1: - helper.setImageResource(R.id.img,R.mipmap.animation_img2); - break; - case 2: - helper.setImageResource(R.id.img,R.mipmap.animation_img3); - break; - } - helper.setText(R.id.tweetName,"Hoteis in Rio de Janeiro"); - String msg="\"He was one of Australia's most of distinguished artistes, renowned for his portraits\""; - ( (TextView)helper.getView(R.id.tweetText)).setText(SpannableStringUtils.getBuilder(msg).append("landscapes and nedes").setClickSpan(clickableSpan).create()); - ( (TextView)helper.getView(R.id.tweetText)).setMovementMethod(LinkMovementMethod.getInstance()); - } - - ClickableSpan clickableSpan = new ClickableSpan() { - @Override - public void onClick(View widget) { - ToastUtils.showShortToast("事件触发了 landscapes and nedes"); - } - - @Override - public void updateDrawState(TextPaint ds) { - ds.setColor(Utils.getContext().getResources().getColor(R.color.clickspan_color)); - ds.setUnderlineText(true); - } - }; - - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickAdapter.java deleted file mode 100644 index 455499133..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/QuickAdapter.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import android.text.method.LinkMovementMethod; -import android.widget.ImageView; -import android.widget.TextView; - -import com.bumptech.glide.Glide; -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.baserecyclerviewadapterhelper.entity.Status; -import com.chad.baserecyclerviewadapterhelper.transform.GlideCircleTransform; -import com.chad.baserecyclerviewadapterhelper.util.SpannableStringUtils; -import com.chad.library.adapter.base.BaseQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class QuickAdapter extends BaseQuickAdapter { - - public QuickAdapter(int dataSize) { - super(R.layout.layout_animation, DataServer.getSampleData(dataSize)); - } - - @Override - protected void convert(BaseViewHolder helper, Status item) { - switch (helper.getLayoutPosition() % - 3) { - case 0: - helper.setImageResource(R.id.img, R.mipmap.animation_img1); - break; - case 1: - helper.setImageResource(R.id.img, R.mipmap.animation_img2); - break; - case 2: - helper.setImageResource(R.id.img, R.mipmap.animation_img3); - break; - } - helper.setText(R.id.tweetName, "Hoteis in Rio de Janeiro"); - helper.setText(R.id.tweetText, "O ever youthful,O ever weeping"); - - } - - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/SectionAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/SectionAdapter.java deleted file mode 100644 index 60d4d94ef..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/SectionAdapter.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.entity.MySection; -import com.chad.baserecyclerviewadapterhelper.entity.Video; -import com.chad.library.adapter.base.BaseSectionQuickAdapter; -import com.chad.library.adapter.base.BaseViewHolder; -import com.chad.library.adapter.base.listener.OnItemChildClickListener; - -import java.util.List; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class SectionAdapter extends BaseSectionQuickAdapter { - /** - * Same as QuickAdapter#QuickAdapter(Context,int) but with - * some initialization data. - * - * @param sectionHeadResId The section head layout id for each item - * @param layoutResId The layout resource id of each item. - * @param data A new list is created out of this one to avoid mutable list - */ - public SectionAdapter(int layoutResId, int sectionHeadResId, List data) { - super(layoutResId, sectionHeadResId, data); - } - - @Override - protected void convertHead(BaseViewHolder helper, final MySection item) { - helper.setText(R.id.header, item.header); - helper.setVisible(R.id.more, item.isMore()); - helper.addOnClickListener(R.id.more); - } - - - @Override - protected void convert(BaseViewHolder helper, MySection item) { - Video video = (Video) item.t; - switch (helper.getLayoutPosition() % - 2) { - case 0: - helper.setImageResource(R.id.iv, R.mipmap.m_img1); - break; - case 1: - helper.setImageResource(R.id.iv, R.mipmap.m_img2); - break; - - } - helper.setText(R.id.tv, video.getName()); - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/UpFetchAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/UpFetchAdapter.java deleted file mode 100644 index 9453d0f92..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/adapter/UpFetchAdapter.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.adapter; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.chad.baserecyclerviewadapterhelper.base.BaseDataBindingAdapter; -import com.chad.baserecyclerviewadapterhelper.databinding.ItemMovieBinding; -import com.chad.baserecyclerviewadapterhelper.entity.Movie; - -/** - * Created by tysheng - * Date: 2017/5/25 10:47. - * Email: tyshengsx@gmail.com - */ - -public class UpFetchAdapter extends BaseDataBindingAdapter { - public UpFetchAdapter() { - super(R.layout.item_movie, null); - } - - @Override - protected void convert(ItemMovieBinding binding, Movie item) { - binding.setMovie(item); - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animation/CustomAnimation.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animation/CustomAnimation.java deleted file mode 100644 index 82e94587c..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animation/CustomAnimation.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.animation; - -import android.animation.Animator; -import android.animation.ObjectAnimator; -import android.view.View; - -import com.chad.library.adapter.base.animation.BaseAnimation; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class CustomAnimation implements BaseAnimation { - - @Override - public Animator[] getAnimators(View view) { - return new Animator[]{ - ObjectAnimator.ofFloat(view, "scaleY", 1, 1.1f, 1), - ObjectAnimator.ofFloat(view, "scaleX", 1, 1.1f, 1) - }; - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation1.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation1.java new file mode 100644 index 000000000..514923cc0 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation1.java @@ -0,0 +1,32 @@ +package com.chad.baserecyclerviewadapterhelper.animator; + +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.view.View; +import android.view.animation.DecelerateInterpolator; +import com.chad.library.adapter4.animation.ItemAnimator; +import org.jetbrains.annotations.NotNull; + +/** + * 自定义动画1 + */ +public class CustomAnimation1 implements ItemAnimator { + @NotNull + @Override + public Animator animator(@NotNull View view) { + Animator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1f); + + Animator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1.3f, 1); + Animator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1.3f, 1); + + scaleY.setInterpolator(new DecelerateInterpolator()); + scaleX.setInterpolator(new DecelerateInterpolator()); + + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.setDuration(350); + animatorSet.play(alpha).with(scaleX).with(scaleY); + + return animatorSet; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation2.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation2.java new file mode 100644 index 000000000..d9d38d2d0 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation2.java @@ -0,0 +1,40 @@ +package com.chad.baserecyclerviewadapterhelper.animator; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.view.View; +import android.view.animation.Interpolator; + +import com.chad.library.adapter4.animation.ItemAnimator; + +import org.jetbrains.annotations.NotNull; + +import static java.lang.Math.PI; +import static java.lang.Math.pow; +import static java.lang.Math.sin; + + +/** + * 自定义动画2 + */ +public class CustomAnimation2 implements ItemAnimator { + @NotNull + @Override + public Animator animator(@NotNull View view) { + Animator translationX = + ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0f); + + translationX.setDuration(800); + translationX.setInterpolator(new MyInterpolator2()); + + return translationX; + } + + private static class MyInterpolator2 implements Interpolator { + @Override + public float getInterpolation(float input) { + float factor = 0.7f; + return (float) (pow(2.0, -10.0 * input) * sin((input - factor / 4) * (2 * PI) / factor) + 1); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation3.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation3.java new file mode 100644 index 000000000..60785bcff --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/animator/CustomAnimation3.java @@ -0,0 +1,30 @@ +package com.chad.baserecyclerviewadapterhelper.animator; + +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.view.View; +import android.view.animation.DecelerateInterpolator; + +import com.chad.library.adapter4.animation.ItemAnimator; + +import org.jetbrains.annotations.NotNull; + +public class CustomAnimation3 implements ItemAnimator { + + @NotNull + @Override + public Animator animator(@NotNull View view) { + Animator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1f); + + Animator translationY = + ObjectAnimator.ofFloat(view, "translationY", view.getRootView().getHeight(), 0f); + translationY.setInterpolator(new DecelerateInterpolator(1.2f)); + + AnimatorSet animatorSet = new AnimatorSet(); + animatorSet.setDuration(450); + animatorSet.play(alpha).with(translationY); + + return animatorSet; + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.java deleted file mode 100644 index 27dd52edc..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.base; - -import android.os.Build; -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.chad.baserecyclerviewadapterhelper.R; -import com.orhanobut.logger.Logger; - -/** - * 文 件 名: BaseActivity - * 创 建 人: Allen - * 创建日期: 16/12/24 15:33 - * 邮 箱: AllenCoder@126.com - * 修改时间: - * 修改备注: - */ -public class BaseActivity extends AppCompatActivity { - /** - * 日志输出标志getSupportActionBar(). - **/ - private TextView title; - private ImageView back; - protected final String TAG = this.getClass().getSimpleName(); - - protected void setTitle(String msg) { - if (title != null) { - title.setText(msg); - } - } - - /** - * sometime you want to define back event - */ - protected void setBackBtn() { - if (back != null) { - back.setVisibility(View.VISIBLE); - back.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); - }else { - Logger.t(TAG).e("back is null ,please check out"); - } - - } - - protected void setBackClickListener(View.OnClickListener l) { - if (back != null) { - back.setVisibility(View.VISIBLE); - back.setOnClickListener(l); - }else { - Logger.t(TAG).e("back is null ,please check out"); - } - - } - - private LinearLayout rootLayout; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // 经测试在代码里直接声明透明状态栏更有效 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, - WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - } - // 这句很关键,注意是调用父类的方法 - super.setContentView(R.layout.activity_base); - initToolbar(); - } - - private void initToolbar() { - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); - if (toolbar != null) { - setSupportActionBar(toolbar); - } - if (getSupportActionBar() != null) { - // Enable the Up button - getSupportActionBar().setDisplayHomeAsUpEnabled(false); - getSupportActionBar().setDisplayShowTitleEnabled(false); - - } - back = (ImageView) findViewById(R.id.img_back); - title = (TextView) findViewById(R.id.title); - } - - - @Override - public void setContentView(int layoutId) { - setContentView(View.inflate(this, layoutId, null)); - } - - @Override - public void setContentView(View view) { - rootLayout = (LinearLayout) findViewById(R.id.root_layout); - if (rootLayout == null) return; - rootLayout.addView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - initToolbar(); - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.kt new file mode 100644 index 000000000..ce16d031f --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseActivity.kt @@ -0,0 +1,39 @@ +package com.chad.baserecyclerviewadapterhelper.base + +import android.os.Build +import android.os.Bundle +import android.view.View +import androidx.activity.enableEdgeToEdge +import androidx.annotation.LayoutRes +import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat +import androidx.core.view.ViewCompat +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.utils.statusBarLightMode + +abstract class BaseActivity(@LayoutRes layoutRes: Int = 0) : AppCompatActivity(layoutRes) { + + + protected open val contentView: View? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + enableEdgeToEdge() + + contentView?.let { + setContentView(it) + } + + + + + + window.statusBarColor = ContextCompat.getColor(this, R.color.spinner_bg) + window.statusBarLightMode = false + + + } + + +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseBindingViewHolder.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseBindingViewHolder.java deleted file mode 100644 index e9ed97d0a..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseBindingViewHolder.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.base; - -import android.databinding.ViewDataBinding; -import android.view.View; - -import com.chad.library.adapter.base.BaseViewHolder; - -/** - * Created by tysheng - * Date: 2017/5/11 14:42. - * Email: tyshengsx@gmail.com - */ - -public class BaseBindingViewHolder extends BaseViewHolder { - private Binding mBinding; - - public BaseBindingViewHolder(View view) { - super(view); - } - - public Binding getBinding() { - return mBinding; - } - - public void setBinding(Binding binding) { - mBinding = binding; - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseDataBindingAdapter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseDataBindingAdapter.java deleted file mode 100644 index 0fbf329e2..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseDataBindingAdapter.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.base; - -import android.databinding.DataBindingUtil; -import android.databinding.ViewDataBinding; -import android.support.annotation.LayoutRes; -import android.support.annotation.Nullable; -import android.view.View; -import android.view.ViewGroup; - -import com.chad.library.adapter.base.BaseQuickAdapter; - -import java.util.List; - - -/** - * Created by tysheng - * Date: 2017/5/11 14:39. - * Email: tyshengsx@gmail.com - */ - -public abstract class BaseDataBindingAdapter extends BaseQuickAdapter> { - - - public BaseDataBindingAdapter(@LayoutRes int layoutResId, @Nullable List data) { - super(layoutResId, data); - } - - public BaseDataBindingAdapter(@Nullable List data) { - super(data); - } - - public BaseDataBindingAdapter(@LayoutRes int layoutResId) { - super(layoutResId); - } - - @Override - protected BaseBindingViewHolder createBaseViewHolder(View view) { - return new BaseBindingViewHolder<>(view); - } - - @Override - protected BaseBindingViewHolder createBaseViewHolder(ViewGroup parent, int layoutResId) { - Binding binding = DataBindingUtil.inflate(mLayoutInflater, layoutResId, parent, false); - View view; - if (binding == null) { - view = getItemView(layoutResId, parent); - } else { - view = binding.getRoot(); - } - BaseBindingViewHolder holder = new BaseBindingViewHolder<>(view); - holder.setBinding(binding); - return holder; - } - - @Override - protected void convert(BaseBindingViewHolder helper, T item) { - convert(helper.getBinding(), item); - helper.getBinding().executePendingBindings(); - } - - protected abstract void convert(Binding binding, T item); -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseViewBindingActivity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseViewBindingActivity.kt new file mode 100644 index 000000000..6cf21b670 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/base/BaseViewBindingActivity.kt @@ -0,0 +1,29 @@ +package com.chad.baserecyclerviewadapterhelper.base + +import android.view.View +import androidx.viewbinding.ViewBinding + +abstract class BaseViewBindingActivity : BaseActivity() { + + private var _viewBinding: V? = null + + protected val viewBinding: V + get() { + return _viewBinding ?: throw IllegalStateException( + "Should be called initBinding()" + ) + } + + /** + * 初始化 [viewBinding] + */ + abstract fun initBinding(): V + + final override val contentView: View + get() { + return initBinding().apply { + _viewBinding = this + }.root + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.java deleted file mode 100644 index 3e18a4431..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.data; - - -import com.chad.baserecyclerviewadapterhelper.entity.MultipleItem; -import com.chad.baserecyclerviewadapterhelper.entity.MySection; -import com.chad.baserecyclerviewadapterhelper.entity.Status; -import com.chad.baserecyclerviewadapterhelper.entity.Video; - -import java.util.ArrayList; -import java.util.List; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class DataServer { - - private static final String HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK = "https://avatars1.githubusercontent.com/u/7698209?v=3&s=460"; - private static final String CYM_CHAD = "CymChad"; - - private DataServer() { - } - - public static List getSampleData(int lenth) { - List list = new ArrayList<>(); - for (int i = 0; i < lenth; i++) { - Status status = new Status(); - status.setUserName("Chad" + i); - status.setCreatedAt("04/05/" + i); - status.setRetweet(i % 2 == 0); - status.setUserAvatar("https://avatars1.githubusercontent.com/u/7698209?v=3&s=460"); - status.setText("BaseRecyclerViewAdpaterHelper https://www.recyclerview.org"); - list.add(status); - } - return list; - } - - public static List addData(List list, int dataSize) { - for (int i = 0; i < dataSize; i++) { - Status status = new Status(); - status.setUserName("Chad" + i); - status.setCreatedAt("04/05/" + i); - status.setRetweet(i % 2 == 0); - status.setUserAvatar("https://avatars1.githubusercontent.com/u/7698209?v=3&s=460"); - status.setText("Powerful and flexible RecyclerAdapter https://github.com/CymChad/BaseRecyclerViewAdapterHelper"); - list.add(status); - } - - return list; - } - - public static List getSampleData() { - List list = new ArrayList<>(); - list.add(new MySection(true, "Section 1", true)); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(true, "Section 2", false)); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(true, "Section 3", false)); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(true, "Section 4", false)); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(true, "Section 5", false)); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - list.add(new MySection(new Video(HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK, CYM_CHAD))); - return list; - } - - public static List getStrData() { - List list = new ArrayList<>(); - for (int i = 0; i < 20; i++) { - String str = HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK; - if (i % 2 == 0) { - str = CYM_CHAD; - } - list.add(str); - } - return list; - } - - public static List getMultipleItemData() { - List list = new ArrayList<>(); - for (int i = 0; i <= 4; i++) { - list.add(new MultipleItem(MultipleItem.IMG, MultipleItem.IMG_SPAN_SIZE)); - list.add(new MultipleItem(MultipleItem.TEXT, MultipleItem.TEXT_SPAN_SIZE, CYM_CHAD)); - list.add(new MultipleItem(MultipleItem.IMG_TEXT, MultipleItem.IMG_TEXT_SPAN_SIZE)); - list.add(new MultipleItem(MultipleItem.IMG_TEXT, MultipleItem.IMG_TEXT_SPAN_SIZE_MIN)); - list.add(new MultipleItem(MultipleItem.IMG_TEXT, MultipleItem.IMG_TEXT_SPAN_SIZE_MIN)); - } - - return list; - } - -// public static List getMultipleChildView() { -// List list = new ArrayList<>(); -// for (int i = 0; i <= 4; i++) { -// list.add(new ClickEntity(ClickEntity.CLICK_ITEM_VIEW, MultipleItem.TEXT_SPAN_SIZE, CYM_CHAD)); -// list.add(new MultipleItem(MultipleItem.IMG, MultipleItem.BIG_IMG_SPAN_SIZE)); -// list.add(new MultipleItem(MultipleItem.IMG, MultipleItem.IMG_SPAN_SIZE)); -// list.add(new MultipleItem(MultipleItem.IMG, MultipleItem.IMG_SPAN_SIZE)); -// list.add(new MultipleItem(MultipleItem.IMG, MultipleItem.IMG_SPAN_SIZE)); -// } -// -// return list; -// } - - -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.kt new file mode 100644 index 000000000..737577cee --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/data/DataServer.kt @@ -0,0 +1,100 @@ +package com.chad.baserecyclerviewadapterhelper.data + +import com.chad.baserecyclerviewadapterhelper.R +import com.chad.baserecyclerviewadapterhelper.entity.DiffEntity +import com.chad.baserecyclerviewadapterhelper.entity.NodeEntity +import com.chad.baserecyclerviewadapterhelper.entity.Status + +/** + * https://github.com/CymChad/BaseRecyclerViewAdapterHelper + */ +object DataServer { + const val HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK = + "https://avatars1.githubusercontent.com/u/7698209?v=3&s=460" + const val CYM_CHAD = "CymChad" + const val CHAY_CHAN = "ChayChan" + + fun getSampleData(lenth: Int): MutableList { + val list: MutableList = ArrayList() + for (i in 0 until lenth) { + val status = Status() + status.userName = "Chad$i" + status.createdAt = "04/05/$i" + status.isRetweet = i % 2 == 0 + + + status.userAvatar = when (i % 3) { + 0 -> R.mipmap.animation_img1 + 1 -> R.mipmap.animation_img2 + else -> R.mipmap.animation_img3 + } + status.text = "BaseRecyclerViewAdpaterHelper https://www.recyclerview.org" + list.add(status) + } + return list + } + + + val strData: List + get() { + val list: MutableList = ArrayList() + for (i in 0..19) { + var str = HTTPS_AVATARS1_GITHUBUSERCONTENT_COM_LINK + if (i % 2 == 0) { + str = CYM_CHAD + } + list.add(str) + } + return list + } + + @JvmStatic + val diffUtilDemoEntities: List + get() { + val list: MutableList = ArrayList() + for (i in 0..9) { + list.add( + DiffEntity( + i, + "Item $i", + "This item $i content", + "06-12" + ) + ) + } + return list + } + + + fun getNodeData(): List { + val list = ArrayList() + for (i in 0..9) { + val node = if (i % 2 == 0) { + NodeEntity("Item $i", null) + } else { + val level2list = ArrayList() + for (n in 0..4) { + val leve2Node = if (n % 2 != 0) { + NodeEntity.Level2NodeEntity("Item ${i} - Level 2 - Index $n", null) + } else { + val level3list = ArrayList() + + for (m in 0..4) { + val level3Node = + NodeEntity.Level2NodeEntity.Level3NodeEntity("Item${i} - Level2-index:${n} - Level 3 - Index $m") + level3list.add(level3Node) + } + + NodeEntity.Level2NodeEntity("Item ${i} - Level 2 - Index $n with Child", level3list) + } + level2list.add(leve2Node) + } + + NodeEntity("Item $i", level2list) + } + list.add(node) + } + + return list + } +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridItemDecoration.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridItemDecoration.java index c1b3e0de3..2e2c49505 100755 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridItemDecoration.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridItemDecoration.java @@ -4,10 +4,11 @@ import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.view.View; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + /** * https://github.com/CymChad/BaseRecyclerViewAdapterHelper */ diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridSectionAverageGapItemDecoration.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridSectionAverageGapItemDecoration.java new file mode 100644 index 000000000..87778c025 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridSectionAverageGapItemDecoration.java @@ -0,0 +1,231 @@ +//package com.chad.baserecyclerviewadapterhelper.decoration; +// +//import android.graphics.Rect; +//import android.os.Build; +//import android.util.DisplayMetrics; +//import android.util.TypedValue; +//import android.view.View; +// +//import androidx.annotation.Nullable; +//import androidx.recyclerview.widget.GridLayoutManager; +//import androidx.recyclerview.widget.RecyclerView; +// +//import com.chad.library.adapter.base.BaseSectionQuickAdapter; +//import com.chad.library.adapter.base.viewholder.BaseViewHolder; +//import com.chad.library.adapter.base.entity.SectionEntity; +// +//import java.util.ArrayList; +//import java.util.List; +// +///** +// * 应用于RecyclerView的GridLayoutManager,水平方向上固定间距大小,从而使条目宽度自适应。
+// * 配合Brvah的Section使用,不对Head生效,仅对每个Head的子Grid列表生效
+// * Section Grid中Item的宽度应设为MATCH_PARAENT +// * +// * @author : renpeng +// * @since : 2018/9/29 +// */ +//public class GridSectionAverageGapItemDecoration extends RecyclerView.ItemDecoration { +// +// private class Section { +// public int startPos = 0; +// public int endPos = 0; +// +// public int getCount() { +// return endPos - startPos + 1; +// } +// +// public boolean contains(int pos) { +// return pos >= startPos && pos <= endPos; +// } +// +// @Override +// public String toString() { +// return "Section{" + +// "startPos=" + startPos + +// ", endPos=" + endPos + +// '}'; +// } +// } +// +// private float gapHorizontalDp; +// private float gapVerticalDp; +// private float sectionEdgeHPaddingDp; +// private float sectionEdgeVPaddingDp; +// private int gapHSizePx = -1; +// private int gapVSizePx = -1; +// private int sectionEdgeHPaddingPx; +// private int eachItemHPaddingPx; //每个条目应该在水平方向上加的padding 总大小,即=paddingLeft+paddingRight +// private int sectionEdgeVPaddingPx; +// private List

mSectionList = new ArrayList<>(); +// private BaseSectionQuickAdapter mAdapter; +// private RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() { +// @Override +// public void onChanged() { +// markSections(); +// } +// +// @Override +// public void onItemRangeChanged(int positionStart, int itemCount) { +// markSections(); +// } +// +// @Override +// public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) { +// markSections(); +// } +// +// @Override +// public void onItemRangeInserted(int positionStart, int itemCount) { +// markSections(); +// } +// +// @Override +// public void onItemRangeRemoved(int positionStart, int itemCount) { +// markSections(); +// } +// +// @Override +// public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { +// markSections(); +// } +// }; +// +// +// /** +// * @param gapHorizontalDp item之间的水平间距 +// * @param gapVerticalDp item之间的垂直间距 +// * @param sectionEdgeHPaddingDp section左右两端的padding大小 +// * @param sectionEdgeVPaddingDp section上下两端的padding大小 +// */ +// public GridSectionAverageGapItemDecoration(float gapHorizontalDp, float gapVerticalDp, float sectionEdgeHPaddingDp, float sectionEdgeVPaddingDp) { +// this.gapHorizontalDp = gapHorizontalDp; +// this.gapVerticalDp = gapVerticalDp; +// this.sectionEdgeHPaddingDp = sectionEdgeHPaddingDp; +// this.sectionEdgeVPaddingDp = sectionEdgeVPaddingDp; +// } +// +// @Override +// public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { +// if (parent.getLayoutManager() instanceof GridLayoutManager && parent.getAdapter() instanceof BaseSectionQuickAdapter) { +// GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager(); +// BaseSectionQuickAdapter adapter = (BaseSectionQuickAdapter) parent.getAdapter(); +// if (mAdapter != adapter) { +// setUpWithAdapter(adapter); +// } +// int spanCount = layoutManager.getSpanCount(); +// int position = parent.getChildAdapterPosition(view); +// SectionEntity entity = adapter.getItem(position); +// +// if (entity == null || entity.isHeader()) { +// //不处理header +// outRect.set(0, 0, 0, 0); +//// Log.w("GridAverageGapItem", "pos=" + position + "," + outRect.toShortString()); +// return; +// } +// +// Section section = findSectionLastItemPos(position); +// +// if (gapHSizePx < 0 || gapVSizePx < 0) { +// transformGapDefinition(parent, spanCount); +// } +// outRect.top = gapVSizePx; +// outRect.bottom = 0; +// +// //下面的visualPos为单个Section内的视觉Pos +// int visualPos = position + 1 - section.startPos; +// if (visualPos % spanCount == 1) { +// //第一列 +// outRect.left = sectionEdgeHPaddingPx; +// outRect.right = eachItemHPaddingPx - sectionEdgeHPaddingPx; +// } else if (visualPos % spanCount == 0) { +// //最后一列 +// outRect.left = eachItemHPaddingPx - sectionEdgeHPaddingPx; +// outRect.right = sectionEdgeHPaddingPx; +// } else { +// outRect.left = gapHSizePx - (eachItemHPaddingPx - sectionEdgeHPaddingPx); +// outRect.right = eachItemHPaddingPx - outRect.left; +// } +// +// if (visualPos - spanCount <= 0) { +// //第一行 +// outRect.top = sectionEdgeVPaddingPx; +// } +// +// if (isLastRow(visualPos, spanCount, section.getCount())) { +// //最后一行 +// outRect.bottom = sectionEdgeVPaddingPx; +//// Log.w("GridAverageGapItem", "last row pos=" + position); +// } +//// Log.w("GridAverageGapItem", "pos=" + position + ",vPos=" + visualPos + "," + outRect.toShortString()); +// } else { +// super.getItemOffsets(outRect, view, parent, state); +// } +// } +// +// private void setUpWithAdapter(BaseSectionQuickAdapter adapter) { +// if (mAdapter != null) { +// mAdapter.unregisterAdapterDataObserver(mDataObserver); +// } +// mAdapter = adapter; +// mAdapter.registerAdapterDataObserver(mDataObserver); +// markSections(); +// } +// +// private void markSections() { +// if (mAdapter != null) { +// BaseSectionQuickAdapter adapter = mAdapter; +// mSectionList.clear(); +// SectionEntity sectionEntity = null; +// Section section = new Section(); +// for (int i = 0, size = adapter.getItemCount(); i < size; i++) { +// sectionEntity = adapter.getItem(i); +// if (sectionEntity != null && sectionEntity.isHeader()) { +// //找到新Section起点 +// if (section != null && i != 0) { +// //已经有待添加的section +// section.endPos = i - 1; +// mSectionList.add(section); +// } +// section = new Section(); +// section.startPos = i + 1; +// } else { +// section.endPos = i; +// } +// } +// //处理末尾情况 +// if (!mSectionList.contains(section)) { +// mSectionList.add(section); +// } +// +//// Log.w("GridAverageGapItem", "section list=" + mSectionList); +// } +// } +// +// private void transformGapDefinition(RecyclerView parent, int spanCount) { +// DisplayMetrics displayMetrics = new DisplayMetrics(); +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { +// parent.getDisplay().getMetrics(displayMetrics); +// } +// gapHSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapHorizontalDp, displayMetrics); +// gapVSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapVerticalDp, displayMetrics); +// sectionEdgeHPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeHPaddingDp, displayMetrics); +// sectionEdgeVPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeVPaddingDp, displayMetrics); +// eachItemHPaddingPx = (sectionEdgeHPaddingPx * 2 + gapHSizePx * (spanCount - 1)) / spanCount; +// } +// +// private Section findSectionLastItemPos(int curPos) { +// for (Section section : mSectionList) { +// if (section.contains(curPos)) { +// return section; +// } +// } +// return null; +// } +// +// private boolean isLastRow(int visualPos, int spanCount, int sectionItemCount) { +// int lastRowCount = sectionItemCount % spanCount; +// lastRowCount = lastRowCount == 0 ? spanCount : lastRowCount; +// return visualPos > sectionItemCount - lastRowCount; +// } +//} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/ClickEntity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/ClickEntity.java index 5eed17e88..d3bb0ddb9 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/ClickEntity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/ClickEntity.java @@ -14,8 +14,6 @@ */ package com.chad.baserecyclerviewadapterhelper.entity; -import com.chad.library.adapter.base.entity.MultiItemEntity; - /** * 文 件 名: ClickEntity * 创 建 人: Allen @@ -24,20 +22,18 @@ * 修改时间: * 修改备注: */ -public class ClickEntity implements MultiItemEntity { +public class ClickEntity { public static final int CLICK_ITEM_VIEW = 1; public static final int CLICK_ITEM_CHILD_VIEW = 2; public static final int LONG_CLICK_ITEM_VIEW = 3; public static final int LONG_CLICK_ITEM_CHILD_VIEW = 4; - public static final int NEST_CLICK_ITEM_CHILD_VIEW = 5; - public int Type; + private final int type; public ClickEntity(final int type) { - Type = type; + this.type = type; } - @Override public int getItemType() { - return Type; + return type; } } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/DiffEntity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/DiffEntity.java new file mode 100644 index 000000000..c677ea718 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/DiffEntity.java @@ -0,0 +1,63 @@ +package com.chad.baserecyclerviewadapterhelper.entity; + +import java.util.Objects; + +public class DiffEntity { + + private int id; + private String title; + private String content; + private String date; + + public DiffEntity(int id, String title, String content, String date) { + this.id = id; + this.title = title; + this.content = content; + this.date = date; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof DiffEntity)) return false; + DiffEntity that = (DiffEntity) o; + return id == that.id && Objects.equals(title, that.title) && Objects.equals(content, that.content) && Objects.equals(date, that.date); + } + + @Override + public int hashCode() { + return Objects.hash(id, title, content, date); + } +} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/GroupDemoEntity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/GroupDemoEntity.kt new file mode 100644 index 000000000..077d711c1 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/GroupDemoEntity.kt @@ -0,0 +1,21 @@ +package com.chad.baserecyclerviewadapterhelper.entity + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class GroupDemoEntity( + @Json(name = "group_name") + val groupName: String, + @Json(name = "group_list") + val groupList: List, +) { + + @JsonClass(generateAdapter = true) + data class Group( + @Json(name = "title") + val title: String, + @Json(name = "content") + val content: String, + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeEntity.kt b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeEntity.kt new file mode 100644 index 000000000..2251545b7 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeEntity.kt @@ -0,0 +1,16 @@ +package com.chad.baserecyclerviewadapterhelper.entity + +/** + * @author: limuyang + * @date: 2019-12-06 + * @Description: + */ +data class HomeEntity( + val name: String = "", + val activity: Class<*>? = null, + val imageResource: Int = 0, + val sectionTitle: String = "" +) { + val isSection: Boolean + get() = sectionTitle.isNotBlank() +} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeItem.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeItem.java deleted file mode 100644 index 10268e53b..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/HomeItem.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.entity; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class HomeItem { - private String title; - private Class activity; - private int imageResource; - - public int getImageResource() { - return imageResource; - } - - public void setImageResource(int imageResource) { - this.imageResource = imageResource; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public Class getActivity() { - return activity; - } - - public void setActivity(Class activity) { - this.activity = activity; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level0Item.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level0Item.java deleted file mode 100644 index 2042f85c1..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level0Item.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.entity; - -import com.chad.library.adapter.base.entity.AbstractExpandableItem; -import com.chad.baserecyclerviewadapterhelper.adapter.ExpandableItemAdapter; -import com.chad.library.adapter.base.entity.MultiItemEntity; - -/** - * Created by luoxw on 2016/8/10. - */ -public class Level0Item extends AbstractExpandableItem implements MultiItemEntity { - public String title; - public String subTitle; - - public Level0Item( String title, String subTitle) { - this.subTitle = subTitle; - this.title = title; - } - - @Override - public int getItemType() { - return ExpandableItemAdapter.TYPE_LEVEL_0; - } - - @Override - public int getLevel() { - return 0; - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level1Item.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level1Item.java deleted file mode 100644 index 80ffeafb4..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Level1Item.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.entity; - -import com.chad.library.adapter.base.entity.AbstractExpandableItem; -import com.chad.baserecyclerviewadapterhelper.adapter.ExpandableItemAdapter; -import com.chad.library.adapter.base.entity.MultiItemEntity; - -/** - * Created by luoxw on 2016/8/10. - */ - -public class Level1Item extends AbstractExpandableItem implements MultiItemEntity{ - public String title; - public String subTitle; - - public Level1Item(String title, String subTitle) { - this.subTitle = subTitle; - this.title = title; - } - - @Override - public int getItemType() { - return ExpandableItemAdapter.TYPE_LEVEL_1; - } - - @Override - public int getLevel() { - return 1; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Movie.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Movie.java index 0d634e05f..0aae39366 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Movie.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/Movie.java @@ -11,7 +11,7 @@ public class Movie { public int price; public String content; - public Movie(String name, int length, int price,String content) { + public Movie(String name, int length, int price, String content) { this.length = length; this.name = name; this.price = price; diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MoviePresenter.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MoviePresenter.java index ce91ecd4c..9d03188ef 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MoviePresenter.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MoviePresenter.java @@ -1,7 +1,8 @@ package com.chad.baserecyclerviewadapterhelper.entity; import android.view.View; -import android.widget.Toast; + +import com.chad.baserecyclerviewadapterhelper.utils.Tips; /** * Created by luoxiongwen on 16/10/24. @@ -9,6 +10,6 @@ public class MoviePresenter { public void buyTicket(View view, Movie movie) { - Toast.makeText(view.getContext(), "buy ticket: " + movie.name, Toast.LENGTH_SHORT).show(); + Tips.show("buy ticket: " + movie.name); } } diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MultipleItem.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MultipleItem.java deleted file mode 100644 index 8eefec2dd..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MultipleItem.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.entity; - -import com.chad.library.adapter.base.entity.MultiItemEntity; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class MultipleItem implements MultiItemEntity { - public static final int TEXT = 1; - public static final int IMG = 2; - public static final int IMG_TEXT = 3; - public static final int TEXT_SPAN_SIZE = 3; - public static final int IMG_SPAN_SIZE = 1; - public static final int IMG_TEXT_SPAN_SIZE = 4; - public static final int IMG_TEXT_SPAN_SIZE_MIN = 2; - private int itemType; - private int spanSize; - - public MultipleItem(int itemType, int spanSize, String content) { - this.itemType = itemType; - this.spanSize = spanSize; - this.content = content; - } - - public MultipleItem(int itemType, int spanSize) { - this.itemType = itemType; - this.spanSize = spanSize; - } - - public int getSpanSize() { - return spanSize; - } - - public void setSpanSize(int spanSize) { - this.spanSize = spanSize; - } - - private String content; - - public String getContent() { - return content; - } - - public void setContent(String content) { - this.content = content; - } - - @Override - public int getItemType() { - return itemType; - } -} diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MySection.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MySection.java deleted file mode 100644 index 862be37b8..000000000 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/entity/MySection.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.chad.baserecyclerviewadapterhelper.entity; - -import com.chad.library.adapter.base.entity.SectionEntity; - -/** - * https://github.com/CymChad/BaseRecyclerViewAdapterHelper - */ -public class MySection extends SectionEntity