需要为某些片段禁用 CollapsingToolbarLayout 上的展开
Posted
技术标签:
【中文标题】需要为某些片段禁用 CollapsingToolbarLayout 上的展开【英文标题】:Need to disable expand on CollapsingToolbarLayout for certain fragments 【发布时间】:2015-08-27 01:12:15 【问题描述】:我有一个控制替换许多片段的 AppCompatActivity。这是我的布局。
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_
android:layout_
android:fitsSystemWindows="true">
<include layout="@layout/activity_main_frame"/>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_
android:layout_
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:background="@color/white"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
activity_main_frame.xml
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_
android:layout_
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_
android:layout_
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_
android:layout_
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="@+id/backdrop"
android:layout_
android:layout_
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<include layout="@layout/activity_main_items"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_
android:layout_
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_
android:layout_
android:visibility="gone"
android:layout_gravity="bottom"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="@+id/content_frame"
android:layout_
android:layout_
app:layout_behavior="@string/appbar_scrolling_view_behavior" >
</FrameLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab1"
android:layout_
android:layout_
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
app:borderWidth="0dp"
android:src="@drawable/app_ic_slide_wallpaper_dark"
android:layout_margin="@dimen/big_padding"
android:clickable="true"/>
</android.support.design.widget.CoordinatorLayout>
我的主页片段最初是设置的,这就是我希望折叠工具栏展开的地方,并且工作正常。但是,当我从侧抽屉更改片段时,我想禁用扩展工具栏。
我已经知道如何在选择抽屉项目时折叠它,但我还需要确保它不会展开,除非显示主页片段。这可能吗?
public void collapseToolbar()
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbar.getLayoutParams();
behavior = (AppBarLayout.Behavior) params.getBehavior();
if(behavior!=null)
behavior.onNestedFling(coordinator, appbar, null, 0, 10000, true);
【问题讨论】:
你有没有找到办法做到这一点?我遇到了同样的问题。 不。我不得不放弃这个概念并将其删除。我认为折叠工具栏不应该与片段一起使用 也许这会有所帮助:***.com/a/53433716/878126? 【参考方案1】:禁用滚动片段内容的嵌套滚动:
recyclerView.setNestedScrollingEnabled(false);
如果您正在使用支持库,请使用它:
ViewCompat.setNestedScrollingEnabled(recyclerView, false);
【讨论】:
实际上,此答案中的 recyclerView 应替换为在 xml 中设置了 layout_behavior 属性的任何视图(或 CoordinatorLayout 中的所有此类视图)。它之所以有效,是因为(至少在支持库的 23.0.1 版本中)CoordinatorLayout 的 onStartNestedScroll 方法迭代其子项并询问他们是否接受嵌套滚动。如果没有人接受它,那么它就不会发挥它的滚动魔法。所以,对,自定义 CoordinatorLayout 可能不需要,只有辅助方法就足够了(如果有几个具有 layout_behavior 的孩子)。 此外,在定位棒棒糖之前的设备时应使用ViewCompat.setNestedScrollingEnabled(recyclerView, expanded);
表单。
这不是一个完整的解决方案,因为您仍然可以触摸并拖动 CollapsingToolbarLayout 来扩展它,它只会禁用带有 layout_behavior 的 NestedScrollView 的扩展
太棒了!对我来说很好..谢谢!
效果很好,谢谢。 @nikolay_turpitko 不适用于具有 layout_behavior 属性的视图,仅适用于 RecyclerView。【参考方案2】:
这个类可以让你禁用/重新启用扩展行为。
public class DisableableAppBarLayoutBehavior extends AppBarLayout.Behavior
private boolean mEnabled;
public DisableableAppBarLayoutBehavior()
super();
public DisableableAppBarLayoutBehavior(Context context, AttributeSet attrs)
super(context, attrs);
public void setEnabled(boolean enabled)
mEnabled = enabled;
@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes)
return mEnabled && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
public boolean isEnabled()
return mEnabled;
像这样在你的布局中使用它:
<android.support.design.widget.AppBarLayout
... other attributes ...
app:layout_behavior="com.yourpackage.DisableableAppBarLayoutBehavior"
>
<!-- your app bar contents -->
</android.support.design.widget.AppBarLayout>
然后,当您要禁用该行为时:
AppBarLayout myAppBar = ....;
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) myAppBar.getLayoutParams();
((DisableableAppBarLayoutBehavior) layoutParams.getBehavior()).setEnabled(false);
【讨论】:
我收到 java.lang.NullPointerException。帮帮我 干得好。但是,它和上面的其他方法有同样的问题:您仍然可以通过直接触摸和拖动 AppBar 本身来扩展内容。 这很好用,除了一个问题,我发现当布局锁定在展开模式时,我无法到达列表的末尾。有没有其他人遇到过这种情况? 为我工作,如果需要,请不要忘记将其默认为 true。 私有布尔 mEnabled = true;【参考方案3】:现在,在 v23 的支持库中,您可以轻松控制应用栏的可见性。
只需获取对您的 AppBarLayout 的引用并根据您要加载的片段隐藏/显示它:
private AppBarLayout appBarLayout;
@Override
protected void onCreate(Bundle savedInstanceState)
[...]
appBarLayout = (AppBarLayout) findViewById(R.id.appbar);
[...]
public void switchToFragment(Fragment fragment, String tag, boolean expandToolbar)
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment currentFragment = fragmentManager.findFragmentByTag(currentFragmentTag);
if(currentFragment == null || !TextUtils.equals(tag, currentFragmentTag) )
currentFragmentTag = tag;
fragmentManager
.beginTransaction()
.replace(R.id.flContent, fragment, currentFragmentTag)
.commit();
if(expandToolbar)
appBarLayout.setExpanded(true,true);
else
appBarLayout.setExpanded(false,true);
附:不要忘记在 build.gradle 中添加所需的依赖项:
dependencies
compile 'com.android.support:design:23.2.1'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:recyclerview-v7:23.2.1'
编辑: 如果您还想将工具栏锁定在某些片段中(除了折叠),您必须求助于解决方法,因为 CollapsingToolbarLayout 直到现在(支持设计的 v23.2.1)才提供此功能。 Here 你可以找到我建议的解决方法。
【讨论】:
setExpanded 也隐藏了我的工具栏。有人知道如何将其设置为折叠但不在屏幕顶部后面吗? 经过数小时的失败尝试,setExpanded() 为我工作!谢谢! 不确定为什么它被接受为答案。当然,这会扩展/折叠您的 AppBarLayout,但是如果您想禁用它,就像问题所说的那样,那么@tachyonflux 的方法就是要走的路。 @Ghedeon 过去曾指出这一点。我的 EDIT 是对您对该问题的具体解释的答案。然而,这个问题的标题和解释的措辞可能会被误解,一些未来的观众/谷歌用户实际上希望得到折叠工具栏问题的答案。因此,对此答案的支持和接受标记。【参考方案4】:您所要做的就是将 CoordinatorLayout 替换为 CoordinatorLayout 的自定义实现,这将欺骗嵌套滚动已被处理。
MyCoordinatorLayout 实现:
public class MyCoordinatorLayout extends CoordinatorLayout
private boolean allowForScroll = false;
public MyCoordinatorLayout(Context context)
super(context);
public MyCoordinatorLayout(Context context, AttributeSet attrs)
super(context, attrs);
@Override public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes)
return allowForScroll && super.onStartNestedScroll(child, target, nestedScrollAxes);
public boolean isAllowForScroll()
return allowForScroll;
public void setAllowForScroll(boolean allowForScroll)
this.allowForScroll = allowForScroll;
活动视图 xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:orientation="vertical"
>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawerLayout"
android:layout_
android:layout_
>
<!--CONTENT-->
<com.example.views.MyCoordinatorLayout
android:id="@+id/coordinator"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:fitsSystemWindows="true"
>
<com.example.views.ControllableAppBarLayout
android:id="@+id/appbar"
android:layout_
android:layout_
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_
android:layout_
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginBottom="32dp"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/header"
android:layout_
android:layout_
android:background="@color/primary"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_
android:layout_
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</com.example.views.ControllableAppBarLayout>
<FrameLayout
android:id="@+id/flContent"
android:layout_
android:layout_
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
</com.example.views.MyCoordinatorLayout>
<!-- DRAWER -->
<fragment
android:id="@+id/fDrawer"
android:name="com.example.fragment.DrawerFragment"
android:layout_
android:layout_
android:layout_gravity="left|start"
android:fitsSystemWindows="true"
android:clickable="true"
/>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
我鼓励您使用带有帮助方法的自定义 AppBarLayout 实现来折叠/展开工具栏。在这个gist 你可以找到一个。
好的,现在是时候在活动中配置我们的工具栏了。
public class ToolbarAppcompatActivity extends AppCompatActivity
implements AppBarLayout.OnOffsetChangedListener
protected Toolbar toolbar;
protected MyCoordinatorLayout coordinator;
protected ControllableAppBarLayout appbar;
@Override protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
configureToolbar();
switchFragment(new FooFragment(), "FOO", true);
protected void configureToolbar()
toolbar = (Toolbar) findViewById(R.id.toolbar);
coordinator = (MyCoordinatorLayout) findViewById(R.id.coordinator);
appbar = (ControllableAppBarLayout) findViewById(R.id.appbar);
appbar.addOnOffsetChangedListener(this);
getDelegate().setSupportActionBar(toolbar);
public void switchToFragment(Fragment fragment, String tag, boolean expandToolbar)
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment currentFragment = fragmentManager.findFragmentByTag(currentFragmentTag);
if(currentFragment == null || !TextUtils.equals(tag, currentFragmentTag) )
currentFragmentTag = tag;
fragmentManager
.beginTransaction()
.replace(R.id.flContent, fragment, currentFragmentTag)
.commit();
if(expandToolbar)
expandToolbar();
else
collapseToolbar();
protected void addFragment(Fragment fragment, String tag, boolean expandToolbar)
FragmentManager fragmentManager = getSupportFragmentManager();
currentFragmentTag = tag;
fragmentManager
.beginTransaction()
.add(R.id.flContent, fragment, currentFragmentTag)
.addToBackStack(tag)
.commit();
if(expandToolbar)
expandToolbar();
else
collapseToolbar();
protected void collapseToolbar()
appbar.collapseToolbar();
coordinator.setAllowForScroll(false);
public void expandToolbar()
appbar.expandToolbar();
coordinator.setAllowForScroll(true);
每次你想切换片段和折叠/展开工具栏时 使用适当的布尔参数调用方法 switchFragment/addFragment。
最后一个音符。确保使用最新的支持库。
dependencies
// android support
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:recyclerview-v7:22.2.1'
compile 'com.android.support:design:22.2.1'
不要在 AppBarLayout 中使用 include 标签。它不起作用
【讨论】:
以防误会。它不是“滚动”,而是“滚动”。无论如何,在 recyclerview 中使用空视图时,扩展 CoordinatorLayout 对我有用。谢谢【参考方案5】:以下代码实现了 3 个目标:
禁用 CollapsingToolbarLayout 由用户展开或折叠,但仍允许AppBarLayout.setExpanded
。
防止滚动 RecyclerView 或 NestedScrollView 展开或折叠 CollapsingToolbarLayout。
// scrollView can be RecyclerView or NestedScrollView
ViewCompat.setNestedScrollingEnabled(scrollView, false)
防止用户通过轻弹 AppBar 来展开或折叠 CollapsingToolbarLayout。
val params = appBar.layoutParams as CoordinatorLayout.LayoutParams
if (params.behavior == null)
params.behavior = AppBarLayout.Behavior()
val behaviour = params.behavior as AppBarLayout.Behavior
behaviour.setDragCallback(object : AppBarLayout.Behavior.DragCallback()
override fun canDrag(appBarLayout: AppBarLayout): Boolean
return false
)
https://code.luasoftware.com/tutorials/android/how-to-disable-or-lock-collapsingtoolbarlayout-collapse-or-expand/
【讨论】:
如果使用视图绑定/数据绑定,这似乎不起作用... 非常感谢,这真的拯救了我的一天!我使用 Java 和数据绑定添加了我对您的解决方案的改编:***.com/a/69045061/5369519【参考方案6】:使用 Android Design Library v23.1.1,@LucyFair 描述的方法不起作用。我设法通过仅将app:layout_scrollFlags
设置为 enterAlwaysCollapsed
来使其工作,并且应用栏保持“锁定”状态。
希望这会有所帮助。 :)
【讨论】:
锁定但展开【参考方案7】:我使用了@JasonWyatt的解决方案,并在行为类中添加了DragCallback
以防止触摸并拖动CollapsingToolbarLayout
来扩展它
private void setDragCallback()
setDragCallback(new DragCallback()
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout)
return mEnabled;
);
【讨论】:
【参考方案8】:我找到了一种适用于活动和各种片段的变通解决方案。您在 Activity 中使用 AppBar 等实现 CollapsingToolbarLayout,然后每次调用新片段时都可以调用这两个函数。
当我希望我的应用栏保持折叠状态时:
public void lockAppBarClosed()
mAppBarLayout.setExpanded(false, false);
mAppBarLayout.setActivated(false);
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams();
lp.height = (int) getResources().getDimension(R.dimen.toolbar_height);
当我希望我的应用栏再次展开和可滚动时
public void unlockAppBarOpen()
mAppBarLayout.setExpanded(true, false);
mAppBarLayout.setActivated(true);
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams();
lp.height = (int) getResources().getDimension(R.dimen.toolbar_expand_height);
您可以通过实现接口从片段中调用这些函数。这是一个简单的示例,适用于您的情况(工具栏仅在 homeFragment 中扩展)
public interface CustomListener()
void unlockAppBarOpen();
void lockAppBarClosed()
public class MainActivity extends BaseActivity implements CustomListener
@Override
public void unlockAppBarOpen()
mAppBarLayout.setExpanded(true, false);
mAppBarLayout.setActivated(true);
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams();
lp.height = (int) getResources().getDimension(R.dimen.toolbar_expand_height);
@Override
public void lockAppBarClosed()
mAppBarLayout.setExpanded(false, false);
mAppBarLayout.setActivated(false);
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)mAppBarLayout.getLayoutParams();
lp.height = (int) getResources().getDimension(R.dimen.toolbar_height);
public class MainFragment extends BaseFragment
@Override
public void onResume()
super.onPause();
((MainActivity) getContext()).unlockAppBarOpen();
public class SecondFragment extends BaseFragment
@Override
public void onResume()
super.onPause();
((MainActivity) getContext()).lockAppBarClosed();
用这个例子:
每次显示 MainFragment -> 都会扩展工具栏并使其可折叠和可展开
每次显示 SecondFragment -> il 都会将工具栏折叠到标准大小并防止其再次展开
希望对你有帮助!
【讨论】:
【参考方案9】:我在 CollapsingToolbarLayout 中找到了启用/禁用折叠的简单解决方案:
private void setExpandEnabled(boolean enabled)
mAppBarLayout.setExpanded(enabled, false);
mAppBarLayout.setActivated(enabled);
final AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
if (enabled)
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
else
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
collapsingToolbarLayout.setLayoutParams(params);
【讨论】:
这不会为我折叠工具栏,但如果我在 setExpanded 之后删除了代码,它肯定会折叠 @DasserBasyouni 是的,它不会崩溃。它只是调节 EXPANDED 布局的启用/禁用状态。如果您需要将 Enabled==false 更改为折叠,那么您应该将逻辑中的标志更改为:if (enabled) params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); else params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED);
要折叠的主要标志:SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED
感谢您的回复,但如果工具栏折叠一点,它仍然会展开工具栏,然后它会禁用滚动
这会导致 RecyclerView 在我滚动时几乎不会移动。【参考方案10】:
我无法发表评论,所以我会将我的补充发布到 JasonWyatt'sDisableAppBarLayoutBehavior 解决方案作为独立答案。
public class DisableableAppBarLayoutBehavior extends AppBarLayout.Behavior
private boolean mEnabled = true; // enabled by default
public DisableableAppBarLayoutBehavior()
super();
public DisableableAppBarLayoutBehavior(Context context, AttributeSet attrs)
super(context, attrs);
public void setEnabled(boolean enabled)
mEnabled = enabled;
@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type)
return mEnabled && super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type);
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type)
if (!isEnabled()) return;
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type)
if (!isEnabled()) return;
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
public boolean isEnabled()
return mEnabled;
除了 onStartNestedScroll 还锁定 onNestedPreScroll 和 onNestedScroll 本身以避免意外行为。例如,在我的情况下 - 在我的应用栏上调用 setExpanded(false, true) 会阻碍预期的行为,并且仍然会延迟扩展。现在可以了:
LayoutParams layoutParams = (LayoutParams) context.appBarLayout.getLayoutParams();
((DisableableAppBarLayoutBehavior)layoutParams.getBehavior()).setEnabled(false);
context.appBarLayout.setLayoutParams(layoutParams);
context.appBarLayout.setExpanded(false, true); // collapse app bar
【讨论】:
【参考方案11】:除了这个之外,所提供的解决方案都不适合我。使用此解决方案,我可以轻松管理折叠工具栏的状态。这将防止折叠工具栏的展开并为其设置标题。
public void lockAppBar(boolean locked,String title)
if(locked)
appBarLayout.setExpanded(false, true);
int px = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 80, getResources().getDisplayMetrics());
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)appBarLayout.getLayoutParams();
lp.height = px;
appBarLayout.setLayoutParams(lp);
collapsingToolbarLayout.setTitleEnabled(false);
toolbar.setTitle(title);
else
appBarLayout.setExpanded(true, false);
appBarLayout.setActivated(true);
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
lp.height = (int) getResources().getDimension(R.dimen.toolbarExpandHeight);
collapsingToolbarLayout.setTitleEnabled(true);
collapsingToolbarLayout.setTitle(title);
【讨论】:
【参考方案12】:像这样找到 AppBarLayout id。
appBarLayout = (AppBarLayout) findViewById(R.id.appbar);
对某些片段禁用 CollapsingToolbarLayout 的展开
appBarLayout.setExpanded(true,true);
为某些片段启用 CollapsingToolbarLayout 的展开
appBarLayout.setExpanded(false,true);
希望对你有帮助!!
【讨论】:
【参考方案13】:锁定和解锁是不够的,简单的锁定会使图像缩小;这是我的解决方案
在需要工具栏处于折叠模式的恢复时调用此方法。
private void lockAppBarClosed()
appBarLayout.setExpanded(false,true);
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
((CustomAppBarLayoutBehavior)layoutParams.getBehavior()).setScrollBehavior(false);
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
params.setScrollFlags(0);
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
这是一个需要Snap
的片段
public void unlockAppBarOpen()
appBarLayout.setExpanded(true,true);
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
((CustomAppBarLayoutBehavior)layoutParams.getBehavior()).setScrollBehavior(true);
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
params.setScrollFlags(0);
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP);
这是一个片段需要在SCROLL_FLAG_EXIT_UNTIL_COLLAPSED
模式下滚动。
public void unlockAppBarOpen()
appBarLayout.setExpanded(true,true);
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
((CustomAppBarLayoutBehavior)layoutParams.getBehavior()).setScrollBehavior(true);
AppBarLayout.LayoutParams params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams();
params.setScrollFlags(0);
params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
还有CustomAppBarLayoutBehavior.java
public class CustomAppBarLayoutBehavior extends AppBarLayout.Behavior
private boolean shouldScroll = false;
public CustomAppBarLayoutBehavior()
super();
public CustomAppBarLayoutBehavior(Context context, AttributeSet attrs)
super(context, attrs);
@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type)
return shouldScroll;
@Override
public boolean onTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev)
if(shouldScroll)
return super.onTouchEvent(parent, child, ev);
else
return false;
public void setScrollBehavior(boolean shouldScroll)
this.shouldScroll = shouldScroll;
public boolean isShouldScroll()
return shouldScroll;
将此行为提供给 AppBarLayout
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_
android:layout_
app:layout_behavior=".behaviors.CustomAppBarLayoutBehavior"
android:theme="@style/ThemeOverlay.MaterialComponents.ActionBar.Primary">
【讨论】:
【参考方案14】:您可以通过将折叠工具栏高度重置为工具栏高度来锁定 appbarlayout 扩展
toolbarHeight = toolbar.getLayoutParams().height;
if (expand)
collapsingToolbar.getLayoutParams().height = getResources().getDimensionPixelOffset(R.dimen.collapsingToolbarDefaultHeight);
appBarLayout.setExpanded(true, true);
else
//collapse
//** it is important you do this before resetting **
appBarLayout.setExpanded(false, true);
appBarLayout.postDelayed(new Runnable()
@Override
public void run()
collapsingToolbar.getLayoutParams().height = toolbarHeight;
, 700/* 600 is default animation time to collapse */);
【讨论】:
【参考方案15】:感谢@Desmond Lua's great answer 我终于能够在我的代码中解决这个问题。这是我使用 Java 和数据绑定的改编解决方案。
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar"
bind:expanded="@myCondition? false : true"
app:disableCollapsingScroll="@myCondition? false : true"
... >
<com.google.android.material.appbar.CollapsingToolbarLayout
... >
...
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:nestedScrollingEnabled="@myCondition? false : true"
... >
...
</NestedScrollView>
@BindingAdapter("disableCollapsingScroll")
public static void bindDisableCollapsingScroll(AppBarLayout appBarLayout, boolean disabled)
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
if (params.getBehavior() == null)
params.setBehavior(new AppBarLayout.Behavior());
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback()
@Override
public boolean canDrag(@NonNull AppBarLayout appBarLayout)
return disabled;
);
【讨论】:
以上是关于需要为某些片段禁用 CollapsingToolbarLayout 上的展开的主要内容,如果未能解决你的问题,请参考以下文章