Skip to content

Fix toolbar drawing under the status bar in 4 appbar screens#60

Merged
hawkff merged 1 commit into
mainfrom
fix-appbar-statusbar-inset
Jun 23, 2026
Merged

Fix toolbar drawing under the status bar in 4 appbar screens#60
hawkff merged 1 commit into
mainfrom
fix-appbar-statusbar-inset

Conversation

@hawkff

@hawkff hawkff commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the toolbar (title + navigate-up/actions) rendering underneath the system status bar (clock/wifi/battery overlap) on four screens:

  • JSON config editor (ConfigEditActivity)
  • QR scanner (ScannerActivity)
  • Assets manager (AssetsActivity)
  • STUN test (StunActivity)

Root cause

Each of these layouts includes the shared appbar with an id on the <include>:

<include android:id="@+id/appbar_include" layout="@layout/layout_appbar" .../>

Putting android:id on an <include> overrides the root id of the included layout, so the included AppBarLayout's own R.id.appbar no longer exists in these layouts.

ThemedActivity (base class) applies the top status-bar inset like this:

findViewById<AppBarLayout>(R.id.appbar)?.apply { updatePadding(top = bars.top) }

Because R.id.appbar was shadowed by appbar_include, this findViewById returned null, so no top padding was applied and the toolbar drew into the status-bar region.

Screens like layout_config_settings.xml render correctly precisely because their <include> has no id, so R.id.appbar survives.

Fix

Drop the android:id="@+id/appbar_include" from the <include> in all four layouts so R.id.appbar survives and ThemedActivity pads it. Since that removes the binding.appbarInclude.toolbar accessor, the toolbar is now resolved via findViewById<Toolbar>(R.id.toolbar) (the same pattern ProfileSettingsActivity already uses).

Scope note

