Die Symbolleiste in AppBarLayout ist scrollbar, obwohl RecyclerView nicht genügend Inhalt zum Scrollen hat

Lesezeit: 14 Minuten

Benutzer-Avatar
eiki

Ist es wirklich beabsichtigt, dass die Toolbar in einem AppBarLayout scrollbar ist, obwohl der Hauptcontainer mit dem „appbar_scrolling_view_behavior“ nicht genug Inhalt hat, um wirklich scrollen zu können?

Was ich bisher getestet habe:
Wenn ich ein NestedScrollView (mit “wrap_content”-Attribut) als Hauptcontainer und ein TextView als untergeordnetes Element verwende, funktioniert das AppBarLayout ordnungsgemäß und scrollt nicht.

Wenn ich jedoch eine RecyclerView mit nur wenigen Einträgen und dem Attribut “wrap_content” verwende (damit kein Scrollen erforderlich ist), ist die Symbolleiste im AppBarLayout scrollbar, obwohl die RecyclerView nie ein Scroll-Ereignis erhält (getestet mit einem OnScrollChangeListener ).

Hier ist mein Layout-Code:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:theme="@style/ToolbarStyle" />
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

Mit folgendem Effekt, dass die Symbolleiste scrollbar ist, obwohl es nicht notwendig ist:

Ich habe auch einen Weg gefunden, damit umzugehen, indem ich prüfe, ob alle RecyclerView-Elemente sichtbar sind, und die Methode setNestedScrollingEnabled() von RecyclerView verwende.
Trotzdem scheint es mir eher ein Bug zu sein, als beabsichtigt. Irgendwelche Meinungen? 😀

EDIT #1:

Für Leute, die an meiner aktuellen Lösung interessiert sind, musste ich die setNestedScrollingEnabled() -Logik in die postDelayed() -Methode eines Handlers mit 5 ms Verzögerung einfügen, da der LayoutManager beim Aufrufen der Methoden immer -1 zurückgab, um dies herauszufinden ob das erste und das letzte Element sichtbar sind.
Ich verwende diesen Code in der Methode onStart() (nachdem meine RecyclerView initialisiert wurde) und jedes Mal, wenn eine Inhaltsänderung der RecyclerView auftritt.

final LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        //no items in the RecyclerView
        if (mRecyclerView.getAdapter().getItemCount() == 0)
            mRecyclerView.setNestedScrollingEnabled(false);
        //if the first and the last item is visible
        else if (layoutManager.findFirstCompletelyVisibleItemPosition() == 0
                && layoutManager.findLastCompletelyVisibleItemPosition() == mRecyclerView.getAdapter().getItemCount() - 1)
            mRecyclerView.setNestedScrollingEnabled(false);
        else
            mRecyclerView.setNestedScrollingEnabled(true);
    }
}, 5);

EDIT #2:

Ich habe gerade mit einer neuen App herumgespielt und es scheint, dass dieses (unbeabsichtigte) Verhalten in der Support-Bibliotheksversion 23.3.0 (oder sogar früher) behoben wurde. Somit sind keine Workarounds mehr erforderlich!

  • Meine Meinung ist, dass es beabsichtigt ist. Dies wurde hier mehrfach gefragt, und wenn dies ein Fehler wäre, hätten sie ihn schon früher behoben – die Designbibliothek ist nicht mehr so ​​jung.

    – natürlich

    7. September 2015 um 17:39 Uhr

  • Danke für die Antwort. Da ich die genannten Antworten/Diskussionen nicht selbst gefunden habe, könnten Sie bitte zumindest eine Ihrer Quellen posten.

    – eiki

    13. September 2015 um 11:21 Uhr

  • Es ist kein Fehler, alle Ereignisse in einer viewGroup werden auf diese Weise behandelt. Da Ihr recyclerview ein untergeordnetes Element von coordinatorLayout ist, wird es bei jedem Generieren des Ereignisses zuerst auf das übergeordnete Element überprüft, und wenn das übergeordnete Element nicht interessiert ist, wird es nur an das untergeordnete Element weitergegeben.

    – Sulabh Deep Puri

    2. November 2015 um 6:41 Uhr


  • Ich habe in der Material Design-Spezifikation keinen Hinweis darauf gefunden, aber basierend auf dem Wie Posteingang von Gmail und Google Play (Meine Wunschliste) funktioniert derzeit. Es scheint, dass das richtige Verhalten darin besteht, die App-Leiste nur wegzuscrollen, wenn genügend Inhalt zum Scrollen vorhanden ist.

    – joelpet

    1. Februar 2016 um 13:13 Uhr

  • Überprüfen Sie stackoverflow.com/a/61941446/5745574

    – Vipul Kumar

    21. Mai 2020 um 18:39 Uhr

Benutzer-Avatar
Benutzer3623735

Bearbeiten 2:

Es stellt sich heraus, dass die einzige Möglichkeit, um sicherzustellen, dass die Symbolleiste nicht scrollbar ist, wenn RecyclerView nicht scrollbar ist, darin besteht, setScrollFlags programmgesteuert zu setzen, wodurch überprüft werden muss, ob RecyclerView scrollbar ist. Diese Überprüfung muss bei jeder Änderung des Adapters durchgeführt werden.

Schnittstelle zur Kommunikation mit der Aktivität:

public interface LayoutController {
    void enableScroll();
    void disableScroll();
}

Hauptaktivität:

public class MainActivity extends AppCompatActivity implements 
    LayoutController {

    private CollapsingToolbarLayout collapsingToolbarLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        collapsingToolbarLayout = 
              (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);

        final FragmentManager manager = getSupportFragmentManager();
        final Fragment fragment = new CheeseListFragment();
        manager.beginTransaction()
                .replace(R.id.root_content, fragment)
                .commit();
    }

    @Override
    public void enableScroll() {
        final AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams)
                                  collapsingToolbarLayout.getLayoutParams();
        params.setScrollFlags(
                AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL 
                | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS
        );
        collapsingToolbarLayout.setLayoutParams(params);
    }

    @Override
    public void disableScroll() {
        final AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams)
                                  collapsingToolbarLayout.getLayoutParams();
        params.setScrollFlags(0);
        collapsingToolbarLayout.setLayoutParams(params);
    }
}

activity_main.xml:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapsing_toolbar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                app:contentScrim="?attr/colorPrimary">

                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    android:background="?attr/colorPrimary"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

            </android.support.design.widget.CollapsingToolbarLayout>

        </android.support.design.widget.AppBarLayout>

        <FrameLayout
            android:id="@+id/root_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="fill_vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

    </android.support.design.widget.CoordinatorLayout>

</android.support.v4.widget.DrawerLayout>

Testfragment:

public class CheeseListFragment extends Fragment {

    private static final int DOWN = 1;
    private static final int UP = 0;

    private LayoutController controller;
    private RecyclerView rv;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        try {
            controller = (MainActivity) getActivity();
        } catch (ClassCastException e) {
            throw new RuntimeException(getActivity().getLocalClassName()
                    + "must implement controller.", e);
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rv = (RecyclerView) inflater.inflate(
                R.layout.fragment_cheese_list, container, false);
        setupRecyclerView(rv);

        // Find out if RecyclerView are scrollable, delay required
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (rv.canScrollVertically(DOWN) || rv.canScrollVertically(UP)) {
                    controller.enableScroll();
                } else {
                    controller.disableScroll();
                }
            }
        }, 100);

        return rv;
    }

    private void setupRecyclerView(RecyclerView recyclerView) {
        final LinearLayoutManager layoutManager = new LinearLayoutManager(recyclerView.getContext());

        recyclerView.setLayoutManager(layoutManager);

        final SimpleStringRecyclerViewAdapter adapter =
                new SimpleStringRecyclerViewAdapter(
                        getActivity(),
                        // Test ToolBar scroll
                        getRandomList(/* with enough items to scroll */)
                        // Test ToolBar pin
                        getRandomList(/* with only 3 items*/)
                );

        recyclerView.setAdapter(adapter);
    }
}

Quellen:

Bearbeiten:

Sie sollten CollapsingToolbarLayout verwenden, um das Verhalten zu steuern.

Durch das direkte Hinzufügen einer Toolbar zu einem AppBarLayout erhalten Sie Zugriff auf die Scroll-Flags enterAlwaysCollapsed und exitUntilCollapsed, aber nicht auf die detaillierte Kontrolle darüber, wie verschiedene Elemente auf das Reduzieren reagieren.
[…] setup verwendet app:layout_collapseMode=”pin” von CollapsingToolbarLayout, um sicherzustellen, dass die Symbolleiste selbst am oberen Rand des Bildschirms angeheftet bleibt, während die Ansicht minimiert wird.http://android-developers.blogspot.com.tr/2015/05/android-design-support-library.html

<android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

    <android.support.v7.widget.Toolbar
        android:id="@+id/drawer_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_collapseMode="pin"/>

</android.support.design.widget.CollapsingToolbarLayout>

Hinzufügen

app:layout_collapseMode="pin"

zu Ihrer Toolbar in XML.

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:layout_collapseMode="pin"
        app:theme="@style/ToolbarStyle" />

  • Es funktioniert nicht für mich. Hast du es getestet? Ich vermute nein.

    – eiki

    18. Februar 2016 um 13:39 Uhr

  • Ja, ich verwende es in meiner eigenen App. Aber ich habe gerade den Unterschied bemerkt, denke ich. Siehe meine Bearbeitung. Sie sollten die Toolbar mit CollapsingToolbarLayout umschließen und die scrollFlags für diese Ansicht festlegen und sicherstellen, dass die Toolbar auf „Pin“ festgelegt ist.

    – Benutzer3623735

    18. Februar 2016 um 16:16 Uhr

  • Hey, erstens entschuldige ich mich dafür, dass ich völlig missverstanden habe, was du zu tun versuchst, und deine Zeit verschwendet hast, indem du eine falsche Antwort gegeben hast. Zweitens, überprüfen Sie bitte mein edit2, es macht genau das, was Sie versuchen zu tun. Lassen Sie mich wissen, wenn Sie Fragen haben.

    – Benutzer3623735

    18. Februar 2016 um 19:43 Uhr

  • Die Gesamtidee macht Sinn, aber es gibt ein Problem. Wenn die Recycleransicht wann nicht scrollen würde nimmt den gesamten vertikalen Raum des CoordinatorLayout ein aber wann nimmt den gesamten Platz ein, der von AppBarLayout + CollapsingToolbarLayout übrig bleibt, dies bricht: Die RecyclerView würde innerhalb des verbleibenden Platzes gut scrollen, aber das AppBarLayout wird nicht zusammenbrechen. Um dies zu beheben, sollten wir irgendwie “würde vertikal innerhalb des vertikalen Raums scrollen, der übrig bleibt, wenn CollapsingToolbarLayout vollständig erweitert ist” aktivieren.

    – Droid256

    17. Oktober 2018 um 16:34 Uhr

Benutzer-Avatar
Emirua

Also, richtige Anerkennung, diese Antwort hat es fast für mich gelöst https://stackoverflow.com/a/32923226/5050087. Aber da die Symbolleiste nicht angezeigt wurde, wenn Sie tatsächlich eine scrollbare Recycleransicht hatten und ihr letztes Element sichtbar war (es würde die Symbolleiste nicht beim ersten Scrollen nach oben zeigen), habe ich mich entschieden, sie zu ändern und anzupassen, um eine einfachere Implementierung und Dynamik zu ermöglichen Adapter.

Zuerst müssen Sie ein benutzerdefiniertes Layoutverhalten für Ihre Appbar erstellen:

public class ToolbarBehavior extends AppBarLayout.Behavior{

private boolean scrollableRecyclerView = false;
private int count;

public ToolbarBehavior() {
}

public ToolbarBehavior(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
    return scrollableRecyclerView && super.onInterceptTouchEvent(parent, child, ev);
}

@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) {
    updatedScrollable(directTargetChild);
    return scrollableRecyclerView && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type);
}

@Override
public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) {
    return scrollableRecyclerView && super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
}

private void updatedScrollable(View directTargetChild) {
    if (directTargetChild instanceof RecyclerView) {
        RecyclerView recyclerView = (RecyclerView) directTargetChild;
        RecyclerView.Adapter adapter = recyclerView.getAdapter();
        if (adapter != null) {
            if (adapter.getItemCount()!= count) {
                scrollableRecyclerView = false;
                count = adapter.getItemCount();
                RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                if (layoutManager != null) {
                    int lastVisibleItem = 0;
                    if (layoutManager instanceof LinearLayoutManager) {
                        LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
                        lastVisibleItem = Math.abs(linearLayoutManager.findLastCompletelyVisibleItemPosition());
                    } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                        StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
                        int[] lastItems = staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(new int[staggeredGridLayoutManager.getSpanCount()]);
                        lastVisibleItem = Math.abs(lastItems[lastItems.length - 1]);
                    }
                    scrollableRecyclerView = lastVisibleItem < count - 1;
                }
            }
        }
    } else scrollableRecyclerView = true;
  }
}

Dann müssen Sie dieses Verhalten nur noch für Ihre Appbar in Ihrer Layoutdatei definieren:

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true"
    app:layout_behavior="com.yourappname.whateverdir.ToolbarBehavior"
    >

Ich habe es nicht für die Bildschirmdrehung getestet, also lassen Sie mich wissen, ob es so funktioniert. Ich denke, es sollte funktionieren, da ich nicht glaube, dass die Zählvariable gespeichert wird, wenn die Rotation stattfindet, aber lassen Sie es mich wissen, wenn dies nicht der Fall ist.

Dies war die einfachste und sauberste Implementierung für mich, genieße es.

  • Ich denke, angesichts des Layouts in der Frage sollten Sie die Methode so nennen updatedScrollable(target) seit der RecyclerView ist kein direktes Kind der AppBarLayout.

    – OneEyeQuestion

    27. März 2016 um 20:56 Uhr

  • Es ist eigentlich ein Verweis auf das CoordinatorLayout, das das übergeordnete Element ist ;).

    – Emirate

    28. März 2016 um 6:38 Uhr

Es ist kein Fehler, alle Ereignisse in einer viewGroup werden auf diese Weise behandelt. Da Ihr recyclerview ein untergeordnetes Element von coordinatorLayout ist, wird es bei jedem Generieren des Ereignisses zuerst auf das übergeordnete Element überprüft, und wenn das übergeordnete Element nicht interessiert ist, wird es nur an das untergeordnete Element weitergegeben. Siehe Google Dokumentation

So etwas in einem LayoutManager Unterklasse scheint zum gewünschten Verhalten zu führen:

@Override
public boolean canScrollVertically() {
    int firstCompletelyVisibleItemPosition = findFirstCompletelyVisibleItemPosition();
    if (firstCompletelyVisibleItemPosition == RecyclerView.NO_POSITION) return false;

    int lastCompletelyVisibleItemPosition = findLastCompletelyVisibleItemPosition();
    if (lastCompletelyVisibleItemPosition == RecyclerView.NO_POSITION) return false;

    if (firstCompletelyVisibleItemPosition == 0 &&
            lastCompletelyVisibleItemPosition == getItemCount() - 1)
        return false;

    return super.canScrollVertically();
}

Die Dokumentation für canScrollVertically() sagt:

/**
 * Query if vertical scrolling is currently supported. The default implementation
 * returns false.
 *
 * @return True if this LayoutManager can scroll the current contents vertically
 */

Beachten Sie die Formulierung „can scroll the aktuelle Inhalte vertikal”, was meiner Meinung nach impliziert, dass der aktuelle Zustand durch den Rückgabewert widergespiegelt werden sollte.

Das tut aber keiner der LayoutManager Unterklassen bereitgestellt durch die v7 Recyclerview-Bibliothek (23.1.1), was mich etwas zweifeln lässt, ob es eine richtige Lösung ist; es könnte in anderen Situationen als in dieser Frage zu unerwünschten Effekten kommen.

Ich habe es mit meiner eigenen Behavior-Klasse implementiert, die möglicherweise an AppBarLayout angehängt ist:

public class CustomAppBarLayoutBehavior extends AppBarLayout.Behavior {

private RecyclerView recyclerView;
private int additionalHeight;

public CustomAppBarLayoutBehavior(RecyclerView recyclerView, int additionalHeight) {
    this.recyclerView = recyclerView;
    this.additionalHeight = additionalHeight;
}

public boolean isRecyclerViewScrollable(RecyclerView recyclerView) {
    return recyclerView.computeHorizontalScrollRange() > recyclerView.getWidth() || recyclerView.computeVerticalScrollRange() > (recyclerView.getHeight() - additionalHeight);
}

@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) {
    if (isRecyclerViewScrollable(mRecyclerView)) {
        return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
    }
    return false;
}

}

Und unten ist der Code, wie man dieses Verhalten einstellt:

final View appBarLayout = ((DrawerActivity) getActivity()).getAppBarLayoutView();
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
layoutParams.setBehavior(new AppBarLayoutNoEmptyScrollBehavior(recyclerView, getResources().getDimensionPixelSize(R.dimen.control_bar_height)));

Benutzer-Avatar
Mohammad Hossein Gerami

Ich habe vorgeschlagen, dass Sie es versuchen Dies Beispiel für die Unterstützung von Design-Bibliothekselementen.

Dies ist ein Layout wie Ihr Layout im Beispiel.

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>

Benutzer-Avatar
Peter

Danke, ich habe eine benutzerdefinierte Klasse von RecyclerView erstellt, aber der Schlüssel wird immer noch verwendet setNestedScrollingEnabled(). Auf meiner Seite hat es gut geklappt.

public class RecyclerViewCustom extends RecyclerView implements ViewTreeObserver.OnGlobalLayoutListener
{
    public RecyclerViewCustom(Context context)
    {
        super(context);
    }

    public RecyclerViewCustom(Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);
    }

    public RecyclerViewCustom(Context context, @Nullable AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    /**
     *  This supports scrolling when using RecyclerView with AppbarLayout
     *  Basically RecyclerView should not be scrollable when there's no data or the last item is visible
     *
     *  Call this method after Adapter#updateData() get called
     */
    public void addOnGlobalLayoutListener()
    {
        this.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    @Override
    public void onGlobalLayout()
    {
        // If the last item is visible or there's no data, the RecyclerView should not be scrollable
        RecyclerView.LayoutManager layoutManager = getLayoutManager();
        final RecyclerView.Adapter adapter = getAdapter();
        if (adapter == null || adapter.getItemCount() <= 0 || layoutManager == null)
        {
            setNestedScrollingEnabled(false);
        }
        else
        {
            int lastVisibleItemPosition = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition();
            boolean isLastItemVisible = lastVisibleItemPosition == adapter.getItemCount() - 1;
            setNestedScrollingEnabled(!isLastItemVisible);
        }

        unregisterGlobalLayoutListener();
    }

    private void unregisterGlobalLayoutListener()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
        {
            getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
        else
        {
            getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    }
}

1257130cookie-checkDie Symbolleiste in AppBarLayout ist scrollbar, obwohl RecyclerView nicht genügend Inhalt zum Scrollen hat

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy