Merge pull request #2871 from atpamat/main-window-tabs

make main page tabs scrollable and hide when there is only a single tab
This commit is contained in:
Tobias Groza 2020-01-02 13:22:01 +01:00 committed by GitHub
commit c56fb8cec2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 132 additions and 2 deletions

View file

@ -30,6 +30,7 @@ import org.schabi.newpipe.settings.tabs.Tab;
import org.schabi.newpipe.settings.tabs.TabsManager; import org.schabi.newpipe.settings.tabs.TabsManager;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.views.ScrollableTabLayout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -37,7 +38,7 @@ import java.util.List;
public class MainFragment extends BaseFragment implements TabLayout.OnTabSelectedListener { public class MainFragment extends BaseFragment implements TabLayout.OnTabSelectedListener {
private ViewPager viewPager; private ViewPager viewPager;
private SelectedTabsPagerAdapter pagerAdapter; private SelectedTabsPagerAdapter pagerAdapter;
private TabLayout tabLayout; private ScrollableTabLayout tabLayout;
private List<Tab> tabsList = new ArrayList<>(); private List<Tab> tabsList = new ArrayList<>();
private TabsManager tabsManager; private TabsManager tabsManager;

View file

@ -0,0 +1,128 @@
package org.schabi.newpipe.views;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayout.Tab;
/**
* A TabLayout that is scrollable when tabs exceed its width.
* Hides when there are less than 2 tabs.
*/
public class ScrollableTabLayout extends TabLayout {
private static final String TAG = ScrollableTabLayout.class.getSimpleName();
private int layoutWidth = 0;
private int prevVisibility = View.GONE;
public ScrollableTabLayout(Context context) {
super(context);
}
public ScrollableTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollableTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
remeasureTabs();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
layoutWidth = w;
}
@Override
public void addTab(@NonNull Tab tab, int position, boolean setSelected) {
super.addTab(tab, position, setSelected);
hasMultipleTabs();
// Adding a tab won't decrease total tabs' width so tabMode won't have to change to FIXED
if (getTabMode() != MODE_SCROLLABLE) {
remeasureTabs();
}
}
@Override
public void removeTabAt(int position) {
super.removeTabAt(position);
hasMultipleTabs();
// Removing a tab won't increase total tabs' width so tabMode won't have to change to SCROLLABLE
if (getTabMode() != MODE_FIXED) {
remeasureTabs();
}
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
// Recheck content width in case some tabs have been added or removed while ScrollableTabLayout was invisible
// We don't have to check if it was GONE because then requestLayout() will be called
if (changedView == this) {
if (prevVisibility == View.INVISIBLE) {
remeasureTabs();
}
prevVisibility = visibility;
}
}
private void setMode(int mode) {
if (mode == getTabMode()) return;
setTabMode(mode);
}
/**
* Make ScrollableTabLayout not visible if there are less than two tabs
*/
private void hasMultipleTabs() {
if (getTabCount() > 1) {
setVisibility(View.VISIBLE);
} else {
setVisibility(View.GONE);
}
}
/**
* Calculate minimal width required by tabs and set tabMode accordingly
*/
private void remeasureTabs() {
if (prevVisibility != View.VISIBLE) return;
if (layoutWidth == 0) return;
final int count = getTabCount();
int contentWidth = 0;
for (int i = 0; i < count; i++) {
View child = getTabAt(i).view;
if (child.getVisibility() == View.VISIBLE) {
// Use tab's minimum requested width should actual content be too small
contentWidth += Math.max(child.getMinimumWidth(), child.getMeasuredWidth());
}
}
if (contentWidth > layoutWidth) {
setMode(TabLayout.MODE_SCROLLABLE);
} else {
setMode(TabLayout.MODE_FIXED);
}
}
}

View file

@ -6,12 +6,13 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout <org.schabi.newpipe.views.ScrollableTabLayout
android:id="@+id/main_tab_layout" android:id="@+id/main_tab_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
app:tabMinWidth="60dp"
app:tabGravity="fill"/> app:tabGravity="fill"/>
<androidx.viewpager.widget.ViewPager <androidx.viewpager.widget.ViewPager