Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/src/main/java/org/schabi/newpipe/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ protected void onCreate(final Bundle savedInstanceState) {

WindowInsetsHelper.applyStatusBarInsets(this, toolbarLayoutBinding.toolbar,
mainBinding.fragmentHolder);
// Edge-to-edge (targetSdk 35+): keep the main content (feed/search/channel/playlist lists,
// and the bottom tab strip) above the system navigation bar.
WindowInsetsHelper.applyNavigationBarInsets(mainBinding.fragmentHolder);

if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
initFragments();
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/org/schabi/newpipe/about/AboutActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class AboutActivity : AppCompatActivity() {
aboutAppVersion.text = BuildConfig.VERSION_NAME
aboutGithubLink.openLink(R.string.github_url)
aboutDonationLink.openLink(R.string.donation_url)
// Edge-to-edge (targetSdk 35+): keep the bottom of the page above the nav bar.
WindowInsetsHelper.applyNavigationBarInsets(root)
return root
}
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/org/schabi/newpipe/about/LicenseFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.schabi.newpipe.R
import org.schabi.newpipe.about.LicenseFragmentHelper.showLicense
import org.schabi.newpipe.databinding.FragmentLicensesBinding
import org.schabi.newpipe.databinding.ItemSoftwareComponentBinding
import org.schabi.newpipe.util.WindowInsetsHelper

/**
* Fragment containing the software licenses.
Expand Down Expand Up @@ -67,6 +68,8 @@ class LicenseFragment : Fragment() {
registerForContextMenu(root)
}
activeLicense?.let { compositeDisposable.add(showLicense(activity, it)) }
// Edge-to-edge (targetSdk 35+): keep the bottom of the licenses list above the nav bar.
WindowInsetsHelper.applyNavigationBarInsets(binding.root)
return binding.root
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ protected void onCreate(final Bundle savedInstanceState) {
setSupportActionBar(downloaderBinding.toolbarLayout.toolbar);

WindowInsetsHelper.applyStatusBarInsets(this, downloaderBinding.toolbarLayout.toolbar);
// Edge-to-edge (targetSdk 35+): keep the bottom of the downloads list above the nav bar.
WindowInsetsHelper.applyNavigationBarInsets(downloaderBinding.frame);

final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/org/schabi/newpipe/error/ErrorActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ protected void onCreate(final Bundle savedInstanceState) {
WindowInsetsHelper.applyStatusBarInsets(this,
activityErrorBinding.toolbarLayout.toolbar,
activityErrorBinding.scrollView);
// Edge-to-edge (targetSdk 35+): keep the bottom of a long error report above the nav bar.
WindowInsetsHelper.applyNavigationBarInsets(activityErrorBinding.scrollView);

final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ protected void onCreate(final Bundle savedInstanceState) {

WindowInsetsHelper.applyStatusBarInsets(this, recaptchaBinding.toolbar,
recaptchaBinding.reCaptchaWebView);
// Edge-to-edge (targetSdk 35+): keep the captcha web view content above the nav bar.
WindowInsetsHelper.applyNavigationBarInsets(recaptchaBinding.reCaptchaWebView);

final String url = sanitizeRecaptchaUrl(getIntent().getStringExtra(RECAPTCHA_URL_EXTRA));
// set return to Cancel by default
Expand Down
16 changes: 0 additions & 16 deletions app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapterMenuWorkaround;
Expand Down Expand Up @@ -107,17 +105,6 @@ protected void initViews(final View rootView, final Bundle savedInstanceState) {
binding.mainTabLayout.setTabRippleColor(binding.mainTabLayout.getTabRippleColor()
.withAlpha(32));

// Edge-to-edge (targetSdk 35+): when the tab strip is moved to the bottom it sits behind the
// system navigation bar (tabs unclickable). Pad it by the nav-bar inset; the pager is laid
// out relative to the tab strip so it follows automatically. requestApplyInsets() in
// updateTabLayoutPosition() re-runs this when the user toggles the position.
ViewCompat.setOnApplyWindowInsetsListener(binding.mainTabLayout, (v, insets) -> {
final int navBottom = mainTabsPositionBottom
? insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom : 0;
v.setPadding(v.getPaddingLeft(), v.getPaddingTop(), v.getPaddingRight(), navBottom);
return insets;
});

setupTabs();
updateTabLayoutPosition();
}
Expand Down Expand Up @@ -248,9 +235,6 @@ private void updateTabLayoutPosition() {
tabLayout.setTabRippleColor(ColorStateList.valueOf(iconColor).withAlpha(32));
tabLayout.setTabIconTint(ColorStateList.valueOf(iconColor));
tabLayout.setSelectedTabIndicatorColor(iconColor);

// Re-apply the nav-bar inset padding for the new position (added at bottom, cleared at top).
ViewCompat.requestApplyInsets(tabLayout);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -722,21 +722,6 @@ protected void initViews(final View rootView, final Bundle savedInstanceState) {
pageAdapter = new TabAdapter(getChildFragmentManager());
binding.viewPager.setAdapter(pageAdapter);
binding.tabLayout.setupWithViewPager(binding.viewPager);
// Edge-to-edge (targetSdk 35+): the bottom tab strip is laid out gravity=bottom, so without
// insets it sits behind the system navigation bar (tabs unclickable) and the pager's last
// item runs under it. Pad the tab strip by the nav-bar inset and grow the pager's bottom
// padding (its XML 48dp tab clearance) by the same amount so content clears both.
final int viewPagerBottomBase = binding.viewPager.getPaddingBottom();
ViewCompat.setOnApplyWindowInsetsListener(binding.tabLayout, (v, insets) -> {
final int navBottom = insets.getInsets(
WindowInsetsCompat.Type.navigationBars()).bottom;
v.setPadding(v.getPaddingLeft(), v.getPaddingTop(), v.getPaddingRight(), navBottom);
binding.viewPager.setPadding(binding.viewPager.getPaddingLeft(),
binding.viewPager.getPaddingTop(), binding.viewPager.getPaddingRight(),
viewPagerBottomBase + navBottom);
return insets;
});
ViewCompat.requestApplyInsets(binding.tabLayout);
updateStickyPlayerMode();

binding.detailThumbnailRootLayout.requestFocus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ protected void onCreate(Bundle savedInstanceState) {

recyclerView = findViewById(R.id.filter_list);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
// Edge-to-edge (targetSdk 35+): keep the bottom of the filter list above the nav bar.
WindowInsetsHelper.applyNavigationBarInsets(recyclerView);

sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
loadFilterItems();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ protected void onCreate(final Bundle savedInstanceBundle) {
WindowInsetsHelper.applyStatusBarInsets(this,
settingsLayoutBinding.settingsToolbarLayout.toolbar,
settingsLayoutBinding.settingsFragmentHolder);
// Edge-to-edge (targetSdk 35+): keep the last preference entry on long, scrollable
// settings pages above the system navigation bar.
WindowInsetsHelper.applyNavigationBarInsets(settingsLayoutBinding.settingsFragmentHolder);

if (restored) {
// Restore state
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/org/schabi/newpipe/util/WindowInsetsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,24 @@ public static void applyStatusBarInsets(@NonNull final AppCompatActivity activit
});
}

/**
* Pads the bottom of a content view by the navigation-bar inset, so its last items stay above
* the system navigation bar in edge-to-edge (targetSdk 35+). Used on the main fragment holder
* so feed/search/channel/playlist lists are not drawn behind the nav bar.
*/
public static void applyNavigationBarInsets(@NonNull final View content) {
final int initialLeft = content.getPaddingLeft();
final int initialTop = content.getPaddingTop();
final int initialRight = content.getPaddingRight();
final int initialBottom = content.getPaddingBottom();

ViewCompat.setOnApplyWindowInsetsListener(content, (view, insets) -> {
final Insets navBars = insets.getInsets(WindowInsetsCompat.Type.navigationBars());
view.setPadding(initialLeft, initialTop, initialRight, initialBottom + navBars.bottom);
return insets;
});
}

private static int getActionBarSize(@NonNull final AppCompatActivity activity) {
final TypedValue typedValue = new TypedValue();
if (activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.util.WindowInsetsHelper;

public abstract class BaseLoginWebViewActivity extends AppCompatActivity {

Expand All @@ -18,6 +19,8 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.login_webview);

webView = findViewById(R.id.login_webview);
// Edge-to-edge (targetSdk 35+): keep the bottom of the login page above the nav bar.
WindowInsetsHelper.applyNavigationBarInsets(webView);
configureWebView();
webView.setWebViewClient(createWebViewClient());
loadLoginUrl();
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
android:layout_gravity="center_horizontal"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:paddingBottomSystemWindowInsets="true"
app:layout_behavior="org.schabi.newpipe.player.event.CustomBottomSheetBehavior" />

</org.schabi.newpipe.views.FocusAwareCoordinator>
Expand Down