content: package dev.dworks.apps.anexplorer.ui;
  
  import androidx.annotation.NonNull;
  import android.view.View;
  import android.widget.AbsListView;
  
  public abstract class AbsListViewScrollDetector implements AbsListView.OnScrollListener {
      private int mLastScrollY;
      private int mPreviousFirstVisibleItem;
      private AbsListView mListView;
      private int mScrollThreshold;
  
      public abstract void onScrollUp();
  
      public abstract void onScrollDown();
  
      @Override
      public void onScrollStateChanged(AbsListView view, int scrollState) {
      }
  
      @Override
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
          if (isSameRow(firstVisibleItem)) {
              int newScrollY = getTopItemScrollY();
              boolean isSignificantDelta = Math.abs(mLastScrollY - newScrollY) > mScrollThreshold;
              if (isSignificantDelta) {
                  if (mLastScrollY > newScrollY) {
                      onScrollUp();
                  } else {
                      onScrollDown();
                  }
              }
              mLastScrollY = newScrollY;
          } else {
              if (firstVisibleItem > mPreviousFirstVisibleItem) {
                  onScrollUp();
              } else {
                  onScrollDown();
              }
  
              mLastScrollY = getTopItemScrollY();
              mPreviousFirstVisibleItem = firstVisibleItem;
          }
      }
  
      public void setScrollThreshold(int scrollThreshold) {
          mScrollThreshold = scrollThreshold;
      }
  
      public void setListView(@NonNull AbsListView listView) {
          mListView = listView;
      }
  
      private boolean isSameRow(int firstVisibleItem) {
          return firstVisibleItem == mPreviousFirstVisibleItem;
      }
  
      private int getTopItemScrollY() {
          if (mListView == null || mListView.getChildAt(0) == null) return 0;
          View topChild = mListView.getChildAt(0);
          return topChild.getTop();
      }
  }