私が取り組んでいるアプリは、アクティビティに実装されているナビゲーションドロワーで構成されています。アクティビティのレイアウトは次のとおりです。
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.v4.widget.DrawerLayout
Android:id="@+id/drawer_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.design.widget.CoordinatorLayout
Android:id="@+id/coordinator"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<FrameLayout
Android:id="@+id/container"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<include
Android:id="@+id/appbar"
layout="@layout/appbar" />
</Android.support.design.widget.CoordinatorLayout>
<Android.support.design.widget.NavigationView
Android:id="@+id/navigation_drawer"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_gravity="start"
app:headerLayout="@layout/header_drawer"
app:menu="@menu/menu_nav">
</Android.support.design.widget.NavigationView>
</Android.support.v4.widget.DrawerLayout>
</FrameLayout>
これは非常に一般的なパターンで、頻繁に変更されるのはコンテナレイアウト内のフラグメントのみです。
フラグメントのいずれかにスクロール要素がある場合、スクロール時にCoordinatorLayoutはツールバー/ AppBarLayoutを含む位置の変換を喜んで行います。
ここでの本当の問題は、フラグメントが置き換えられたとき、ツールバーの位置が同じままであることです。つまり、ツールバーが非表示の場合、意図しないままになります。
結果は次のとおりです。
この:
動けなくなる:
この場合のツールバーの位置をリセットするにはどうすればよいですか?
編集:バグの可能性があります。AppBarLayoutのオフセット変更リスナーは、アプリを再起動するときにのみ呼び出され(戻るボタンを押してアプリを開く)、激しい放り込みの後に再び呼び出されるのを停止します。
スクロール状態をリセットするには、AppBarLayout.Behavior
オブジェクト
CoordinatorLayout coordinator = (CoordinatorLayout) findViewById(R.id.coordinator);
AppBarLayout appbar = (AppBarLayout) findViewById(R.id.appbar);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appbar.getLayoutParams();
AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior();
onNestedPreScroll
メソッドを手動で呼び出します。
int[] consumed = new int[2];
behavior.onNestedPreScroll(coordinator, appbar, null, 0, -1000, consumed);
アニメーションでスムーズにリセットしたい場合は、代わりにonNestedFling
を呼び出してみてください:
behavior.onNestedFling(coordinator, appbar, null, 0, -1000, true);
まずMainActivityでAppBarLayoutの参照を取得し、次に置換されるフラグメントの一時停止状態で、以下のメソッドを使用してツールバーを展開します。
MainActivity.appbar.setExpanded(true,true);
または、ツールバーを閉じるには:
MainActivity.appbar.setExpanded(false,true);
2番目のパラメーターは、ツールバーをスムーズにスクロールするために使用されます。
サポートライブラリをv23に更新すると、次を使用できます。
appBarLayout.setExpanded(true/false);
public void setExpanded(boolean expanded)
このAppBarLayoutが展開されているかどうかを設定し、既にレイアウトされている場合はアニメーション化します。
AppBarLayoutのスクロールと同様に、このメソッドはこのレイアウトがCoordinatorLayoutの直接の子であることに依存しています。
expandedレイアウトを完全に展開する必要がある場合はtrue、完全に折りたたむ必要がある場合はfalse
@razzledazzle AppBarLayoutは、onOffsetChangedListenersをWeakReferencesとして保存します。これは、たとえば激しいフリングを行うときなど、必要なときにガベージコレクションされることを意味します。ここで解決策を参照してください:
フラグメントが変更される前にこのコードを使用しています。
scrollingElement.startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
scrollingElement.dispatchNestedPreScroll(0, -Integer.MAX_VALUE, null, null);
scrollingElement.stopNestedScroll();
ドキュメント のように
AppBarLayoutサポート
void setExpanded(ブール展開、ブールアニメーション);
このAppBarLayoutを展開するかどうかを設定します。
- expandedboolean:レイアウトを完全に展開する必要がある場合はtrue、完全に折りたたむ必要がある場合はfalse
- animateboolean:新しい状態にアニメートするかどうか
最初に、あなたが必要です
AppBarLayout appBarLayout = findViewById(R.id.appBarLayout);
次にexpandレイアウトに
appBarLayout.setExpanded(true, true); // with animation
appBarLayout.setExpanded(true, false); // without animation
およびtocollapseレイアウト
appBarLayout.setExpanded(false, true); // with animation
appBarLayout.setExpanded(false, false); // without animation
Android.support.design.widget.CoordinatorLayout
内のFrameLayout
をAndroid.support.v4.widget.NestedScrollView
で置換またはラップすると、他のハッキングなしで自動的にジョブが実行されます。次のようになります。
<Android.support.design.widget.CoordinatorLayout
Android:id="@+id/coordinator"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.v4.widget.NestedScrollView
Android:id="@+id/container"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<include
Android:id="@+id/appbar"
layout="@layout/appbar" />
</Android.support.design.widget.CoordinatorLayout>