RepoPilotOpen in app →

youth5201314/banner

🔥🔥🔥Banner 2.0 来了!Android广告图片轮播控件,内部基于ViewPager2实现,Indicator和UI都可以自定义。

Mixed

Stale — last commit 2y ago

weakest axis
Use as dependencyMixed

last commit was 2y ago; no CI workflows detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 2y ago; no CI workflows detected

  • 13 active contributors
  • Apache-2.0 licensed
  • Tests present
Show all 6 evidence items →
  • Stale — last commit 2y ago
  • Single-maintainer risk — top contributor 85% of recent commits
  • No CI workflows detected
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/youth5201314/banner?axis=fork)](https://repopilot.app/r/youth5201314/banner)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/youth5201314/banner on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: youth5201314/banner

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/youth5201314/banner shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Stale — last commit 2y ago

  • 13 active contributors
  • Apache-2.0 licensed
  • Tests present
  • ⚠ Stale — last commit 2y ago
  • ⚠ Single-maintainer risk — top contributor 85% of recent commits
  • ⚠ No CI workflows detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live youth5201314/banner repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/youth5201314/banner.

What it runs against: a local clone of youth5201314/banner — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in youth5201314/banner | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | Last commit ≤ 878 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>youth5201314/banner</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of youth5201314/banner. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/youth5201314/banner.git
#   cd banner
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of youth5201314/banner and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "youth5201314/banner(\\.git)?\\b" \\
  && ok "origin remote is youth5201314/banner" \\
  || miss "origin remote is not youth5201314/banner (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 878 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~848d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/youth5201314/banner"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Banner 2.0 is an Android carousel/banner control library built on ViewPager2 that displays image ads with automatic rotation. It provides a lightweight, customizable rotation container with pluggable indicators and page transition effects (Depth, ZoomOut, Rotate, Scale, Alpha), supporting both horizontal and vertical orientations, gallery effects, and integration with RecyclerView. Monorepo with two modules: /app (example application with 8 demo activities) and /banner (the library root, not visible in file tree but referenced in gradle). App contains adapters (/adapter: ImageAdapter, ImageNetAdapter, MultipleTypesAdapter), custom viewholders (/viewholder: ImageHolder, VideoHolder), and demo UIs (/ui: BannerFragment, GalleryActivity, RecyclerViewBannerActivity, VideoActivity). Utility classes like ParentRecyclerView and TabLayoutMediator handle edge cases.

👥Who it's for

Android developers building e-commerce, news, or content apps who need a carousel UI component for image ads without reinventing ViewPager2 animations and indicator logic. Specifically developers wanting to avoid intrusive UI frameworks and retain full control over layout and styling.

🌱Maturity & risk

Actively maintained and production-ready. The codebase demonstrates maturity with 154KB of Java code, support for androidx/ViewPager2, and evidence of use in "multiple million-user level APPs" per the README. Latest version is 2.2.1 (from gradle comment). However, no visible CI/CD pipeline or automated test suite in the file list is a minor concern.

Relatively low risk for a mature carousel library. Single maintainer (youth5201314) creates some dependency risk, but the library has minimal external dependencies (only ViewPager2 from androidx). The README suggests occasional issue reproducibility challenges; no breaking changes evident in current structure, though ViewPager2 dependency should be monitored for AndroidX updates.

Active areas of work

No commit history visible in provided data. The library appears in steady-state maintenance: the README indicates the maintainer is responsive to issues but focuses on bug fixes and demo improvements rather than feature churn. Version 2.2.1 is current (gradle reference). Focus appears to be on demo completeness (7 distinct example activities covering fragments, RecyclerView nesting, video, TV, gallery modes).

🚀Get running

git clone https://github.com/youth5201314/banner.git
cd banner
# Build with Gradle (no explicit ./gradlew wrapper visible, assume Android Studio gradle)
gradle build
# Or import into Android Studio and run the app module on an emulator/device

Daily commands: Import the /app module into Android Studio. Configure a device/emulator. Run gradle installDebug or click Run in Android Studio to launch MainActivity. The app will display demo carousels with various configurations (image-only, image+title, video, gallery, Meizu effect, headline ticker).

🗺️Map of the codebase

🛠️How to make changes

Adding a new carousel effect: extend PageTransformer and register via banner.addPageTransformer() (see existing transforms in library code). Custom indicator: implement Indicator interface and call setIndicator(). Custom item UI: extend BannerAdapter and override onCreateViewHolder() in /app/src/main/java/com/test/banner/adapter/ (reference ImageTitleAdapter.java, ImageNetAdapter.java as templates). Adding demo activity: create new Activity in /app/src/main/java/com/test/banner/ui/, add to AndroidManifest.xml, instantiate Banner and configure via fluent API.

🪤Traps & gotchas

ViewPager2 alpha dependency: the gradle references androidx.viewpager2:viewpager2:1.1.0-alpha01 (not final release; consider upgrading to latest stable in production). RecyclerView nesting complexity: nested Banner inside RecyclerView requires custom ParentRecyclerView and careful touch delegation (see ParentRecyclerView.java); naive ViewPager2 nesting will lose scroll responsiveness. Lifecycle management critical: Banner.start()/stop() must be manually wired to Activity/Fragment onStart/onStop (demo activities show this but easy to forget). Infinite loop requires 2+ items: setting adapter with enableLoop=true on 0-1 item lists will cause unexpected behavior (library assumes >= 2 items for modulo wrapping). ProGuard minification enabled in debug builds: app/build.gradle sets minifyEnabled=true in debug config; can hide errors; disable for initial development.

💡Concepts to learn

  • ViewPager2 and Infinite Scrolling with ModuloWrapping — Banner's carousel loops endlessly; understanding ViewPager2's position wrapping (e.g., converting item 0 ↔ getRealCount() for visual infinity) is essential to modifying rotation behavior or debugging click-position mismatches.
  • PageTransformer and View Animation Composition — Banner's built-in effects (Depth, Rotate, ZoomOut) are PageTransformer implementations that interpolate view properties during transitions; understanding how addPageTransformer() chains multiple effects is critical to customizing motion.
  • RecyclerView Touch Event Propagation and Nested Scrolling — Banner nested in RecyclerView requires ParentRecyclerView.java workaround to prevent scroll conflicts; understanding NestedScrollingParent/NestedScrollingChild protocol and requestDisallowInterceptTouchEvent() is vital for horizontal carousels in vertical lists.
  • Adapter Pattern and ViewHolder Binding — Banner's BannerAdapter + ViewHolder design mirrors RecyclerView.Adapter; understanding item recycling, onCreateViewHolder, and onBindViewHolder is prerequisite to extending Banner with custom item types (see MultipleTypesAdapter.java).
  • Lifecycle Management and AutoStart/Stop Patterns — Banner.start()/stop() must sync with Activity/Fragment lifecycle to prevent memory leaks (rotating items in a destroyed context); failing to wire this causes ANRs and resource leaks in production.
  • Fluent Builder API and Method Chaining — Banner uses chainable configuration methods (setAdapter().setIndicator().setLoopTime()…); understanding fluent interfaces and return-this patterns is expected for both users and maintainers extending the API.
  • Handler-based Timer and Auto-rotation Scheduling — Banner's setLoopTime() / isAutoLoop() internally likely use Handler.postDelayed() to trigger carousel rotation; understanding Android's Handler/Looper threading model is necessary to debug rotation timing issues or implement pause/resume.
  • facebook/fresco — Image loading and caching library commonly paired with Banner for efficient carousel image management; handles memory pooling and placeholder strategies.
  • android/architecture-components-samples — Official Android architecture samples; demonstrates proper ViewModel + Lifecycle integration patterns that Banner.start()/stop() should follow in production apps.
  • samlss/Broccoli — Alternative carousel library using RecyclerView directly (not ViewPager2); useful comparison if Broccoli's approach (or limitations) interests contributors evaluating design tradeoffs.
  • gongwen/MarqueeView — Vertical scrolling ticker library; complements Banner for news/headline feeds (see Banner's TouTiaoActivity demo which attempts similar UX).
  • android/compose-samples — Jetpack Compose equivalents for carousel UI; future-proofing reference if Banner maintainer decides to offer Compose migration path.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for BannerViewPager2 core functionality

The repository has multiple adapter implementations (ImageAdapter, ImageNetAdapter, MultipleTypesAdapter, etc.) but no visible test directory. Adding unit tests for the banner's core ViewPager2 behavior would improve reliability and make it easier for contributors to validate changes. This is especially important for a carousel library where edge cases around page transitions, infinite scrolling, and indicator synchronization are critical.

  • [ ] Create app/src/test/java/com/test/banner directory structure
  • [ ] Add unit tests for banner indicator synchronization with ViewPager2
  • [ ] Add tests for adapter behavior with different data sizes (empty, single item, multiple items)
  • [ ] Add tests for gallery and vertical scrolling mode configurations
  • [ ] Consider using Robolectric for View-related tests if needed

Create Proguard rules documentation and expand proguard-rules.pro

The app/proguard-rules.pro file exists but the repository uses minifyEnabled=true in debug builds, which is unusual and suggests potential ProGuard-related issues. The banner library likely needs specific ProGuard rules that aren't documented. Creating comprehensive ProGuard rules and documentation would help users avoid crashes when minifying their apps that depend on this library.

  • [ ] Document current ProGuard rules in app/proguard-rules.pro with comments explaining ViewPager2-related rules
  • [ ] Add specific rules for BaseRecyclerViewAdapterHelper (BRVAH 3.0.2) which is a dependency
  • [ ] Add rules for Glide (4.12.0) integration in ImageNetAdapter
  • [ ] Create PROGUARD.md file documenting best practices for library users
  • [ ] Consider removing minifyEnabled=true from debug builds in build.gradle as this is non-standard

Add instrumentation tests for Banner in RecyclerView and Fragment contexts

The file structure shows multiple integration scenarios (RecyclerViewBannerActivity, BannerFragment, Vp2FragmentRecyclerviewActivity, BannerListFragment) but no androidTest directory. These are real-world usage patterns that need validation. Instrumentation tests would ensure the banner works correctly when nested in RecyclerViews, Fragments, and complex layouts—common pain points for ViewPager2 libraries.

  • [ ] Create app/src/androidTest/java/com/test/banner directory
  • [ ] Add instrumentation test for BannerFragment lifecycle and state restoration
  • [ ] Add tests for banner inside RecyclerView (test scroll behavior doesn't conflict with banner scroll)
  • [ ] Add tests for Vp2FragmentRecyclerviewActivity composition
  • [ ] Test indicator synchronization during rotation and configuration changes

🌿Good first issues

  • Add automated UI tests for carousel rotation: The /app module has zero visible test files (no /test or /androidTest directories). Create AndroidTest class in app/src/androidTest/java/com/test/banner/ using Espresso to verify Banner rotation timing (setLoopTime), item click callbacks (OnBannerListener), and indicator state sync. Start with ImageAdapter activity.
  • Document PageTransformer composition: The README lists 7 built-in transformers (AlphaPageTransformer, DepthPageTransformer, etc.) but provides no code example of combining multiple via addPageTransformer(). Add a new demo Activity (e.g., ComposedTransformActivity.java) in /app/src/main/java/com/test/banner/ui/ that chains 2-3 transformers and document the result in README with before/after GIF.
  • Create Kotlin interop guide: Repo is 97.5% Java, 2.5% Kotlin. Junior contributors unfamiliar with Java-to-Kotlin Banner usage will struggle. Add a new file app/src/main/java/com/test/banner/KotlinExampleActivity.kt showing Banner setup in Kotlin (leveraging extension functions, apply blocks) and document gotchas (null safety, SAM conversions for listeners). Reference existing Java MainActivity for feature parity.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 777c7db — 更新viewpager版本 (youth5201314)
  • b82bf41 — Merge pull request #1039 from youth5201314/revert-1037-master (youth5201314)
  • 751223b — Revert "增加一屏多页(大于三页)的功能" (youth5201314)
  • f9b2610 — Merge pull request #1037 from gyf-dev/master (youth5201314)
  • 5e9a29b — 增加一屏多页(大于三页)的功能 (gyf-dev)
  • 39ff0ca — kotlin中使用banner的demo修改 (youth5201314)
  • 2866247 — Merge remote-tracking branch 'origin/dev-vp2' (youth5201314)
  • a2c7ba6 — bug修复,kotlin使用demo修改 (youth5201314)
  • 0e334ea — Merge branch 'release-2.2.0' (youth5201314)
  • 97f262c — 删除gradle.properties (youth5201314)

🔒Security observations

  • High · Outdated ViewPager2 Dependency — app/build.gradle - dependencies section. The project uses androidx.viewpager2:viewpager2:1.1.0-alpha01, which is an alpha version released before the stable 1.0.0. Alpha versions are not production-ready and may contain unpatched security vulnerabilities and stability issues. Fix: Update to the latest stable version of ViewPager2 (currently 1.0.0 or higher). Replace '1.1.0-alpha01' with a stable release version.
  • High · Outdated Material Design Dependency — app/build.gradle - dependencies section. The project uses com.google.android.material:material:1.2.0-alpha06, which is an alpha version. Alpha versions may have security vulnerabilities, stability issues, and incomplete feature implementations. Fix: Update to the latest stable version of Material Design library (1.3.0 or higher). Replace 'com.google.android.material:material:1.2.0-alpha06' with a stable release.
  • Medium · Outdated AppCompat Dependency — app/build.gradle - dependencies section. The project uses androidx.appcompat:appcompat:1.1.0 which is significantly outdated (released in 2019). This version may contain security vulnerabilities that have been patched in newer releases. Fix: Update to the latest stable version of AppCompat (1.6.0 or higher) to receive security patches and bug fixes.
  • Medium · Outdated Glide Image Library — app/build.gradle - dependencies section. The project uses com.github.bumptech.glide:glide:4.12.0 which is outdated. While Glide is a reputable library, outdated versions may lack security patches for image processing vulnerabilities. Fix: Update Glide to version 4.15.0 or higher for security patches and performance improvements.
  • Medium · Outdated ConstraintLayout Dependency — app/build.gradle - dependencies section. The project uses androidx.constraintlayout:constraintlayout:1.1.3 which is significantly outdated (released in 2019). This may contain unpatched vulnerabilities. Fix: Update to androidx.constraintlayout:constraintlayout:2.1.4 or higher for security patches.
  • Medium · Outdated RecyclerView Dependency — app/build.gradle - dependencies section. The project uses androidx.recyclerview:recyclerview:1.2.0 which is outdated. RecyclerView handles user input and rendering, making it a potential attack surface. Fix: Update to androidx.recyclerview:recyclerview:1.3.0 or higher.
  • Medium · Debug Build Minification Enabled — app/build.gradle - buildTypes.debug section. The debug build configuration has minifyEnabled set to true. This can make debugging harder and may introduce obfuscation-related issues during development. While not a direct security vulnerability, it hinders security analysis during development. Fix: Consider disabling minification for debug builds to ease development and debugging: set minifyEnabled to false for the debug variant.
  • Low · Outdated ButterKnife Dependency — app/build.gradle - dependencies section. The project uses com.jakewharton:butterknife:10.2.3 which is outdated. While view binding alternatives are now recommended, this version may lack recent fixes. Fix: Consider migrating to Android's native View Binding or migrate ButterKnife to the latest version (10.2.3 is current, but view binding is the modern approach).
  • Low · Outdated Dependency: BaseRecyclerViewAdapterHelper — app/build.gradle - dependencies section. The project uses com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.2 which is an external third-party library. Ensure this library is maintained and receives security updates. Fix: Verify that this library is actively maintained. Check the GitHub

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · youth5201314/banner — RepoPilot