im using a coordinatorLayout and a floating action button between two layers, like this:
in the orange part i put a NestedScrollView to show alot of information about the product that have his photo on purple part.
When the users scrolls the layout and the anchor of the FAB ( the image on purple layout) is gone, the FAB keeps on top|right of the layout.
what im trying to do is: when the anchor is gone, the FAB go to buttom|right of the layout insted to remain on top of screen.
can you help me? thanks :)
I've used this code to change the actionbar title when to toolbar collapses. You can reuse it to change the fab position instead of changing the title :
((AppBarLayout) findViewById(R.id.appbar)).addOnOffsetChangedListener(new AppBarStateChangeListener() {
#Override
public void onStateChanged(AppBarLayout appBarLayout, State state) {
switch (state) {
case COLLAPSED:
getSupportActionBar().setTitle(mMatch.getUniversity().getDisplayName());
break;
case NOT_COLLAPSED:
getSupportActionBar().setTitle("");
break;
}
}
});
Related
i need some help with my toolbar.
Right now i use a collapsing toolbar with image wich collapsed when i scroll up.
I know i can use contentScrim to make the Toolbar transparent and therefore see the image as "toolbar background".
However, i want the image to blur(/fade) when the toolbar is collapsed.
Any suggestions how to achieve this?
You can use this library. (RealTimeBlurView)
For the blur effect, just put the imageview behind the blurview.
To achieve what you want just change blurview's alpha when the app bar is scrolled.
appbar.addOnOffsetChangedListener(new OnOffsetChangedListener() {
#Override
public void onOffsetChanged(final AppBarLayout appBarLayout, final int verticalOffset) {
float offsetAlpha = (appBarLayout.getY() / appbar.getTotalScrollRange());
blurView.setAlpha( 1 - (offsetAlpha * -1));
}
});
UPDATE
FastBlur
Here's another benchmarking project to showcase all the possible blurring methods in android. Just get the fastest algorithm from the demo and use it in your project.
Hope this helps!
I was using Collapsible Toolbar in my app. On activity launch Collapsible Toolbar is expanded state with scrolling enabled and its working well normally. But now I have a requirement to show a full screen error layout in case my API fails. In that case I have to collapsed toolbar with scrolling effect blocked.
Error Layout shows a Retry Button. On Retry I make API call again and if API gives success I have to again expand Toolbar and enable scrolling effect.
I was able to collapse toolbar with setExpanded(flag, animate) but in that case I am not able to block scrolling effect of Collapsible Toolbar while error layout is shown.
I need to provide a way to block as well as unblock scroll effect + Expand/Collapse Toolbar. Any help would be really appreciated.. !!!
Make your error layout such that it will overlap Collapsible Toolbar. Also set android:clickable="true" to your error layout.
When you set visibility to your error layout, set Toolbar scrolling accordingly.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f3f3f3"
android:orientation="vertical"
>
<!-- Add your other layout including Collapsible Toolbar here.-->
<RelativeLayout
android:id="#+id/errorLayout"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
I created a library AppBarrr to lock the screen in expanded mode, based on my previous answer.
As I said, the height of the Toolbar is the key: the CollapsingToolbarLayout will collapse until the Toolbar's height and will expand until the AppBarLayout's height.
With this library, you must set two layouts as the Toolbar and your Expanded Layout (used to lock the screen and the scroll), it will create a CollapsingToolbarLayout and inflate these layouts inside.
You can declare the animations duration, the color of the inner CollapsingToolbarLayout, the collapsed/expanded title's style, even the height of the locked layout... You could also hide the Expanded Layout if you click outside it. It can support NestedScrollView and ScrollView inside the Expanded Layout. The documentation and a sample app are available on Github.
For those who don't want to use the library, my previous answer shows the way to do it. Here's the output of the previous answer:
Basically, this is the same concept, but no need to write a full class, with the lib you just need to have a simple widget in xml and that's it!
Feel free to use, fork or test. Hope it will be useful ;)
If you use AlertDialog to communicate the error and a ProgressDialog (spinner) to show you are doing stuff, you can block user input while your app is doing it's thing.
A simple solution that you can apply is just use the property
android:visibility="gone"
for the content that you don't want to show and just make your error layout visible by using property android:visibility="visible"
place the error layout at the bottom of your parent layout
once the contents are not visible on screen and error layout is just visible you will achieve the desired result that you want. Hope this helps you.
You can implement the interface and call its methods when to enable or disable the collapsing effect.
public interface AppbarRequestListener {
void unlockAppBarOpen();
void lockAppBarClosed();
}
#Override
public void unlockAppBarOpen() {
appBarLayout.setExpanded(true, false);
appBarLayout.setActivated(true);
setAppBarDragging(false);
}
#Override
public void lockAppBarClosed() {
appBarLayout.setExpanded(false, false);
appBarLayout.setActivated(false);
setAppBarDragging(false);
}
private void setAppBarDragging(final boolean isEnabled) {
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
#Override
public boolean canDrag(AppBarLayout appBarLayout) {
return isEnabled;
}
});
params.setBehavior(behavior);
}
I have CoordinatorLayout with AppBarLayout and Toolbar inside it:
CoordinatorLayout
- AppBarLayout
- Toolbar
animateLayoutChanges=true
Nice. And I use this code to hide/show back arrow button:
private void setBackArrowState(boolean state) {
actionBar.setDisplayHomeAsUpEnabled(state);
actionBar.setDisplayShowHomeEnabled(state);
}
There is what I got in result:
When the back arrow button hide, title not animated to it's normal position. How can I solve it?
After extensive searching it seems that surprisingly no one is interested in the same behavior. Please point me to the appropriate place if I missed it.
The problem is the following:
I have a coordinator layout in the main activity xml. Inside of the coordinator layout there is a view pager. Inside two of the three fragments that I put inside the view pager there are recycle views that trigger the hiding of the toolbar in the coordinator layout. The third fragment does not have a recycle view though. The issue is that when the toolbar is shown the third fragment is drawn lower than it should, hiding part of the ui below the bottom edge of the screen. If the toolbar is hidden everything is shown normally.
So the question is - how can I hide the toolbar programmatically? e.g. when the user swipes to the third fragment in the view pager?
If you think there is a better approach - I would be also glad to hear that. Thanks!
Answer to your question :
I assume your Toolbar is included in a AppBarLayout.
To achieve it, you can add a ViewPager.OnPageChangeListener to your ViewPager, and in the onPageSelected() callback call setExpanded() on your AppBarLayout :
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
#Override
public void onPageSelected(int position) {
if(position == 2) { //the position of your non-scrolling fragment
AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar);
appBarLayout.setExpanded(false, true); //Hide the toolbar.
}
}
#Override
public void onPageScrollStateChanged(int state) { }
});
Alternate approach :
Another approach, won't say better, I'll let you judge depending on your content and user interactions, can be to keep having the same scrolling effect on your non-recycler fragment.
You can easily implement that by wrapping your fragment content in a NestedScrollView (included in support-v4) with the corresponding Behaviour that will trigger the hiding of the toolbar in your CoordinatorLayout :
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:fillViewport="true">
<!-- Your non-recycler view fragment layout -->
</android.support.v4.widget.NestedScrollView>
A nice blog post about scrolling, tabs and CoordinatorLayout : https://mzgreen.github.io/2015/06/23/How-to-hideshow-Toolbar-when-list-is-scrolling(part3)/
I have a layout identical to the Play Store where I have a Toolbar, Tab Strip, and ViewPager all in a vertical LinearLayout. I want to achieve the quick return pattern of the Play Store where the Toolbar hides but the TabStrip and ViewPager stay but animate up with the Toolbar.
I have the animating Toolbar part down using animate().translateY() but I can't get the content to shift up with it (at least not smoothly). I've tried something like:
<FrameLayout>
<Toolbar (with WindowActionBarOverlay = true)>
<LinearLayout paddingTop = Toolbar_height>
*Contains all the stuff I don't want to hide*
</LinearLayout>
</FrameLayout>
But this doesn't make the content shift up either. So I tried setting the Top Padding of the LinearLayout to 0 after I animate the Toolbar but that is instantaneous rather than animating with the ToolBar. So I tried to animate the entire LinearLayout instead using animate().translateY() but that is a bit laggy and has some unwanted side effects.
Anyone have any ideas? For RecyclerView and preferably a minSDK of 15.
Try adding an animator listener on the toolbar's translation to update the padding. Back-of-napkin code:
toolbar.animate()
.translateY(-toolbar.getHeight())
.setUpdateListener(new AnimatorUpdateListener()) {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
contentView.setPadding(
contentView.getPaddingLeft(),
// The padding is the inverse of the animation progress.
toolbar.getHeight() * (1f - animation.getAnimatedFraction()),
contentView.getPaddingRight(),
contentView.getPaddingBottom());
}
});
I'd be interested to see what the performance is like updating the layout on each animation frame like that.