Search code examples
javaandroidandroid-listfragmentonscrollonscrolllistener

How to get static onScroll event values from CollectionView back to the calling ListFragment or use the values in non-static method in the class?


I working on a Android application that has a ListFragment using a CollectionView. I want to be able to get the values from the onScroll event in the CollectionView as they change and use them in the ListFragment or even the CollectionView in a non-static method , however since onScroll event is static it won't allow a reference to a non-static method. Is there a way to do this or is there a way to make the onScroll event non-static for a ListFragment?

Here the basic CollectionView onScroll event code

    private  class MultiScrollListener implements OnScrollListener {
    private  Set<OnScrollListener> children = new HashSet<OnScrollListener>();


    public void addOnScrollListener(OnScrollListener listener) {
        children.add(listener);
    }
    @Override
    public void onScrollStateChanged(AbsListView absListView, int i) {

        for (OnScrollListener listener : children) {
            listener.onScrollStateChanged(absListView, i);
        }
    }

    @Override
    public void onScroll(AbsListView absListView, int i, int i2, int i3) {

   // ?????
   // ?????  I'd like to get the values of i, i2 and i3, from above
   // ?????  as they change into a non-static method.
   // ?????
             myMethod(i);

   //      I get the following error from Android Studio: 
   //      non static method 'myMethod(int i) cannot be referenced from a static context
   //


        for (OnScrollListener listener : children) {
            listener.onScroll(absListView, i, i2, i3);

        }
    }
}

As suggested I even tried making everything public, as below, but no change, still the same error.

    public  class MultiScrollListener implements OnScrollListener {
    public Set<OnScrollListener> children = new HashSet<OnScrollListener>();


    public void addOnScrollListener(OnScrollListener listener) {
        children.add(listener);
    }
    @Override
    public void onScrollStateChanged(AbsListView absListView, int i) {

        for (OnScrollListener listener : children) {
            listener.onScrollStateChanged(absListView, i);
            BrowseCorrelatedSessionsActivity.onBrowseSessionScrolled(1);
        }
    }

    @Override
    public void onScroll(AbsListView absListView, int i, int i2, int i3) {

        for (OnScrollListener listener : children) {
            listener.onScroll(absListView, i, i2, i3);

        }
    }

Solution

  • As suggested in the comments, I believe that EventBus can handle this situation

    Just wanted to show what I meant by making the class public and creating a callback:

    public  class MultiScrollListener implements OnScrollListener {
    
        // define callback interface
        public interface MultiScrollListenerCallback {
            public void onBrowseSessionScrolled(int someInt);
        }
    
        public Set<OnScrollListener> children = new HashSet<OnScrollListener>();
    
        private MultiScrollListenerCallback multiScrollListenerCallback;
    
        // get a reference to the callback in the constructor
        public MultiScrollListener(MultiScrollListenerCallback multiScrollListenerCallback) {
            this.multiScrollListenerCallback = multiScrollListenerCallback;
        }
    
    
        public void addOnScrollListener(OnScrollListener listener) {
            children.add(listener);
        }
        @Override
        public void onScrollStateChanged(AbsListView absListView, int i) {
    
            for (OnScrollListener listener : children) {
                listener.onScrollStateChanged(absListView, i);
                // speak through the callback
                multiScrollListenerCallback.onBrowseSessionScrolled(1); 
            }
        }
    
        @Override
        public void onScroll(AbsListView absListView, int i, int i2, int i3) {
    
            for (OnScrollListener listener : children) {
                listener.onScroll(absListView, i, i2, i3);
    
            }
        }
    }
    

    Now to use this fancy callback you have two options

    1) Let your Activity implement MultiScrollListenerCallback

    public class BrowseCorrelatedSessionsActivity implements MultiScrollListenerCallback {
        ...
        MultiScrollListener msl = new MultiScrollListener(this);
        ...
        public void onBrowseSessionScrolled(int someInt) {
            // handle callback
        }
    }
    

    2) Or make an anonymous inner class

    public class BrowseCorrelatedSessionsActivity {
        ...
        MultiScrollListener msl = new MultiScrollListener(new MultiScrollListenerCallback() {
            public void onBrowseSessionScrolled(int someInt) {
                // handle callback
            }
        });
    }
    

    Note that this code is written directly here on SO so might contain errors, just wanted to show you the idea.

    By the way please try and avoid ever making static calls to an Activity or Fragment as this may very quickly lead to headaches due to orientation changes and the like. You just cannot rely on the state to be as stable as handling static calls. Even if you are careful, not running in to runtime troubles, it is likely to explode in a can of spaghetti code later on.