use custom view to improve performance for nested scroll views

This commit is contained in:
dkanada 2020-09-28 13:50:06 +09:00
commit a0e23c13d8
3 changed files with 89 additions and 2 deletions

View file

@ -123,6 +123,8 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
binding.songs.setLayoutManager(new GridLayoutManager(this, 1));
binding.songs.setAdapter(songAdapter);
binding.scrollView.setRecyclerView(binding.songs);
}
private void setUpAlbumRecyclerView() {

View file

@ -0,0 +1,84 @@
package com.dkanada.gramophone.views;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import androidx.annotation.NonNull;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class InceptionScrollView extends NestedScrollView {
private RecyclerView recyclerView;
public InceptionScrollView(@NonNull Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onNestedPreScroll(@NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
// if scrolling down and scroll view not at bottom and recycler view fills screen but scroll view doesn't fill the screen
if (dy > 0 && !isSvScrolledToBottom(this) && !isRvFillParent(this, recyclerView) && isSvFillParent(this)) {
scrollBy(0, dy);
consumed[1] = dy;
return;
}
// send to normal scroll view method
super.onNestedPreScroll(target, dx, dy, consumed, type);
}
public void setRecyclerView(RecyclerView recyclerView) {
this.recyclerView = recyclerView;
InceptionScrollView scrollView = this;
this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect scrollBounds = new Rect();
getDrawingRect(scrollBounds);
ViewGroup.LayoutParams params = recyclerView.getLayoutParams();
params.height = scrollBounds.bottom;
recyclerView.setLayoutParams(params);
scrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
private static boolean isSvScrolledToBottom(NestedScrollView sv) {
return !sv.canScrollVertically(1);
}
// might be useful in the future
private static boolean isRvScrolledToTop(RecyclerView rv) {
final LinearLayoutManager lm = (LinearLayoutManager) rv.getLayoutManager();
return lm != null && lm.findFirstCompletelyVisibleItemPosition() == 0;
}
private static boolean isRvFillParent(NestedScrollView sv, RecyclerView rv) {
Rect scrollLocationInParent = new Rect();
sv.getHitRect(scrollLocationInParent);
Rect viewLocationVisible = new Rect();
rv.getDrawingRect(viewLocationVisible);
return viewLocationVisible == scrollLocationInParent;
}
// this would probably need changes to do exactly what it says in the name
private static boolean isSvFillParent(NestedScrollView sv) {
Rect scrollBounds = new Rect();
sv.getHitRect(scrollBounds);
Rect viewBounds = new Rect();
sv.getDrawingRect(viewBounds);
return viewBounds.top >= scrollBounds.top;
}
}

View file

@ -146,7 +146,8 @@
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
<com.dkanada.gramophone.views.InceptionScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
@ -179,7 +180,7 @@
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</com.dkanada.gramophone.views.InceptionScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>