Android CollapsingToolbarLayout collapse Listener

后端 未结 12 1155
情歌与酒
情歌与酒 2020-12-12 11:37

I am using CollapsingToolBarLayout alongside with AppBarLayout and CoordinatorLayout, and they are working Fine altogether. I set my <

相关标签:
12条回答
  • 2020-12-12 12:33

    This solution works perfectly for me to detect AppBarLayout collapsed or expanded.

    appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
    
                if (Math.abs(verticalOffset)-appBarLayout.getTotalScrollRange() == 0)
                {
                    //  Collapsed
    
    
                }
                else
                {
                    //Expanded
    
    
                }
            }
        });
    

    Used addOnOffsetChangedListener on the AppBarLayout.

    0 讨论(0)
  • 2020-12-12 12:33

    This solution is working for me:

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
      if (i == 0) {
        if (onStateChangeListener != null && state != State.EXPANDED) {
          onStateChangeListener.onStateChange(State.EXPANDED);
        }
        state = State.EXPANDED;
      } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
        if (onStateChangeListener != null && state != State.COLLAPSED) {
          onStateChangeListener.onStateChange(State.COLLAPSED);
        }
        state = State.COLLAPSED;
      } else {
        if (onStateChangeListener != null && state != State.IDLE) {
          onStateChangeListener.onStateChange(State.IDLE);
        }
        state = State.IDLE;
      }
    }
    

    Use addOnOffsetChangedListener on the AppBarLayout.

    0 讨论(0)
  • 2020-12-12 12:35

    Here's a Kotlin solution. Add an OnOffsetChangedListener to the AppBarLayout.

    Method A:

    Add AppBarStateChangeListener.kt to your project:

    import com.google.android.material.appbar.AppBarLayout
    import kotlin.math.abs
    
    abstract class AppBarStateChangeListener : AppBarLayout.OnOffsetChangedListener {
    
        enum class State {
            EXPANDED, COLLAPSED, IDLE
        }
    
        private var mCurrentState = State.IDLE
    
        override fun onOffsetChanged(appBarLayout: AppBarLayout, i: Int) {
            if (i == 0 && mCurrentState != State.EXPANDED) {
                onStateChanged(appBarLayout, State.EXPANDED)
                mCurrentState = State.EXPANDED
            }
            else if (abs(i) >= appBarLayout.totalScrollRange && mCurrentState != State.COLLAPSED) {
                onStateChanged(appBarLayout, State.COLLAPSED)
                mCurrentState = State.COLLAPSED
            }
            else if (mCurrentState != State.IDLE) {
                onStateChanged(appBarLayout, State.IDLE)
                mCurrentState = State.IDLE
            }
        }
    
        abstract fun onStateChanged(
            appBarLayout: AppBarLayout?,
            state: State?
        )
    
    }
    

    Add the listener to your appBarLayout:

    appBarLayout.addOnOffsetChangedListener(object: AppBarStateChangeListener() {
            override fun onStateChanged(appBarLayout: AppBarLayout?, state: State?) {
                Log.d("State", state.name)
                when(state) {
                    State.COLLAPSED -> { /* Do something */ }
                    State.EXPANDED -> { /* Do something */ }
                    State.IDLE -> { /* Do something */ }
                }
            }
        }
    )
    

    Method B:

    appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
            if (abs(verticalOffset) - appBarLayout.totalScrollRange == 0) { 
                // Collapsed
            } else if (verticalOffset == 0) {
                // Expanded
            } else {
                // Idle
            }
        }
    )
    
    0 讨论(0)
  • 2020-12-12 12:37

    I share the full implementation, based on @Frodio Beggins and @Nifhel code:

    public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {
    
        public enum State {
            EXPANDED,
            COLLAPSED,
            IDLE
        }
    
        private State mCurrentState = State.IDLE;
    
        @Override
        public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
            if (i == 0) {
                if (mCurrentState != State.EXPANDED) {
                    onStateChanged(appBarLayout, State.EXPANDED);
                }
                mCurrentState = State.EXPANDED;
            } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
                if (mCurrentState != State.COLLAPSED) {
                    onStateChanged(appBarLayout, State.COLLAPSED);
                }
                mCurrentState = State.COLLAPSED;
            } else {
                if (mCurrentState != State.IDLE) {
                    onStateChanged(appBarLayout, State.IDLE);
                }
                mCurrentState = State.IDLE;
            }
        }
    
        public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
    }
    

    And then you can use it:

    appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
        @Override
        public void onStateChanged(AppBarLayout appBarLayout, State state) {
            Log.d("STATE", state.name());
        }
    });
    
    0 讨论(0)
  • 2020-12-12 12:37

    Here is the solution in Kotlin:

    abstract class AppBarStateChangeListener : OnOffsetChangedListener {
        enum class State {
            EXPANDED, COLLAPSED, IDLE
        }
    
        private var mCurrentState =
            State.IDLE
    
        override fun onOffsetChanged(appBarLayout: AppBarLayout, i: Int) {
            mCurrentState = if (i == 0) {
                if (mCurrentState != State.EXPANDED) {
                    onStateChanged(appBarLayout, State.EXPANDED)
                }
                State.EXPANDED
            } else if (Math.abs(i) >= appBarLayout.totalScrollRange) {
                if (mCurrentState != State.COLLAPSED) {
                    onStateChanged(appBarLayout, State.COLLAPSED)
                }
                State.COLLAPSED
            } else {
                if (mCurrentState != State.IDLE) {
                    onStateChanged(appBarLayout, State.IDLE)
                }
                State.IDLE
            }
        }
    
        abstract fun onStateChanged(
            appBarLayout: AppBarLayout?,
            state: State?
        )
    }
    

    Here is the listener:

      appbar.addOnOffsetChangedListener(object : AppBarStateChangeListener() {
            override fun onStateChanged(
                appBarLayout: AppBarLayout?,
                state: State?
            ) {
                if(state == State.COLLAPSED){
                    LayoutBottom.visibility = View.GONE
                }else if(state == State.EXPANDED){
                    LayoutBottom.visibility = View.VISIBLE
                }
            }
        })
    
    0 讨论(0)
  • 2020-12-12 12:43

    This code worked for me

    mAppBarLayout.addOnOffsetChangedListener(new   AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if (verticalOffset == -mCollapsingToolbarLayout.getHeight() + mToolbar.getHeight()) {
                    //toolbar is collapsed here
                    //write your code here
                }
            }
        });
    
    0 讨论(0)
提交回复
热议问题