可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The app I'm working on consists of a Navigation Drawer which is implemented in an Activity. The activity layout is as follows:
This is a very common pattern, only thing that changes frequently is the Fragment inside the container layout.
If any of the Fragment has a scrolling element, upon scrolling, the CoordinatorLayout will happily make position translations, including the Toolbar/AppBarLayout.
The real problem here is, when the Fragment gets replaced, the position for the Toolbar remains the same, i.e., if the Toolbar is hidden, it will stay so which isn't intended.
Result is this:
This:
Gets stuck:
How can one reset the Toolbar position for this case?
EDIT: A bug is probable, the AppBarLayout offset change listener gets called only when relaunching the app (press back button and open the app), and stops getting called again after an intense fling.
回答1:
To reset the scroll state, just get the AppBarLayout.Behavior
object
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();
and call onNestedPreScroll
method manually:
int[] consumed = new int[2]; behavior.onNestedPreScroll(coordinator, appbar, null, 0, -1000, consumed);
If you would like to reset smoothly with an animation, you can try calling onNestedFling
instead:
behavior.onNestedFling(coordinator, appbar, null, 0, -1000, true);
回答2:
First get a AppBarLayout refrence in you MainActivity, then in the pause state of the fragment that is being replaced, use the method below to expand toolbar :
MainActivity.appbar.setExpanded(true,true);
And or to close the toolbar :
MainActivity.appbar.setExpanded(false,true);
The second parameter is used to scroll the toolbar smoothly.
回答3:
Update your support lib to v23 then you can use:
appBarLayout.setExpanded(true/false);
public void setExpanded (boolean expanded)
Sets whether this AppBarLayout is expanded or not, animating if it has already been laid out.
As with AppBarLayout's scrolling, this method relies on this layout being a direct child of a CoordinatorLayout.
expanded true if the layout should be fully expanded, false if it should be fully collapsed
回答4:
@razzledazzle The AppBarLayout stores onOffsetChangedListeners as WeakReferences, which means they are garbage collected when needed, for instance when you do a intense fling. See solution here:
https://code.google.com/p/android/issues/detail?id=176328
回答5:
I'm using this codes before fragment changes.
scrollingElement.startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL); scrollingElement.dispatchNestedPreScroll(0, -Integer.MAX_VALUE, null, null); scrollingElement.stopNestedScroll();
回答6:
Replace or Wrap the FrameLayout
inside the android.support.design.widget.CoordinatorLayout
with a android.support.v4.widget.NestedScrollView
and that will do the job automatically without having to any other hacks....so it would look like this:
回答7:
As document said
AppBarLayout supports
void setExpanded (boolean expanded, boolean animate);
Sets whether this AppBarLayout is expanded or not.
- expanded boolean: true if the layout should be fully expanded, false if it should be fully collapsed
- animate boolean: Whether to animate to the new state
So at first you need
AppBarLayout appBarLayout = (AppBarLayout)findViewById(R.id.appBarLayout);
then to expand layout
appBarLayout.setExpanded(true, true); // with animation appBarLayout.setExpanded(true, false); // without animation
and to collapse layout
appBarLayout.setExpanded(false, true); // with animation appBarLayout.setExpanded(false, false); // without animation