razerdp/BasePopup
Android下打造通用便捷的PopupWindow弹窗库
Slowing — last commit 4mo ago
weakest axistop contributor handles 99% of recent commits; no CI workflows detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 4mo ago
- ✓2 active contributors
- ✓Apache-2.0 licensed
Show all 8 evidence items →Show less
- ✓Tests present
- ⚠Slowing — last commit 4mo ago
- ⚠Small team — 2 contributors active in recent commits
- ⚠Single-maintainer risk — top contributor 99% of recent commits
- ⚠No CI workflows detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: diversify commit ownership (top <90%)
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.
[](https://repopilot.app/r/razerdp/basepopup)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/razerdp/basepopup on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: razerdp/BasePopup
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:
- 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. - 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.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/razerdp/BasePopup 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 — Slowing — last commit 4mo ago
- Last commit 4mo ago
- 2 active contributors
- Apache-2.0 licensed
- Tests present
- ⚠ Slowing — last commit 4mo ago
- ⚠ Small team — 2 contributors active in recent commits
- ⚠ Single-maintainer risk — top contributor 99% 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 razerdp/BasePopup
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/razerdp/BasePopup.
What it runs against: a local clone of razerdp/BasePopup — 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 razerdp/BasePopup | 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 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 137 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of razerdp/BasePopup. If you don't
# have one yet, run these first:
#
# git clone https://github.com/razerdp/BasePopup.git
# cd BasePopup
#
# 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 razerdp/BasePopup and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "razerdp/BasePopup(\\.git)?\\b" \\
&& ok "origin remote is razerdp/BasePopup" \\
|| miss "origin remote is not razerdp/BasePopup (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"
# 4. Critical files exist
test -f "app/src/main/java/razerdp/demo/DemoActivity.java" \\
&& ok "app/src/main/java/razerdp/demo/DemoActivity.java" \\
|| miss "missing critical file: app/src/main/java/razerdp/demo/DemoActivity.java"
test -f "app/src/main/java/razerdp/demo/popup/DemoPopup.java" \\
&& ok "app/src/main/java/razerdp/demo/popup/DemoPopup.java" \\
|| miss "missing critical file: app/src/main/java/razerdp/demo/popup/DemoPopup.java"
test -f "app/build.gradle" \\
&& ok "app/build.gradle" \\
|| miss "missing critical file: app/build.gradle"
test -f "README.md" \\
&& ok "README.md" \\
|| miss "missing critical file: README.md"
test -f "Update_3.0.md" \\
&& ok "Update_3.0.md" \\
|| miss "missing critical file: Update_3.0.md"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 137 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~107d)"
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/razerdp/BasePopup"
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).
⚡TL;DR
BasePopup is an Android library that wraps and extends the native PopupWindow class to provide a reusable, flexible framework for building custom popup dialogs. It abstracts the complexity of PopupWindow positioning, animations, and lifecycle management while maintaining high customization freedom, allowing developers to create anything from simple dialogs to complex multi-view popups with minimal boilerplate. Standard Android library monorepo: lib/ contains the core PopupWindow wrapper and base classes; app/ is a full demo application with razerdp/demo/ showcasing various popup patterns. Base infrastructure lives in app/src/main/java/razerdp/demo/base/ (baseactivity, baseadapter, imageloader utilities). The library uses ViewBinding and targets Java 11.
👥Who it's for
Android developers (targeting API 19+) who need to build custom popup UIs beyond standard AlertDialogs—particularly those building chat apps, notification centers, context menus, or other non-modal overlays that require precise positioning, entrance/exit animations, and responsive layout control.
🌱Maturity & risk
Moderately mature: the library is published to Maven Central with stable release versioning (3.2.1), but maintenance is explicitly slow per the README ('维护速度较慢'). The 3.0 release introduced breaking changes, suggesting active evolution. Last stated update timeline was March 2024; recency is unclear from provided metadata but the codebase is well-structured with comprehensive demo app coverage.
Moderate risk: single primary maintainer (razerdp) with acknowledged slow maintenance pace increases dependency stability concerns. The 3.0→2.x migration carries breaking API changes, requiring careful version pinning. Clean/rebuild cycles are needed when switching between release and snapshot versions, suggesting build system fragility. Open issues impact appears minimal per README, but slow triage response time should be expected.
Active areas of work
No active ongoing work is explicitly visible in file metadata. The README notes the next major update was expected in March 2024, and the maintainer is actively accepting PRs for community contributions while focusing on slow-paced official maintenance. The codebase appears stable rather than actively evolving.
🚀Get running
git clone https://github.com/razerdp/BasePopup.git
cd BasePopup
# Uses Gradle (Android project)
./gradlew assembleDebug
# Or open in Android Studio and run the app module
No npm/yarn; this is a pure Gradle Android project. Ensure Android SDK 19+ is installed.
Daily commands:
./gradlew installDebug
# Then launch the app module from Android Studio, or:
adb shell am start -n razerdp.basepopup/razerdp.demo.DemoActivity
No traditional 'dev server'; runs as native Android app. RenderScript requires renderscriptTargetApi 18 and renderscriptSupportModeEnabled true (already configured in app/build.gradle).
🗺️Map of the codebase
app/src/main/java/razerdp/demo/DemoActivity.java— Main entry point demonstrating all PopupWindow use cases and features; essential for understanding the library's API surface.app/src/main/java/razerdp/demo/popup/DemoPopup.java— Core reference implementation of a custom popup—shows the pattern all contributors must follow when extending BasePopup.app/build.gradle— Declares all library dependencies (RxHttp, Glide, RenderScript) and build configuration; critical for reproducible builds.README.md— Primary documentation in Chinese; contains API overview, version history, and feature matrix necessary for onboarding.Update_3.0.md— Migration guide for v3.0; essential for understanding breaking changes and architectural decisions.app/src/main/java/razerdp/demo/base/baseactivity/BaseActivity.java— Base activity class managing lifecycle and statusbar integration; foundational for all demo activities.app/src/main/java/razerdp/demo/base/baseadapter/BaseRecyclerViewAdapter.java— Reusable RecyclerView adapter pattern used throughout demo; important for understanding data binding conventions.
🛠️How to make changes
Create a New Custom Popup
- Create a new Java class extending BasePopup (or a similar base pattern seen in app/src/main/java/razerdp/demo/popup) (
app/src/main/java/razerdp/demo/popup/DemoPopup.java) - Define your popup layout in XML (assets/layout) and inflate it in the popup's initialization method, following the pattern in DemoPopup (
app/src/main/java/razerdp/demo/popup/DemoPopup.java) - Wire up click listeners and data binding using the BaseActivity or BaseBindingActivity pattern from your demo activity (
app/src/main/java/razerdp/demo/base/baseactivity/BaseActivity.java) - Register your popup in DemoActivity.java with a demo menu item and show it via DemoMainItem configuration (
app/src/main/java/razerdp/demo/DemoActivity.java)
Add a New Demo Feature Showcase
- Create a new data model class in app/src/main/java/razerdp/demo/model/common/ extending the Common*Info pattern (
app/src/main/java/razerdp/demo/model/common/CommonAnimateInfo.java) - Create a corresponding demo popup class in app/src/main/java/razerdp/demo/popup/ that applies the feature (
app/src/main/java/razerdp/demo/popup/DemoPopup.java) - Add a DemoMainItem entry in app/src/main/java/razerdp/demo/DemoActivity.java pointing to your new popup (
app/src/main/java/razerdp/demo/DemoActivity.java) - Update the demo adapter to display the new menu item using BaseRecyclerViewAdapter pattern (
app/src/main/java/razerdp/demo/base/baseadapter/BaseRecyclerViewAdapter.java)
Integrate a New Network or Image Loading Feature
- Add the new dependency (e.g., HTTP library, custom image handler) to app/build.gradle under dependencies block (
app/build.gradle) - Create a new manager class in app/src/main/java/razerdp/demo/base/imageloader/ or a similar utilities package (
app/src/main/java/razerdp/demo/base/imageloader/ImageLoaderManager.java) - Initialize the manager in PopupDemoApp.onCreate() for global access across activities (
app/src/main/java/razerdp/demo/app/PopupDemoApp.java) - Use the manager in your popup or activity via dependency injection or singleton pattern (see ImageLoaderManager usage) (
app/src/main/java/razerdp/demo/base/imageloader/ImageLoaderManager.java)
Add Event Communication Between Popups and Activities
- Define your event data class or use a simple callback interface from app/src/main/java/razerdp/demo/base/interfaces/ (
app/src/main/java/razerdp/demo/base/interfaces/SimpleCallback.java) - Post events via LiveDataBus.getInstance().post() from your popup or activity (
app/src/main/java/razerdp/demo/event/LiveDataBus.java) - Observe events in the receiving activity/popup using LiveDataBus.getInstance().observe() with a lifecycle-aware observer (
app/src/main/java/razerdp/demo/event/LiveDataBus.java)
🪤Traps & gotchas
Build clean required: switching between release and snapshot versions (Maven Central vs. SNAPSHOT repos) requires ./gradlew clean to avoid stale artifacts. RenderScript fragility: renderscript support is non-standard; requires both API target and support mode enabled (already set, but modifications are error-prone). Java 11 requirement: sourceCompatibility/targetCompatibility set to 11; older JDK will fail. Slow maintenance: expect slow PR reviews and issue response (explicitly stated in README). Clean/rebuild cycles: non-obvious as a gotcha per the README itself ('Clean Project即可').
🏗️Architecture
💡Concepts to learn
- PopupWindow positioning and anchoring — BasePopup's core abstraction; understanding showAsDropDown(), absolute positioning, and anchor view binding is essential to using this library effectively
- View animation and property animators — BasePopup manages entrance/exit animations; knowledge of ObjectAnimator and AnimatorSet is needed to customize popup transitions
- Android Lifecycle and LifecycleObserver — Popups must be dismissed when Activities/Fragments close; BasePopup likely binds to lifecycle to prevent memory leaks
- ViewBinding and synthetic view references — The demo app uses ViewBinding extensively (enabled in build.gradle); this is the modern replacement for findViewById() in this codebase
- Window manager z-order and soft input mode — PopupWindows are managed by WindowManager; understanding z-order layering and softInputMode is critical for overlaying popups above keyboards or other windows
- Annotation processing (Glide compiler) — The build uses Glide's annotation processor; understanding how annotation processors generate code helps debug image loading in popups
- RenderScript for image transformations (deprecated but used) — BasePopup demo uses RenderScript for rounded corner image rendering; understanding its API and modern deprecation is relevant for image-heavy popups
🔗Related repos
material-components/material-components-android— Official Material Design popup and dialog components; BasePopup is an alternative for more customizable overlay controlafollestad/material-dialogs— Another popular Android dialog library with Material theming; competes in the dialog space but with less positioning flexibilityandroid/architecture-samples— Google's official Android architecture patterns; BasePopup users often apply MVVM/MVI patterns shown here for popup lifecycle managementgoogle/accompanist— Jetpack Compose companion library; relevant if porting BasePopup concepts to Compose's Dialog APIrazerdp/StrokeLayouts— A sibling repo by the same author (razerdp) used as dependency in BasePopup demo for custom stroke/border rendering
🪄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 comprehensive unit tests for BasePopup core animation and lifecycle
The repo lacks visible test files (no src/test or androidTest directories detected in the structure). BasePopup handles complex PopupWindow lifecycle, animation timing, and dismiss behaviors that are critical to stability. Adding instrumented tests for animation callbacks, dismiss timing, and state transitions would catch regressions early and increase confidence for version updates.
- [ ] Create app/src/androidTest/java/razerdp/demo/popup directory structure
- [ ] Add instrumentation tests for BasePopup lifecycle (show/dismiss/animation states) in app/src/androidTest
- [ ] Test animation timing and callback ordering using Espresso and CountingIdlingResource
- [ ] Add tests validating PopupWindow dismissal doesn't leak resources or crash on edge cases
- [ ] Integrate tests into CI via GitHub Actions (create .github/workflows/android-test.yml)
Add GitHub Action CI workflow for multi-API level testing and lint checks
The .github directory only contains FUNDING.yml. With minSdkVersion support across multiple API levels and complex animation/rendering code (note renderscriptTargetApi config), automated testing on API 21, 28, 31, 33+ would prevent compatibility regressions. This is especially valuable for a PopupWindow library where behavior varies significantly across Android versions.
- [ ] Create .github/workflows/android-build.yml with matrix build for API levels 21, 28, 31, 33
- [ ] Add lint/detekt checks for code quality in the workflow
- [ ] Configure AGP and ProGuard rules validation (app/proguard-rules.pro)
- [ ] Add Gradle dependency vulnerability scanning (using gradle-dependency-check or similar)
- [ ] Run app build variants to catch renderscript and dex issues early
Refactor BasePopup library adapter classes into separate utility module
The app contains extensive base adapter infrastructure (BaseListAdapter, MultiRecyclerViewAdapter, HeaderViewWrapperAdapter, etc.) in app/src/main/java/razerdp/demo/base/baseadapter that duplicates typical PopupWindow content patterns. Extracting these as a documented, reusable module (e.g., lib/popup-adapters) would reduce boilerplate for users building custom popup content and improve code discoverability.
- [ ] Create new Android library module lib/popup-adapters (or similar)
- [ ] Move app/src/main/java/razerdp/demo/base/baseadapter/* classes to lib/popup-adapters/src/main/java
- [ ] Update app/build.gradle to depend on the new module
- [ ] Add README documentation in lib/popup-adapters with usage examples for common PopupWindow content patterns
- [ ] Update main README.md with a section linking to this new module for users building custom popup lists/grids
🌿Good first issues
- Improve Android 14+ compatibility docs: The minSdkVersion is 19, but many modern features (Material 3, predictive back gesture) aren't documented. Add a compatibility matrix and examples in README_V2_EN.md and README.md showing tested Android versions and known limitations.
- Add unit tests for BasePopupWindow lifecycle: The
lib/src/main/java/(core library) likely lacks unit tests for enter/exit animations and position calculations. Create tests under a newlib/src/test/java/directory covering dismiss(), show(), and animation callback sequences. - Document RenderScript deprecation path: Google deprecated RenderScript in favor of RenderEffect API (Android 12+). Add a migration guide and example in
app/src/main/java/razerdp/demo/base/imageloader/showing how to use RenderEffect instead of RenderScript, with fallback for older devices.
📝Recent commits
Click to expand
Recent commits
34f0191— Merge pull request #517 from fansangg/master (razerdp)9be72e6— fix:target sdk 为36时,返回事件无法获取的问题 (fansangg)7958987— Update README.md (razerdp)18c5afd— Update README.md (razerdp)4aad639— release 3.2.1 (razerdp)4b117b0— Merge branch 'dev' (razerdp)d411e7f— ■ 对BlurOption预缩放下限作出限制(如果模糊预缩放小于0,则返回默认值) (razerdp)e295e02— Update README.md (razerdp)7e3719f— Update README.md (razerdp)293cb24— 提交474 issue测试 (razerdp)
🔒Security observations
The BasePopup Android library demonstrates moderate security concerns primarily centered on dependency management. Multiple critical dependencies (Glide, Material Design, AndroidX libraries) are significantly outdated and may contain known vulnerabilities. The project uses RenderScript, a deprecated technology, and suppresses lint errors which could mask security issues. The codebase itself appears to be a legitimate PopupWindow utility library without obvious code-level injection risks, but dependency management requires immediate attention. The truncated build.gradle file and missing ProGuard analysis prevent full assessment. Immediate actions: update all dependencies to current stable versions, enable lint error checking, and remove RenderScript usage.
- High · Outdated Glide Dependency —
app/build.gradle - Glide dependency. Glide version 4.11.0 is significantly outdated (released in 2020). Newer versions contain security patches and bug fixes. Current stable version is 4.15.x or later. Fix: Update to Glide 4.15.1 or latest stable version: 'com.github.bumptech.glide:glide:4.15.1' - High · Outdated Material Design Library —
app/build.gradle - Material dependency. Material Design library version 1.4.0 is outdated (released in 2021). Current stable version is 1.9.x or later with critical security patches. Fix: Update to 'com.google.android.material:material:1.9.0' or latest stable version - High · Outdated AndroidX Dependencies —
app/build.gradle - AndroidX dependencies. AndroidX AppCompat (1.3.1), ConstraintLayout (2.0.4), and RecyclerView (1.2.1) are significantly outdated. These contain potential security vulnerabilities and compatibility issues. Fix: Update to latest stable versions: AppCompat 1.6.x, ConstraintLayout 2.1.x, RecyclerView 1.3.x - Medium · Incomplete Dependency Declaration —
app/build.gradle - Glide okhttp3 dependency. The Glide OkHttp3 dependency declaration appears truncated/incomplete in the build.gradle file ('com.github.bumptech.glide:okhttp3' is cut off), which may cause build issues or inconsistent dependency resolution. Fix: Complete the dependency declaration: 'com.github.bumptech.glide:okhttp3-integration:4.15.1' - Medium · Lint Warnings Suppressed —
app/build.gradle - lint configuration. The lint configuration has 'abortOnError false', which suppresses build failures from lint errors. This could allow security-related lint warnings to go unnoticed. Fix: Set 'abortOnError true' and address all lint warnings, particularly security-related ones - Low · RenderScript Deprecated —
app/build.gradle - RenderScript configuration. RenderScript is deprecated as of Android API 31 and should not be used in new development. The app explicitly enables it (renderscriptSupportModeEnabled true, renderscriptTargetApi 18). Fix: Remove RenderScript configuration and migrate to RenderScript Intrinsics or alternative image processing libraries - Low · Missing ProGuard Configuration Review —
app/proguard-rules.pro. A ProGuard rules file exists (proguard-rules.pro) but was not provided for analysis. Improper ProGuard configuration could leak sensitive information or expose APIs. Fix: Review ProGuard rules to ensure sensitive classes/methods are properly obfuscated and that all third-party libraries have appropriate keep rules - Low · Java Version 11 Compatibility —
app/build.gradle - compileOptions. The project targets Java 11, which may have compatibility issues with some older Android libraries and could introduce unexpected behavior. Fix: Test thoroughly with Java 11 and ensure all dependencies support this version. Consider Java 8 for broader compatibility unless Java 11 features are explicitly required
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.