Android折叠工具栏布局折叠侦听器
我正在使用Android折叠工具栏布局折叠侦听器,android,android-design-library,android-collapsingtoolbarlayout,Android,Android Design Library,Android Collapsingtoolbarlayout,我正在使用折叠工具栏布局以及AppBarLayout和CoordinatorLayout,它们都工作得很好。当我向上滚动时,我将我的工具栏设置为固定,我想知道当折叠工具栏布局时,是否有方法更改工具栏的标题文本 最后,在滚动和展开时,我需要两个不同的标题 appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void
折叠工具栏布局
以及AppBarLayout
和CoordinatorLayout
,它们都工作得很好。当我向上滚动时,我将我的工具栏设置为固定,我想知道当折叠工具栏布局时,是否有方法更改工具栏的标题文本
最后,在滚动和展开时,我需要两个不同的标题
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (Math.abs(verticalOffset)-appBarLayout.getTotalScrollRange() == 0)
{
// Collapsed
}
else
{
//Expanded
}
}
});
提前感谢大家将一个OnOffsetChangedListener
挂接到您的AppBarLayout
。当垂直偏移达到0或小于工具栏高度时,表示折叠工具栏布局已折叠,否则将展开或展开
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);
}
}
});
mAppBarLayout.addOnOffsetChangedListener(新的AppBarLayout.OnOffsetChangedListener(){
@凌驾
公共无效onOffsetChanged(AppBarLayout AppBarLayout,int verticalOffset){
如果(verticalOffset==0 | | verticalOffset此解决方案对我有效:
@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;
}
}
在AppBarLayout上使用addOnOffsetChangedListener。我共享基于@Frodio Beggins和@Niphel代码的完整实现:
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;
}
}
});
}
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);
}
然后你可以使用它:
appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
@Override
public void onStateChanged(AppBarLayout appBarLayout, State state) {
Log.d("STATE", state.name());
}
});
这个代码对我有用
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
}
}
});
此解决方案非常适合我检测AppBarLayout
折叠或扩展
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (Math.abs(verticalOffset)-appBarLayout.getTotalScrollRange() == 0)
{
// Collapsed
}
else
{
//Expanded
}
}
});
在AppBarLayout
上使用addOnOffsetChangedListener
,如果使用的是CollasingToolbarLayout,则可以将其
collapsingToolbar.setExpandedTitleColor(ContextCompat.getColor(activity, android.R.color.transparent));
collapsingToolbar.setTitle(title);
您可以使用以下方法获得折叠工具栏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);
});
仅供参考:此代码非常适合我。您可以随意使用百分比刻度
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
double percentage = (double) Math.abs(verticalOffset) / collapsingToolbar.getHeight();
if (percentage > 0.8) {
collapsingToolbar.setTitle("Collapsed");
} else {
collapsingToolbar.setTitle("Expanded");
}
}
我的工具栏偏移值在折叠时为-582,展开时为0
所以我通过在Toast中设置offsetvalue来找到值,并相应地更改代码
mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if(verticalOffset == -582) {
Toast.makeText(MainActivity.this, "collaped" + verticalOffset, Toast.LENGTH_SHORT).show();
mCollapsingToolbarLayout.setTitle("Collapsed");
}else if(verticalOffset == 0){
Toast.makeText(MainActivity.this, "expanded" + verticalOffset, Toast.LENGTH_SHORT).show();
mCollapsingToolbarLayout.setTitle("expanded");
}
}
});
这是一个Kotlin解决方案。将OnOffsetChangedListener
添加到AppBarLayout
方法A:
appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
if (abs(verticalOffset) - appBarLayout.totalScrollRange == 0) {
// Collapsed
} else if (verticalOffset == 0) {
// Expanded
} else {
// Idle
}
}
)
将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?
)
}
将侦听器添加到您的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 */ }
}
}
}
)
方法B:
appBarLayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
if (abs(verticalOffset) - appBarLayout.totalScrollRange == 0) {
// Collapsed
} else if (verticalOffset == 0) {
// Expanded
} else {
// Idle
}
}
)
以下是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?
)
}
下面是听众:
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
}
}
})
它对我不起作用。OnCollapse我要启用“主页”按钮,并在“展开”时隐藏“主页”按钮当工具栏完全展开时,垂直偏移值似乎为零,然后在折叠时变为负值。当工具栏折叠时,垂直偏移等于负工具栏高度(-mToolbar.getHeight())。因此…工具栏部分展开为“if(verticalOffset>-mToolbar.getHeight()”。如果有人想知道appBarLayout.getVerticalOffset()
方法在哪里,可以调用appBarLayout.getY()
检索回调中使用的相同值。不幸的是Jarett Millard不对。根据fitsSystemWindow配置和状态栏配置(透明),appBarLayout.getY()
可能是verticalOffset=appBarLayout.getY()+statusBarHeight
是否有人注意到mAppBarLayout.addOnOffsetChangedListener(侦听器)即使我们实际上没有与appbar交互,也会重复调用。或者这是我的布局/应用程序中的一个错误,我观察到了这种行为。Plz帮助!你能分享你的完整代码吗?State.EXPANDED等是什么?这是正确的。但请不要担心使用Proguard,枚举将被转换为整数值。我不知道。这是真的太好了!枚举也是确保类型安全的一种非常好的方法。你不能让State.inboded因为它不存在(编译器会抱怨)但是对于整型常量,你可以使用一个编译器不知道是错误的值。它们和单例一样好,但这是另一回事。@droppin_science for android enums check out@DavidDarias我个人认为enums是一种更干净的方法,即使有开销(从这里开始的参数…:-)比Nikola Despotoski更好的答案似乎不是一个可靠的解决方案。我测试了它,在我的设备上的值如下:mCollapsingToolbarLayout.getHeight()=1013,mToolbar.getHeight()=224。因此,根据您的解决方案,折叠状态下的垂直偏移量必须为-789,但它等于-693。这是一个很好的答案,因为它提供了一个标准化偏移量。在我看来,API应该直接提供这一点,而不是垂直偏移量
像素距离。我希望当AppBarLayout折叠时,视图是隐藏和展开的d视图是显示的。所以我使用val percentage=1-abs(verticalOffset).toFloat()/appBarLayout.totalScrollRange
。它对我来说工作得很好。它可以多次触发折叠,也可以在展开时触发。