Recylcerview hides a layout as its scroll - android

Currently, if the 2nd item in the recyclerview is not visible to the user, a specific layout will be hidden/gone.
So this is my current code:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, final int dy) { final float test = dy;
if (layoutManager.findFirstCompletelyVisibleItemPosition() > 2) {
if(mAccountLayout.isShown() && mDateLayout.isShown()) {
mAccountLayout.setVisibility(View.GONE);
mDateLayout.setVisibility(View.GONE);
Log.d("SCROLLINGDOWN", "SCROLL");
Log.d("SCROLLdown",""+dy);
}
} else {
if(!mAccountLayout.isShown() && !mDateLayout.isShown()) {
mAccountLayout.setVisibility(View.VISIBLE);
mDateLayout.setVisibility(View.VISIBLE);
Log.d("SCROLLINGUP", "SCROLL");
Log.d("SCROLLUP",""+dy);
}
}
}
});
What i want is to have atleast an animation when the layout is being hidden/gone. Would likely similar to this: Sample animation without using coordinator layout.
If the user scroll slowly down, then the layout should be also slowly be hidden until the 2nd item in the recyclerview is no longer visible.

Related

How to solve problem with recylerView that is not detecting scrolling of this, if I load exactly 10 items while pagination or when it covers screen

If I load more than 10 items it works fine. e.g. I select 25 or 50 limits from spinner pagination works fine, but when I select limit 10, then scrolling is not detected inside onScrolled of addOnScrollListener method.
Or if I load the amount of elements that cover the screen, then we need to scroll further items of recyclerView.
RecyclerView creation method
VulnerabilityScanAdapter vulnerabilityScanAdapter = new VulnerabilityScanAdapter(
getActivity(), callback, vulnerabilityScanPojoList
);
vulnerabilityScanAdapter.notifyDataSetChanged();
final LinearLayoutManager mLayoutManager = new LinearLayoutManager(getContext(),
LinearLayoutManager.VERTICAL, false);
vulnerabilityScanRv.setLayoutManager(mLayoutManager);
vulnerabilityScanRv.setItemAnimator(new DefaultItemAnimator());
vulnerabilityScanRv.setAdapter(vulnerabilityScanAdapter);
// This is the code for pagination of this recyclerView
vulnerabilityScanRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(dy > 0){
// Scrolling Down
if (totalCount > currentPageCount) {
LinearLayoutManager linearLayoutManager =
(LinearLayoutManager) recyclerView.getLayoutManager();
if (linearLayoutManager != null &&
linearLayoutManager.findLastCompletelyVisibleItemPosition() ==
vulnerabilityScanPojoList.size() - 1) {
//bottom of list!
loadMore();
}
} else {
//showSnackForAttributes(true,"No more data avaiable.");
}
}else if(dy < 0){
// Scrolling Up
}
}
});
I have done debugging to know whether the control is going inside onScrolled method while scrolling or not. It goes inside onScrollStateChanged when it reaches to the bottom of the list.

boolean cannot be converted to int horizontalRecyclerView.setVisibility(recyclerView.canScrollVertically(-1));

hello im trying to hide the horizontal recyclerview when vertical recyclerview scroll i have tried to implement this method but there is an error
boolean cannot be converted to int
horizontalRecyclerView.setVisibility(recyclerView.canScrollVertically(-1));
verticalRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
horizontalRecyclerView.setVisibility(recyclerView.canScrollVertically(-1));
}
});
setVisibility is required an integer, you can use View.VISIBLE or View.GONE, but you give an boolean instead, If you want to hide it, change it to
verticalRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
if(recyclerView.canScrollVertically(-1))
horizontalRecyclerView.setVisibility(View.GONE);
else
horizontalRecyclerView.setVisibility(View.VISIBLE);
}
});
setVisibility method doesn't take boolean param, which is returned by canScrollVertically. you have to set one of these params (ints)
visibility int: One of VISIBLE, INVISIBLE, or GONE. Value is VISIBLE, INVISIBLE, or GONE
so
horizontalRecyclerView.setVisibility(recyclerView.canScrollVertically(-1) ?
View.VISIBLE : View.GONE);

Change View height after translation animation?

In my activity I have a BottomNavigationView and a RecyclerView, and what I want to do is to hide the BottomNavigationView when I scroll the view, I'm using this code:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
BottomNavigationView navigationView = requireActivity().findViewById(R.id.bottom_navigation_view);
if (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING && dy > 0){
navigationView.animate()
.translationY(navigationView.getHeight());
}
else if(recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING && dy < 0)
navigationView.animate()
.translationY(0);
}
});
This works fine except for the fact that it still shows the bounds of the view, so after hiding the BottomNavigationView I get an empty rectangle. What is the best way to make the height of the view follow the translation?
I don't see how your "hiding" BottomNavigationView
but if your using
BottomNavigationView.setVisibility(View.INVISIBLE);
which hides the view but keeps its width and height.
it needs to be
BottomNavigationView.setVisibility(View.GONE);
which hides the view and makes the width = 0 and height = 0

