diff --git a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java index de68269e9..e1b61ea7c 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/MainFragment.java @@ -1,6 +1,16 @@ package org.schabi.newpipe.fragments; +import static android.widget.RelativeLayout.ABOVE; +import static android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM; +import static android.widget.RelativeLayout.ALIGN_PARENT_TOP; +import static android.widget.RelativeLayout.BELOW; +import static com.google.android.material.tabs.TabLayout.INDICATOR_GRAVITY_BOTTOM; +import static com.google.android.material.tabs.TabLayout.INDICATOR_GRAVITY_TOP; + import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.graphics.Color; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -9,7 +19,9 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.RelativeLayout; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; @@ -17,6 +29,7 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapterMenuWorkaround; import androidx.preference.PreferenceManager; +import androidx.viewpager.widget.ViewPager; import com.google.android.material.tabs.TabLayout; @@ -29,6 +42,8 @@ import org.schabi.newpipe.settings.tabs.Tab; import org.schabi.newpipe.settings.tabs.TabsManager; import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.ServiceHelper; +import org.schabi.newpipe.util.ThemeHelper; +import org.schabi.newpipe.views.ScrollableTabLayout; import java.util.ArrayList; import java.util.List; @@ -42,8 +57,11 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte private boolean hasTabsChanged = false; - private boolean previousYoutubeRestrictedModeEnabled; + private SharedPreferences prefs; + private boolean youtubeRestrictedModeEnabled; private String youtubeRestrictedModeEnabledKey; + private boolean mainTabsPositionBottom; + private String mainTabsPositionKey; /*////////////////////////////////////////////////////////////////////////// // Fragment's LifeCycle @@ -66,10 +84,11 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte } }); + prefs = PreferenceManager.getDefaultSharedPreferences(requireContext()); youtubeRestrictedModeEnabledKey = getString(R.string.youtube_restricted_mode_enabled); - previousYoutubeRestrictedModeEnabled = - PreferenceManager.getDefaultSharedPreferences(requireContext()) - .getBoolean(youtubeRestrictedModeEnabledKey, false); + youtubeRestrictedModeEnabled = prefs.getBoolean(youtubeRestrictedModeEnabledKey, false); + mainTabsPositionKey = getString(R.string.main_tabs_position_key); + mainTabsPositionBottom = prefs.getBoolean(mainTabsPositionKey, false); } @Override @@ -87,25 +106,27 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte binding.mainTabLayout.setupWithViewPager(binding.pager); binding.mainTabLayout.addOnTabSelectedListener(this); - binding.mainTabLayout.setTabRippleColor(binding.mainTabLayout.getTabRippleColor() - .withAlpha(32)); setupTabs(); + updateTabLayoutPosition(); } @Override public void onResume() { super.onResume(); - final boolean youtubeRestrictedModeEnabled = - PreferenceManager.getDefaultSharedPreferences(requireContext()) - .getBoolean(youtubeRestrictedModeEnabledKey, false); - if (previousYoutubeRestrictedModeEnabled != youtubeRestrictedModeEnabled) { - previousYoutubeRestrictedModeEnabled = youtubeRestrictedModeEnabled; - setupTabs(); - } else if (hasTabsChanged) { + final boolean newYoutubeRestrictedModeEnabled = + prefs.getBoolean(youtubeRestrictedModeEnabledKey, false); + if (youtubeRestrictedModeEnabled != newYoutubeRestrictedModeEnabled || hasTabsChanged) { + youtubeRestrictedModeEnabled = newYoutubeRestrictedModeEnabled; setupTabs(); } + + final boolean newMainTabsPosition = prefs.getBoolean(mainTabsPositionKey, false); + if (mainTabsPositionBottom != newMainTabsPosition) { + mainTabsPositionBottom = newMainTabsPosition; + updateTabLayoutPosition(); + } } @Override @@ -190,6 +211,38 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte setTitle(tabsList.get(tabPosition).getTabName(requireContext())); } + private void updateTabLayoutPosition() { + final ScrollableTabLayout tabLayout = binding.mainTabLayout; + final ViewPager viewPager = binding.pager; + final boolean bottom = mainTabsPositionBottom; + + // change layout params to make the tab layout appear either at the top or at the bottom + final var tabParams = (RelativeLayout.LayoutParams) tabLayout.getLayoutParams(); + final var pagerParams = (RelativeLayout.LayoutParams) viewPager.getLayoutParams(); + + tabParams.removeRule(bottom ? ALIGN_PARENT_TOP : ALIGN_PARENT_BOTTOM); + tabParams.addRule(bottom ? ALIGN_PARENT_BOTTOM : ALIGN_PARENT_TOP); + pagerParams.removeRule(bottom ? BELOW : ABOVE); + pagerParams.addRule(bottom ? ABOVE : BELOW, R.id.main_tab_layout); + tabLayout.setSelectedTabIndicatorGravity( + bottom ? INDICATOR_GRAVITY_TOP : INDICATOR_GRAVITY_BOTTOM); + + tabLayout.setLayoutParams(tabParams); + viewPager.setLayoutParams(pagerParams); + + // change the background and icon color of the tab layout: + // service-colored at the top, app-background-colored at the bottom + tabLayout.setBackgroundColor(ThemeHelper.resolveColorFromAttr(requireContext(), + bottom ? R.attr.colorSecondary : R.attr.colorPrimary)); + + @ColorInt final int iconColor = bottom + ? ThemeHelper.resolveColorFromAttr(requireContext(), R.attr.colorAccent) + : Color.WHITE; + tabLayout.setTabRippleColor(ColorStateList.valueOf(iconColor).withAlpha(32)); + tabLayout.setTabIconTint(ColorStateList.valueOf(iconColor)); + tabLayout.setSelectedTabIndicatorColor(iconColor); + } + @Override public void onTabSelected(final TabLayout.Tab selectedTab) { if (DEBUG) { diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 70f129561..a846b3829 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -270,6 +270,9 @@ caption_settings_key caption_user_set_key + + main_tabs_position + show_search_suggestions show_local_search_suggestions diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index eb774f338..47e5048e5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -222,6 +222,8 @@ Delete entire search history? Search history deleted Fast mode + Move main tab selector to the bottom + Main tabs position Error External storage unavailable diff --git a/app/src/main/res/xml/appearance_settings.xml b/app/src/main/res/xml/appearance_settings.xml index d726e26b7..beb46cdf5 100644 --- a/app/src/main/res/xml/appearance_settings.xml +++ b/app/src/main/res/xml/appearance_settings.xml @@ -66,4 +66,12 @@ app:singleLineTitle="false" app:iconSpaceReserved="false" /> + +