Android CollapsingToolbarLayout崩溃侦听器

Ana*_*ade 92 android android-design-library android-collapsingtoolbarlayout

我使用的CollapsingToolBarLayout旁边有AppBarLayoutCoordinatorLayout,和他们一起工作的罚款.Toolbar当我向上滚动时,我将我设置为固定,我想知道是否有一种方法可以在CollapsingToolBarLayout折叠时更改工具栏的标题文本.

总结一下,我想在滚动扩展时使用两种不同的标题.

谢谢大家

rci*_*ati 127

我基于@Frodio Beggins和@Nifhel代码分享了完整的实现:

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);
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用它:

appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
    @Override
    public void onStateChanged(AppBarLayout appBarLayout, State state) {
        Log.d("STATE", state.name());
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 那是对的.但请不要使用Proguard将枚举转换为整数值. (21认同)
  • 枚举也是确保类型安全的一种非常好的方法。您不能拥有State.IMPLODED,因为它不存在(编译器会抱怨),但是使用Integer常量,您可以使用一个值,表示编译器不知道是错误的。它们也很适合单身,但这就是另一个故事。 (2认同)

Muh*_*s M 83

这个解决方案非常适合我检测AppBarLayout折叠或扩展.

appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {

            if (Math.abs(verticalOffset)-appBarLayout.getTotalScrollRange() == 0)
            {
                //  Collapsed


            }
            else
            {
                //Expanded


            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

使用addOnOffsetChangedListenerAppBarLayout.

  • 这场火灾多次倒塌,也有扩大的趋势。 (3认同)

Nik*_*ski 35

OnOffsetChangedListener你的AppBarLayout.当verticalOffset达到0或小于Toolbar高度时,表示CollapsingToolbarLayout已折叠,否则它正在展开或展开.

mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
            @Override
            public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
                if(verticalOffset == 0 || verticalOffset <= mToolbar.getHeight() && !mToolbar.getTitle().equals(mCollapsedTitle)){
                    mCollapsingToolbar.setTitle(mCollapsedTitle);
                }else if(!mToolbar.getTitle().equals(mExpandedTitle)){
                    mCollapsingToolbar.setTitle(mExpandedTitle);
                }

            }
        });
Run Code Online (Sandbox Code Playgroud)

  • 工具栏完全展开时,verticalOffset值似乎为零,然后在折叠时变为负值.折叠工具栏时,verticalOffset等于工具栏高度为负(-mToolbar.getHeight()).所以...工具栏部分展开"if(verticalOffset> -mToolbar.getHeight())" (7认同)

小智 16

这段代码对我有用

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
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)


小智 15

private enum State {
    EXPANDED,
    COLLAPSED,
    IDLE
}

private void initViews() {
    final String TAG = "AppBarTest";
    final AppBarLayout mAppBarLayout = findViewById(R.id.appbar);
    mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        private State state;

        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            if (verticalOffset == 0) {
                if (state != State.EXPANDED) {
                    Log.d(TAG,"Expanded");
                }
                state = State.EXPANDED;
            } else if (Math.abs(verticalOffset) >= appBarLayout.getTotalScrollRange()) {
                if (state != State.COLLAPSED) {
                    Log.d(TAG,"Collapsed");
                }
                state = State.COLLAPSED;
            } else {
                if (state != State.IDLE) {
                    Log.d(TAG,"Idle");
                }
                state = State.IDLE;
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)


ole*_*234 12

这是一个Kotlin解决方案。添加一个OnOffsetChangedListenerAppBarLayout.

方法一:

添加AppBarStateChangeListener.kt到您的项目:

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?
    )

}
Run Code Online (Sandbox Code Playgroud)

将侦听器添加到您的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 */ }
            }
        }
    }
)
Run Code Online (Sandbox Code Playgroud)

方法B:

appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
        if (abs(verticalOffset) - appBarLayout.totalScrollRange == 0) { 
            // Collapsed
        } else if (verticalOffset == 0) {
            // Expanded
        } else {
            // Idle
        }
    }
)
Run Code Online (Sandbox Code Playgroud)


Nav*_*r M 7

您可以使用以下方法获得collapsingToolBar alpha百分比:

appbarLayout.addOnOffsetChangedListener( new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            float percentage = ((float)Math.abs(verticalOffset)/appBarLayout.getTotalScrollRange());
            fadedView.setAlpha(percentage);
    });
Run Code Online (Sandbox Code Playgroud)

供参考:链接

  • 这是一个很好的答案,因为它给出了一个标准化的偏移量.在我看来,API应该直接提供这个而不是`verticalOffset`像素距离. (2认同)