This is a pre-existing bug on main (the appbar_include id was introduced in the earlier merged sora-editor PR #58), independent of the in-flight toolchain PR #59. Fixed here on its own branch to keep that PR focused.

Testing

  • Local JDK 17: :app:compileOssDebugKotlin + :app:processOssDebugResources
  • On device (Redmi Note 9, LineageOS A13, com.nb4a.debug): opened the JSON config editor — the "Config Settings" toolbar now sits cleanly below the status bar. Editor, TextMate themes, line numbers, and extended keyboard unaffected.
  • Other three screens use the identical include/activity pattern, so the same fix applies.

CodeRabbit CLI: no findings.

Greptile Summary

Removes android:id="@+id/appbar_include" from four layout <include> tags so the included AppBarLayout's own R.id.appbar is preserved, allowing ThemedActivity's inset listener to apply the correct top status-bar padding. The corresponding activity code switches from the generated binding.appbarInclude.toolbar accessor to findViewById<Toolbar>(R.id.toolbar), matching the pattern already used by ProfileSettingsActivity.

  • Layouts fixed (layout_assets, layout_edit_config, layout_scanner, layout_stun): remove the android:id from <include layout="@layout/layout_appbar"> so R.id.appbar is not shadowed.
  • Activity code (AssetsActivity, ScannerActivity, StunActivity, ConfigEditActivity): replace binding.appbarInclude.toolbar with findViewById<Toolbar>(R.id.toolbar) to compensate for the removed binding accessor.

Confidence Score: 5/5

Safe to merge — the change is a targeted, well-understood layout fix with no logic changes and no new dependencies.

All eight files change only to remove one attribute from four XML includes and update four toolbar-lookup lines to match the already-established ProfileSettingsActivity pattern. No remaining appbarInclude references exist in the codebase, the fix is consistent across all affected screens, and setContentView is always called before findViewById, so no null-return risk is introduced.

No files require special attention.

Important Files Changed

Filename Overview
app/src/main/res/layout/layout_edit_config.xml Removes android:id from the appbar include, restoring R.id.appbar so ThemedActivity's inset listener can pad it correctly.
app/src/main/res/layout/layout_assets.xml Same one-line removal of android:id from the appbar include as the other three layout files.
app/src/main/res/layout/layout_scanner.xml Same one-line removal of android:id from the appbar include.
app/src/main/res/layout/layout_stun.xml Same one-line removal of android:id from the appbar include.
app/src/main/java/io/nekohasekai/sagernet/ui/profile/ConfigEditActivity.kt Updates toolbar binding to findViewById(R.id.toolbar) and adds an explanatory comment; no functional issues.
app/src/main/java/io/nekohasekai/sagernet/ui/AssetsActivity.kt Switches toolbar lookup to findViewById(R.id.toolbar); clean, matches the ProfileSettingsActivity pattern.
app/src/main/java/io/nekohasekai/sagernet/ui/ScannerActivity.kt Switches toolbar lookup to findViewById(R.id.toolbar); no other changes.
app/src/main/java/io/nekohasekai/sagernet/ui/StunActivity.kt Switches toolbar lookup to findViewById(R.id.toolbar); no other changes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Activity.onCreate()\nsetContentView(binding.root)"] --> B["ThemedActivity\nsetOnApplyWindowInsetsListener"]
    B --> C{"findViewById\nR.id.appbar"}
    C -- "BEFORE (appbar_include id shadowed R.id.appbar)" --> D["null — no padding applied\nToolbar draws under status bar ❌"]
    C -- "AFTER (no id on include)" --> E["AppBarLayout found\nupdatePadding(top = bars.top) ✅"]
    A --> F["setSupportActionBar(...)"]
    F -- "BEFORE" --> G["binding.appbarInclude.toolbar\n(binding accessor from shadowed id)"]
    F -- "AFTER" --> H["findViewById(R.id.toolbar)\n(direct lookup, always resolves)"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["Activity.onCreate()\nsetContentView(binding.root)"] --> B["ThemedActivity\nsetOnApplyWindowInsetsListener"]
    B --> C{"findViewById\nR.id.appbar"}
    C -- "BEFORE (appbar_include id shadowed R.id.appbar)" --> D["null — no padding applied\nToolbar draws under status bar ❌"]
    C -- "AFTER (no id on include)" --> E["AppBarLayout found\nupdatePadding(top = bars.top) ✅"]
    A --> F["setSupportActionBar(...)"]
    F -- "BEFORE" --> G["binding.appbarInclude.toolbar\n(binding accessor from shadowed id)"]
    F -- "AFTER" --> H["findViewById(R.id.toolbar)\n(direct lookup, always resolves)"]
Loading

Reviews (1): Last reviewed commit: "Fix toolbar drawing under the status bar..." | Re-trigger Greptile

The JSON config editor, QR scanner, assets manager, and STUN test screens
rendered their toolbar title/actions underneath the system status bar
(clock/wifi/battery overlap).

Root cause: each layout's `<include layout="@layout/layout_appbar">` carried
android:id="@+id/appbar_include", which overrides the included AppBarLayout's
own R.id.appbar. ThemedActivity applies the top status-bar inset via
findViewById<AppBarLayout>(R.id.appbar) — which returned null in these
layouts, so no top padding was applied.

Fix (matches layout_config_settings, which renders correctly): drop the
android:id from the <include> so R.id.appbar survives and ThemedActivity pads
it. The toolbar is now resolved via findViewById<Toolbar>(R.id.toolbar)
instead of the removed binding.appbarInclude.toolbar accessor.

Affected: layout_edit_config / ConfigEditActivity, layout_scanner /
ScannerActivity, layout_assets / AssetsActivity, layout_stun / StunActivity.

Verified on device (Redmi Note 9, A13): config editor toolbar now sits below
the status bar; editor, themes, and extended keyboard unaffected.
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Four layout files have android:id="@+id/appbar_include" removed from their <include> tags for layout_appbar. The four corresponding activities (AssetsActivity, ScannerActivity, StunActivity, ConfigEditActivity) are updated to call setSupportActionBar(findViewById<Toolbar>(R.id.toolbar)) instead of accessing the toolbar through the view binding's appbarInclude accessor.

Changes

Toolbar Lookup Refactor

Layer / File(s) Summary
Remove appbar_include IDs from layouts
app/src/main/res/layout/layout_assets.xml, app/src/main/res/layout/layout_edit_config.xml, app/src/main/res/layout/layout_scanner.xml, app/src/main/res/layout/layout_stun.xml
android:id="@+id/appbar_include" is removed from the <include> tag referencing @layout/layout_appbar in all four layouts; the included layout itself and its sizing attributes are unchanged.
Switch setSupportActionBar to findViewById
app/src/main/java/io/nekohasekai/sagernet/ui/AssetsActivity.kt, .../ScannerActivity.kt, .../StunActivity.kt, .../profile/ConfigEditActivity.kt
Each activity adds a androidx.appcompat.widget.Toolbar import and replaces binding.appbarInclude.toolbar with findViewById<Toolbar>(R.id.toolbar) in the setSupportActionBar call. ConfigEditActivity also adds comments about inset/padding behavior of the included app bar layout.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~4 minutes

Poem

🐇 Hop, hop, the binding's gone,
appbarInclude — farewell, move on!
findViewById leaps into place,
The toolbar still greets every face.
Same bar, new path — the warren cheers! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: fixing toolbar rendering under the status bar across four screens.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description comprehensively explains the toolbar rendering bug, root cause, fix, and testing performed on the four affected activities.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@hawkff hawkff merged commit f7f4aad into main Jun 23, 2026
8 checks passed
@hawkff hawkff deleted the fix-appbar-statusbar-inset branch June 23, 2026 00:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant