web-dev-qa-db-de.com

ScrollingViewBehavior für ListView

Ich habe zwei Aktivitäten mit AppBarLayout mit einem Toolbar und TabLayout aus der Unterstützungsbibliothek 22.

Das Layout von beiden ist ziemlich ähnlich: Ein Toolbar oben, darunter TabLayout, darunter ein ViewPager mit 3 Fragments.

Die Fragment der ersten Aktivität hat eine RecyclerView, die Fragment der zweiten Aktivität verwendet stattdessen eine ListView.

Das scrollbare Toolbar Beispiel von https://github.com/chrisbanes/cheesesquare funktioniert bei der ersten Aktivität mit dem RecyclerView, aber mit dem ListView.

Ich habe versucht, ein benutzerdefiniertes ListViewScrollBehavior zu erstellen, das AppBarLayout.ScrollingViewBehavior Erweitert, aber bisher kein Glück. Die TouchEvents werden nur zum horizontalen Scrollen an die benutzerdefinierte Klasse übergeben, nicht jedoch beim Scrollen des ListView (vertikal).

Wie kann ein CoordinatorLayout mit ListView verwendet werden?

34
marmor

Die einzige Lösung, die jetzt funktioniert, besteht darin, Folgendes zu verwenden:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
     listView.setNestedScrollingEnabled(true);
}

Es wird natürlich nur auf Lollipop funktionieren.

36
Nicolas POMEPUY

Alternative Lösung zu Nicolas POMEPUYs Antwort ist ViewCompat.setNestedScrollingEnabled(View, boolean)

ViewCompat.setNestedScrollingEnabled(listView, true);

Natürlich funktioniert verschachteltes Scrollen nur mit Lollipop.

13
hidro

Ich glaube, dass das CoordinatorLayout nur mit RecyclerView und NestedScrollView funktioniert. Versuchen Sie, Ihr ListView in ein NestedScrollView zu wickeln, oder konvertieren Sie es in ein RecyclerView mit einem LinearLayoutManager

11
TheoK

Um auf AppBarLayout reagieren zu können, muss NestedScrollingChild implementiert werden. ListView ist nicht. Es kann jedoch leicht von einer Delegierten-Klasse implementiert werden. Verwenden Sie es, es wird genau das tun, was RecyclerView getan hat

public class NestedScrollingListView extends ListView implements NestedScrollingChild {
private NestedScrollingChildHelper mNestedScrollingChildHelper;

public NestedScrollingListView(final Context context) {
    super(context);
    initHelper();
}

public NestedScrollingListView(final Context context, final AttributeSet attrs) {
    super(context, attrs);
    initHelper();
}

public NestedScrollingListView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initHelper();
}

@TargetApi(Build.VERSION_CODES.Lollipop)
public NestedScrollingListView(final Context context, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    initHelper();
}

private void initHelper() {
    mNestedScrollingChildHelper = new NestedScrollingChildHelper(this);
    setNestedScrollingEnabled(true);
}

@Override
public void setNestedScrollingEnabled(final boolean enabled) {
    mNestedScrollingChildHelper.setNestedScrollingEnabled(enabled);
}

@Override
public boolean isNestedScrollingEnabled() {
    return mNestedScrollingChildHelper.isNestedScrollingEnabled();
}

@Override
public boolean startNestedScroll(final int axes) {
    return mNestedScrollingChildHelper.startNestedScroll(axes);
}

@Override
public void stopNestedScroll() {
    mNestedScrollingChildHelper.stopNestedScroll();
}

@Override
public boolean hasNestedScrollingParent() {
    return mNestedScrollingChildHelper.hasNestedScrollingParent();
}

@Override
public boolean dispatchNestedScroll(final int dxConsumed, final int dyConsumed, final int dxUnconsumed, final int dyUnconsumed, final int[] offsetInWindow) {
    return mNestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}

@Override
public boolean dispatchNestedPreScroll(final int dx, final int dy, final int[] consumed, final int[] offsetInWindow) {
    return mNestedScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}

@Override
public boolean dispatchNestedFling(final float velocityX, final float velocityY, final boolean consumed) {
    return mNestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}

@Override
public boolean dispatchNestedPreFling(final float velocityX, final float velocityY) {
    return mNestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}

}

5
I Love Coding

ListView ScrollingViewBehavior unterstützt nur> = 21.

Ansonsten sollten Sie den Code wie folgt schreiben:

private int mPreviousVisibleItem;


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
    listView.setNestedScrollingEnabled(true);
} else {
    listView.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            if (firstVisibleItem > mPreviousVisibleItem) {
                appBarLayout.setExpanded(false, true);
            } else if (firstVisibleItem < mPreviousVisibleItem) {
                appBarLayout.setExpanded(true, true);
            }
            mPreviousVisibleItem = firstVisibleItem;
        }
    });
}
1