my app has 3 fragments that are being inflated from mainActivity with BottomNavigationView. One of the fragments uses RecyclerView and is scrollable, with BottomNavigationView the last item in recyclerView is being covered up. According to Google's guidelines bottomNavigationView should hide on scroll down and show on scroll up. It's easy enough to make it hide from the mainAcitivity but it doesn't work when Im trying to hide it from the other fragment. How do I do this properly?
This code from recyclerView checks for the scroll state:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) {
//mainActivity.setNavigationVisibility(false);
} else if (dy < 0 ) {
//mainActivity.setNavigationVisibility(true);
}
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
And should call this method in the mainActivity that hides the bottomNavigationView:
public void setNavigationVisibility(boolean visible) {
if (navigation.isShown() && !visible) {
navigation.setVisibility(View.GONE);
}
else if (!navigation.isShown() && visible){
navigation.setVisibility(View.VISIBLE);
}
}
try this
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) {
((MainActivity)getActivity()).setNavigationVisibility(false);
} else if (dy < 0 ) {
((MainActivity)getActivity()).setNavigationVisibility(true);
}
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
When you use activity method from fragment then you have to create your method public and you can access that method by typecasting.
Related
I have a RecyclerView with Horizontal LinearLayoutManager.
I would like to check ScrollListener.
My goal is to check these steps:
Check when RecyclerView start scroll
Check when RecyclerView end scroll
Check when RecyclerView's scroll is in center position
Here is a my RecyclerView code with LinearLayoutManager.
LinearLayoutManager horizontalManager = new LinearLayoutManager(context);
horizontalManager.setOrientation(LinearLayoutManager.HORIZONTAL);
viewHolderStory.recyclerView.setLayoutManager(horizontalManager);
viewHolderStory.recyclerView.addItemDecoration(new PaddingItemDecoration((Activity) context));
viewHolderStory.recyclerView.setHasFixedSize(true);
viewHolderStory.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
});
viewHolderStory.recyclerView.setNestedScrollingEnabled(false);
Is any way to add validation on my addOnScrollListener method?
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if(newState==RecyclerView.SCROLL_STATE_IDLE){
/// User Stops Scroll
}
if(newState==RecyclerView.SCROLL_STATE_DRAGGING){
/// User Starts Scroll
}
}
You can find more from this.
You can compute this with computeVerticalScrollExtent() , computeVerticalScrollOffset() and computeVerticalScrollRange()
if your recyler view is horizontal, these functions have a horizontal counterpart
full code :
viewHolderStory.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
int extent = recyclerView.computeVerticalScrollExtent();
int offset = recyclerView.computeVerticalScrollOffset();
int range = recyclerView.computeVerticalScrollRange();
if(offset == 0){
//fire when recycler view hit top
Log.i("myTag", "onScrolled: top");
}
else if(offset + extent == range){
//fire when recycler view hit bottom
Log.i("myTag", "onScrolled: bottom");
}
else {
//fire the rest of the time
Log.i("myTag", "onScrolled: middle");
}
}
});
I have a horizontal Recycler view implemented with SnapHelper to get a carousal effect. In my ViewHolder I have a function to animate the views inside Recycler item. So whenever an item is scrolled to center (selected) in SnapHelper I need to start the animation. I have tried following code but its not working. Sometimes I am getting viewholder as null.
widgetScrollView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(final RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_SETTLING) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
int pos = ((LinearLayoutManager) widgetScrollView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
ResultTallyAdapter.ViewHolder viewHolder = (ResultTallyAdapter.ViewHolder) recyclerView.findViewHolderForAdapterPosition(pos);
viewHolder.startAnimation(MainActivity.this, pos);
}
}, 1000);
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
I was trying same thing like you. But code is different. I use SnapHelper to find current view and get position from this view and start operation on adapter by this position. You can get idea following code, may help you
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
synchronized (this) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
//calculatePositionAndScroll(recyclerView);
View view = snapHelper.findSnapView(recyclerView.getLayoutManager());
if (view != null) {
int pos = recyclerView.getLayoutManager().getPosition(view);
Log.d("RecyclerViewTest", "position: " + pos + " item: " + itemList.get(pos).getName());
makeSelectedItem(pos); // do your stuff on this view
// adapter.notifyDataSetChanged();
}
}
}
}
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
How can I get object from recyclerview when it leaves screen while scrolling? For example I have note with id 11 how can I get this note id whenever it leaves screen?
One way you could do it:
Boolean upScrolling;
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
LinearLayoutManager mgr = (LinearLayoutManager) recyclerView.getLayoutManager();
int topPosition = mgr.findFirstVisibleItemPosition();
/// your code
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy < 0) {
upScrolling = true;
} else if (dy > 0) {
upScrolling = false;
}
}
});
After scrolling up, in the listener you get the 1st visible item. At the position your code you write the code to check if the 1st visible item is the one below the item you want. If this is the case then you get the time it went off the screen.
Edited to check if it scrolls up or down.
Basically I want my recyclerview to automatically scroll to a position where the item is not half shown. Like the one in googleplay.
I have written a code
public void scrollToVisible(){
int firstVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
View view = recyclerView.getLayoutManager().getChildAt(0);
if (firstVisibleItemPosition > 0 && view != null) {
int offsetTop = view.getTop();
if (firstVisibleItemPosition - 1 >= 0 && adapter.getItemCount() > 0) {
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(firstVisibleItemPosition - 1, offsetTop);
}
}
}
The problem comes next. I dont know where to put this code. I have a vague idea to put it when the recyclerview stops on scrolling but I've been searching for quite some time now and i cant find such a method. when i put it on the onScroll some unexpected behavior comes out
You may create a CustomRecyclerView extending RecyclerView
public class CustomRecyclerView extends RecyclerView {
#Override
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
// check if scrolling has stopped
if (state == SCROLL_STATE_IDLE) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();
// use code here
}
}
If it maybe of any help to someone:
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Log.d("y value",String.valueOf(dy));
if (dy > 0) {
//scrolling up
} else {
// Scrolling down
}
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
// Do something
Log.e("SCROLL_STATE_FLING","SCROLL_STATE_FLING");
} else if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
Log.e("SCROLLTOUCH_SCROLL","SCROLL_STATE_TOUCH_SCROLL");
//slideUp(party_view);
// Do something
} else if (newState==AbsListView.OnScrollListener.SCROLL_STATE_IDLE){
// Do something
//slideDown(party_view);
Log.e("SCROLL_STATE_IDLE","SCROLL_STATE_IDLE");
}
}
});
complete example with UI synchronization
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
Handler handler = new Handler(getMainLooper());
if (newState == 0) {
handler.removeCallbacks(MainActivity.this::hideFab);
handler.postDelayed(MainActivity.this::showFab, 400);
} else {
handler.removeCallbacks(MainActivity.this::showFab);
handler.postDelayed(MainActivity.this::hideFab, 100);
}
}
});
private void hideFab() {
addFile.hide();
addText.hide();
camera.hide();
}
private void showFab() {
addFile.show();
addText.show();
camera.show();
}
I am developing an App for Android TV via Nexus Player. In my App, I use the VerticalGridFragment to show TV shows. For shows' number is 2000+, I want to use page loading when the VerticalGridView scrolls to its bottom.
However, I get stuck on how to judge the VerticalGridView has scrolled to bottom.
I use reflect to get the VerticalGridView,and addScrollListener() to it.Here the codes:
private void addGridScrollListener() {
try {
Class<VerticalGridFragment> VerticalGridFragmentClass = VerticalGridFragment.class;
Field verticalGridViewHolder = VerticalGridFragmentClass.getDeclaredField("mGridViewHolder");
verticalGridViewHolder.setAccessible(true);
VerticalGridPresenter.ViewHolder viewHolder = (VerticalGridPresenter.ViewHolder) verticalGridViewHolder.get(this);
VerticalGridView gridView = viewHolder.getGridView();
gridView.addOnScrollListener(scrollListener);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
private RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
};
RecyclerView doesn't has the function such as getLastVisiableItemPosition, so I can't know if the VerticalGridView has scrolled to bottom or not.
What should I do in the scrollListener ? Or is there any other solutions?
Thanks!
I found the solution:
private RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState != RecyclerView.SCROLL_STATE_IDLE) {
return;
}
//get current last child View
View lastChildView = recyclerView.getLayoutManager().getChildAt(recyclerView.getLayoutManager().getChildCount() - 1);
//get the bottom
int lastChildBottom = lastChildView.getBottom();
// get recyclerView's bottom
int recyclerBottom = recyclerView.getBottom() - recyclerView.getPaddingBottom();
//get last childview's position
int lastPosition = recyclerView.getLayoutManager().getPosition(lastChildView);
if (lastChildBottom == recyclerBottom && lastPosition == recyclerView.getLayoutManager().getItemCount() - 1) {
// yes to bottom.
}
}
};