I have a fragment which renders a recycleview with an floating action button. The problem is that when the list is empty, the fab keeps on the right top, when the list has few items, the fab keeps below the list but not at the bottom, and it only keeps totally at the bottom when the list fill the screen with items. Could somebody help me please? Bellow is my code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
tools:context="com.app.juninho.financeapp.activity.FuncionarioActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/funcionario_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/btn_add_func"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right|end"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_margin="16dp"
android:src="#drawable/ic_menu_send"
app:layout_behavior="com.app.juninho.financeapp.utils.ScrollAwareFABBehavior" />
</android.support.design.widget.CoordinatorLayout>
if the list is empty, fab keeps at the top, which is wrong:
if the list has a few items, fab doesn't keep totally at the bottom:
Here is the correct way, fab is at the bottom:
Using RelativeLayout it seems to work, but its too at the right/bottom corner:
The problem is your FAB attribute: app:layout_behavior="com.app.juninho.financeapp.utils.ScrollAwareFABBehavior".
#. You don't need to add this with your FAB. Just remove this attribute and add attribute app:layout_anchor="#id/funcionario_recycler_view" and app:layout_anchorGravity="bottom|right|end" to FAB to anchor it with RecyclerView.
Update your layout as below:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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"
tools:context="com.app.juninho.financeapp.activity.FuncionarioActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/funcionario_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/btn_add_func"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right|end"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_margin="16dp"
android:src="#drawable/ic_menu_send"
app:layout_anchor="#id/funcionario_recycler_view"
app:layout_anchorGravity="bottom|right|end" />
</android.support.design.widget.CoordinatorLayout>
#. If you want to hide/show FAB when scrolling RecyclerView, then you can do it pragmatically in your java code as below:
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.funcionario_recycler_view);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.btn_add_func);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
if (dy > 0 ||dy<0 && fab.isShown())
{
fab.hide();
}
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
{
if (newState == RecyclerView.SCROLL_STATE_IDLE)
{
fab.show();
}
super.onScrollStateChanged(recyclerView, newState);
}
});
Hope this will help~
Related
I'd like to achieve the flow like gmail
i've tried this so far
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#android:color/transparent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/story_toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/measure_50dp"
app:layout_scrollFlags="scroll|enterAlways" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/tv_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/measure_15dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Appbar hides while scroll up but doesnt appear on scroll down until its completely scrolled down. I'd like to achieve the flow like gmail, where the recyclerView is match_parent and it appears behind the toolbar when scrolled up, and toolbar hides/unhides on srcroll up and down in a nested scroll view. Any help is appreciated, Thanks!
You have to create nestedScrollview addOnScrollChangedListener like this
float viewScrolled = 0f
nestedScrollview.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver
.OnScrollChangedListener() {
if (viewScrolled < nestedScrollview.getScrollY()) {
viewScrolled = nestedScrollview.getScrollY();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Hide your app bar
}
}
if (viewScrolled > nestedScrollview.getScrollY()) {
viewScrolled = nestedScrollview.getScrollY();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (viewScrolled == 0F) {
// Show your app bar
}
}
}
And also refer this link:-https://medium.com/#tonia.tkachuk/appbarlayout-scroll-behavior-with-layout-scrollflags-2eec41b4366b
I have an AppBar and RecyclerView in CoordiantorLayout. SwipeToRefresh has to be fullscreen but RecyclerView not scrolling down then.
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="128dp"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
How to add fullscreen pull to refresh in Coordinator layout without a library.
You can disable swipe refresh layout when AppBar isn't fully expanded and enable it if it is fully expanded.
vAppBar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
vSwipeRefresh.isEnabled = verticalOffset == 0
})
I add swipetorefresh top level like answer above. And I fix my scroll up issue with code below. Thanks to mohammadReza :)
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int topRowVerticalPosition =
(recyclerView == null || recyclerView.getChildCount() == 0) ? 0 : recyclerView.getChildAt(0).getTop();
swipeRefreshLayout.setEnabled(topRowVerticalPosition >= 0);
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
try to set SwipeRefreshLayout as root parent like this :
<?xml version="1.0" encoding="utf-8"?>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="128dp" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
I'm trying to implement hide/show SearchView on scroll feature inside a SwipeRefreshLayout.
I want to show SearchView when user scroll to the bottom and hide - when scroll to top.
Also i want to keep swipe refresh behaviour.
Tried many examples, but haven't seen close results.
My xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/loading_bar"/>
<include layout="#layout/network_error"/>
<include layout="#layout/empty_materials_coinlist"/>
<RelativeLayout
android:id="#+id/coinlist_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/coinlist_item_bg">
<RelativeLayout
android:id="#+id/custom_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="exitUntilCollapsed">
<TextView
android:id="#+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="toolbar_title"
android:textColor="#color/toolbar_text_color"
android:textSize="18sp"
android:typeface="sans"
android:layout_gravity="center" />
</RelativeLayout>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/custom_toolbar">
<android.widget.SearchView
android:id="#+id/sv_coin"
android:layout_width="match_parent"
android:layout_height="40dp"
android:iconifiedByDefault="false"
app:layout_scrollFlags="scroll|enterAlways|snap"/>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/currenciesRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/coinlist_item_bg"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
Try this
myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) {
//check for scroll down
int itemPosition = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
if(itemPosition==list.size()){// your last item your recyclerview
// hide your SearchView here
}
} else {
//check for scroll up
int itemPosition = linearLayoutManager.findLastCompletelyVisibleItemPosition();
if(itemPosition==0){
// show your SearchView here
}
}
}
});
I have a Recyclerview inside Scrollview, I want to store item details of Recyclerview where scroll stopped.
I have a xml like,
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/White">
<RelativeLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/tile_view_pager"
android:layout_width="match_parent"
android:layout_height="200dp"
android:visibility="gone"
android:layout_marginRight="2dp"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/news_feed_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
I have added ScrollListener for recyclerview. But As I'm using parent Scrollview for the activity, recyclerview's ScrollListener is not getting called.
I tried changing parent scrollview to NestedScrollView then recyclerview is scrolling as a one item at once but i want scroll to be freely. Like scrolling our contacts.
Issue : When I scroll, Parent ScrollView getting scrolled and I don't have any control on my recyclerview. So It's difficult to figure out which item of recyclerview is visible once scroll stopped.
Basically I want to code without changing my XML.
I want to store item details of Recyclerview where scroll stopped.
When scroll stops, scroll state transitions into idle state. However, idle state is the state before and after scroll. Therefore you are looking for a transition into idle state after settling state.
Do it like this:
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
boolean scrolled;
int[] displayedPositions;
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_SETTLING) {
scrolled = true;
} else if (newState == RecyclerView.SCROLL_STATE_IDLE && scrolled) {
scrolled = false;
int[] into = new int[//number of spans];
displayedPositions = ((StaggeredGridLayoutManager) recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPositions(into)
}
}
}
private int overallXScrol = 0;
//...
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
overallXScroll = overallXScroll + dx;
Log.i("check","overall->" + overallXScroll);
}
});
try NestedScrollView instead scrollview like below
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/White">
<RelativeLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/tile_view_pager"
android:layout_width="match_parent"
android:layout_height="200dp"
android:visibility="gone"
android:layout_marginRight="2dp"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/news_feed_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
I found the solution. Just we need to change layout. I'm using CoordinatorLayout as a parent view. And Now I'm able to use onScrollListener of recyclerview.
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/White">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="#+id/tile_view_pager"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginEnd="2dp"
android:visibility="gone"/>
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/news_feed_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
click here to view image
how can i place the as floating button as shown image position. Below is my XML code
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.RecyclerView
android:id="#+id/rec_summary_recycler_view_inflow"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarSize="5dp"
android:scrollbars="vertical"
android:scrollbarThumbVertical="#drawable/scr"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:backgroundTint="#color/colorPrimary"
android:src="#drawable/down_arrow"
android:layout_margin="25dp"
app:fabSize="mini"
android:onClick="Scroll" />
Try to add this lines in fab. change value according to your needs. this lines will sets a fab to right bottom of screen.
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_gravity="end|bottom"
use this to hide show the fab on recyclerview scroll
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
if (dy > 0 ||dy<0 && fab.isShown())
{
fab.hide();
}
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
{
if (newState == RecyclerView.SCROLL_STATE_IDLE)
{
fab.show();
}
super.onScrollStateChanged(recyclerView, newState);
}
});
Give an id to your content_layout.xml (id:layout_content) and use app:layout_anchor="#id/layout_content" in your fab layout.
<include layout="#layout/content_order_list"
android:id="#+id/layout_content"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="#id/layout_content"
app:layout_anchorGravity="bottom|end"
android:layout_marginBottom="90dp"
android:layout_marginEnd="#dimen/activity_horizontal_margin"
android:layout_marginRight="#dimen/activity_horizontal_margin"
app:srcCompat="#android:drawable/ic_dialog_email" />