How can I identify that RecyclerView's last item is visible on screen?

I have one RecyclerView and I added list of data into the RecyclerView. I wanted to add more data in list, when last RecyclerView item is visible on screen. After that I want to make a web service call and update the RecyclerView data. How can I achieve this?
Any suggestions?
One option would involve editing your LayoutManager. The idea here is to find the position of the last visible item. If that position is equal to the last item of your dataset, then you should trigger a reload.
#Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
final int result = super.scrollVerticallyBy(dy, recycler, state);
if (findLastVisibleItemPosition() == mData.length - 1) {
loadMoreData();
}
return result;
}
#Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
if (findLastVisibleItemPosition() == mData.length - 1) {
loadMoreData();
}
}
Alternatively, you could do this via your adapter's onBindViewHolder method, although this is admittedly a bit of a "hack":
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (position == mData.length - 1) {
// load more data here.
}
/// binding logic
}
3rd option would be to add an OnScrollListener to the RecyclerView. #velval's answer on this page explains this well.
Regardless which option you go for, you should also include code to prevent the data load logic from triggering too many times (e.g., before the previous request to fetch more data completes and returns new data).
If someone stumble across this post this is a quick and simple tutorial on how to do it:
All you need to do is:
recyclerView.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);
int visibleItemCount = lm.getChildCount();
int totalItemCount = lm.getItemCount();
int firstVisibleItemPosition= lm.findFirstVisibleItemPosition();
// Load more if we have reach the end to the recyclerView
if ( (visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0) {
loadMoreItems();
}
}
});
Then your loadMoreItems() should look something like this:
private void loadMoreItems() {
// init offset=0 the frist time and increase the offset + the PAGE_SIZE when loading more items
queryOffset = queryOffset + PAGE_SIZE;
// HERE YOU LOAD the next batch of items
List<Items> newItems = loadItems(queryOffset, PAGE_SIZE);
if (newItems.size() > 0) {
items.addAll(newItems);
adapter.notifyDataSetChanged();
}
}
Seen many of the above answers but my answer is different one and it will work in your cases also. My approach is based on scroll state of recylerview. Maintain below variable "check" and this should update only once when api responds. Put below code in your api response. If you want to handle last item only on every call of api.
final boolean[] check = {true};
recyclerView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (!recyclerView.canScrollVertically(1)) {
// last item of recylerview reached.
if (check[0]) {
//your code for last reached item
scroll_handler.setVisibility(View.GONE);
}
} else {
scroll_handler.setVisibility(View.VISIBLE);
check[0] = false;
}
}
});
If you want to handle your last item every time then do it as below
recyclerView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (!recyclerView.canScrollVertically(1))
// Bottom of recyler view.
arrow_img.setRotation(180);
}
}
});
See also Android - Detect when the last item in a RecyclerView is visible.
private fun isLastItemVisible(): Boolean {
val layoutManager = recycler_view.layoutManager
val position = layoutManager.findLastCompletelyVisibleItemPosition()
return position >= adapter.itemCount - 1
}

Expand Recyclerview item with animation when scrolling up

Iphone App video link
How I can design and develop view which is posted in above video? This is basically the item expansion of recyclerview with animation. I have tried with onItemtouchlistener of recyclerview and also with some custom view with animation, but didn't get the accurate result.
Finally i came accross addonscrolllistener, this give me results but not accurate.
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if(newState == RecyclerView.FOCUS_UP) {
System.out.println("hello, ia m going up");
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0){
TextView tv = (TextView)recyclerView.findViewById(R.id.title);
//tv.setVisibility(View.VISIBLE);
if (tv.getVisibility()==View.VISIBLE){
System.out.println("yes");
}else {
slideToTop(tv);
}
}
}
});
private void slideToTop(View view){
TranslateAnimation animate = new TranslateAnimation(0,0,0,-view.getHeight());
animate.setDuration(1000);
animate.setFillAfter(false);
view.startAnimation(animate);
view.setVisibility(View.VISIBLE);
}
I think your question is too broad - however, here is some psuedocode:
onScrolled() {
View child = getSecondVisibleChild();
int distanceFromTop = child.getTop();
int distanceAtWhichExpandingShouldOccur = 100;
if(distanceFromTop < distanceAtWhichExpandingShouldOccur ) {
child.setHeight(child.getOriginalHeight() + (distanceFromTop - distanceAtWhichExpandingShouldOccur))
}
}
So you'll notice, the second visible child is the one who's height changes. It changed when it's less than distanceAtWhichExpandingShouldOccur from the top of the window. Its height changes to ensure its bottom remains stationary - therefore its height is increasing at the same pace its top is moving.
Once it's no longer the second visible child (aka, its top is 0), it should be scrolled off as normal and the next child should have its height changed when its top is less than distanceAtWhichExpandingShouldOccur.
This library can be a study case for you: https://github.com/florent37/MaterialLeanBack

Categories

Resources