I have a horizontal center zoom image list in which i want to display play icon and text for center scale view only
I am able to scale center Imageview but getting position problem while managing it through model.
But sometimes it displays and sometimes not. but i am getting position of center imageview perfectly in class onScrollStateChanged method.
Following class i have used for layout manager and scrollview in my activity
mAdapter = new ContactScreenAdapter(ContactScreenActivity.this, mContext, listFavoriteContact);
scrollZoomLayoutManager = new ScrollZoomLayoutManager(this, Dp2px(25));
recyclerFavoriteList.setLayoutManager(scrollZoomLayoutManager);
recyclerFavoriteList.setAdapter(mAdapter);
recyclerFavoriteList.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (!(layoutManager instanceof CircleLayoutManager) && !(layoutManager instanceof ScrollZoomLayoutManager)) {
mAutoSet = true;
return;
}
if (!mAutoSet) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
final int dx;
if (layoutManager instanceof CircleLayoutManager) {
dx = ((CircleLayoutManager) layoutManager).getOffsetCenterView();
} else {
dx = ((ScrollZoomLayoutManager) layoutManager).getOffsetCenterView();
}
recyclerView.smoothScrollBy(dx, 0);
Log.d(TAG,"#### dx : "+ ((ScrollZoomLayoutManager) layoutManager).getCurrentPosition());
mAdapter.setSelecteditem(((ScrollZoomLayoutManager) layoutManager).getCurrentPosition());
}
mAutoSet = true;
}
if (newState == RecyclerView.SCROLL_STATE_DRAGGING || newState == RecyclerView.SCROLL_STATE_SETTLING) {
mAutoSet = false;
}
}
});
and i am updating my model in adapter method
public void setSelecteditem(int selecteditem) {
this.selectedItem = selecteditem;
for (int i=0;i<moviesList.size();i++){
moviesList.get(i).setCenterSelected(false);
Log.d("CSA","## moviesList.get(i).isCenterSelected() : "+ moviesList.get(i).isCenterSelected());
}
moviesList.get(selecteditem).setCenterSelected(true);
notifyDataSetChanged();
}
Thank you for help in advance.
Related
I have a horizontal list which it's using a recycler view and a PagerSnapHelper to simulate a view pager.
I want to swipe scroll one element at the time, but the problem is that i can scroll to the last element with one swipe.
So my problem is that I want to stop the swipe after one element swiped so if someone has any advice will be appreciated.
You could try adding a logic by checking the current position as mentioned in below post:
SnapHelper Item Position
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if(newState == RecyclerView.SCROLL_STATE_IDLE) {
View centerView = snapHelper.findSnapView(mLayoutManager);
int pos = mLayoutManager.getPosition(centerView);
Log.e("Snapped Item Position:",""+pos);
}
}
or Something like this:
LinearSnapHelper snapHelper = new LinearSnapHelper() {
#Override
public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
View centerView = findSnapView(layoutManager);
if (centerView == null)
return RecyclerView.NO_POSITION;
int position = layoutManager.getPosition(centerView);
int targetPosition = -1;
if (layoutManager.canScrollHorizontally()) {
if (velocityX < 0) {
targetPosition = position - 1;
} else {
targetPosition = position + 1;
}
}
if (layoutManager.canScrollVertically()) {
if (velocityY < 0) {
targetPosition = position - 1;
} else {
targetPosition = position + 1;
}
}
final int firstItem = 0;
final int lastItem = layoutManager.getItemCount() - 1;
targetPosition = Math.min(lastItem, Math.max(targetPosition, firstItem));
return targetPosition;
}
};
snapHelper.attachToRecyclerView(recyclerView);
Ref: https://ogeek.cn/qa/?qa=441913/&show=441914
I have a recycleView that I need to observe when the last item is reached but I have notice the it always indicate that I reached the last item even if I haven't scrolled yet.
My code for setting up the recycler:
newsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
newsRecyclerView.setFocusable(false);
newsRecyclerView.setNestedScrollingEnabled(false);
newsAdapter = new NewsAdapter(getContext(), newsDetails, categoryNumber);
newsRecyclerView.setAdapter(newsAdapter);
layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
My xml code is:
<android.support.v7.widget.RecyclerView
android:id="#+id/news_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/news_top_stories_title_text_view" />
This is my code that I put in my Util, and use anywhere.
Util.setRecyclerViewLastPositionListner(rv, linearLayoutManager , new UtilitiesV2.OnLastPositionReached() {
#Override
public void onReached() {
// last position reached
}
});
Put this in Util.
private boolean userScrolled = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;
public interface OnLastPositionReached {
void onReached();
}
public void setRecyclerViewLastPositionListner(RecyclerView rvBooksMockTest, final LinearLayoutManager mLayoutManager, final OnLastPositionReached onLastPositionReached) {
rvBooksMockTest.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
userScrolled = true;
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// Here get the child count, item count and visibleitems
// from layout manager
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
// Now check if userScrolled is true and also check if
// the item is end then update recycler view and set
// userScrolled to false
if (userScrolled && (visibleItemCount + pastVisiblesItems) == totalItemCount) {
userScrolled = false;
if (onLastPositionReached != null) onLastPositionReached.onReached();
}
}
});
}
Update
According to your requirement, here is NestedScrollView bottom reach listener.
nestedScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (nestedScrollView != null) {
if (nestedScrollView.getChildAt(0).getBottom() <= (nestedScrollView.getHeight() + nestedScrollView.getScrollY())) {
//scroll view is at bottom
} else {
//scroll view is not at bottom
}
}
}
});
Thanks to Khemraj who give the tip for solution
because I have a recyclerview inside NestedScrollView and coordinator layout as parent for them
I have solved my problem like this:
public Disposable observeNestedScroll(LoadMoreListener listener) {
return RxNestedScrollView.scrollChangeEvents(nestedScrollView)
.subscribe(
viewScrollChangeEvent -> {
NestedScrollView nestedScrollView =(NestedScrollView) viewScrollChangeEvent.view();
if(nestedScrollView.getChildAt(nestedScrollView.getChildCount() - 1) != null) {
if ((viewScrollChangeEvent.scrollY() >= (nestedScrollView.getChildAt(nestedScrollView.getChildCount() - 1).getMeasuredHeight() - nestedScrollView.getMeasuredHeight())) &&
viewScrollChangeEvent.scrollY() > viewScrollChangeEvent.oldScrollY()) {
listener.onLoadMore();
}
}
});
}
I've seen to many responses for this question and I stand that all of them don't give accurate behavior as an outcome. However if you follow this approach I'm positive you'll get the best behavior.
rvCategories is your RecyclerView
categoriesList is the list passed to your adapter
binding.rvCategories.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
val position = (recyclerView.layoutManager as LinearLayoutManager).findLastCompletelyVisibleItemPosition()
if (position + 1 == categoriesList.size) {
// END OF RECYCLERVIEW IS REACHED
} else {
// END OF RECYCLERVIEW IS NOT REACHED
}
}
})
I've attached a PagerSnapHelper to a RecyclerView with a Horizontal LinearLayoutManager using below code.
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(myRecyclerView);
However, when I perform scroll, snapping happens only in one direction. i.e. it snaps to next item on a right swipe but doesn't snap to previous item on a left swipe.
Is this the default behavior? Could I override this to enable snapping to previous item as well on a left swipe?
Any pointers here would be of great help. Thanks!
SnapHelper sometimes has issues in some cases, like item count etc.
You can use this GravitySnapHelper class which is extended from LinearSnapHelper.
import android.view.Gravity;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.LinearSnapHelper;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.RecyclerView;
public class GravitySnapHelper extends LinearSnapHelper {
private OrientationHelper mVerticalHelper;
private OrientationHelper mHorizontalHelper;
private int mGravity;
private boolean mIsRtlHorizontal;
private boolean mSnapLastItemEnabled;
SnapListener mSnapListener;
boolean mSnapping;
private RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_SETTLING) {
mSnapping = false;
}
if (newState == RecyclerView.SCROLL_STATE_IDLE && mSnapping && mSnapListener != null) {
int position = getSnappedPosition(recyclerView);
if (position != RecyclerView.NO_POSITION) {
mSnapListener.onSnap(position);
}
mSnapping = false;
}
}
};
public GravitySnapHelper(int gravity) {
this(gravity, false, null);
}
public GravitySnapHelper(int gravity, boolean enableSnapLastItem) {
this(gravity, enableSnapLastItem, null);
}
public GravitySnapHelper(int gravity, boolean enableSnapLastItem, SnapListener snapListener) {
if (gravity != Gravity.START && gravity != Gravity.END
&& gravity != Gravity.BOTTOM && gravity != Gravity.TOP) {
throw new IllegalArgumentException("Invalid gravity value. Use START " +
"| END | BOTTOM | TOP constants");
}
mSnapListener = snapListener;
mGravity = gravity;
mSnapLastItemEnabled = enableSnapLastItem;
}
#Override
public void attachToRecyclerView(#Nullable RecyclerView recyclerView)
throws IllegalStateException {
if (recyclerView != null) {
if (mGravity == Gravity.START || mGravity == Gravity.END) {
mIsRtlHorizontal
= false;
}
if (mSnapListener != null) {
recyclerView.addOnScrollListener(mScrollListener);
}
}
super.attachToRecyclerView(recyclerView);
}
#Override
public int[] calculateDistanceToFinalSnap(#NonNull RecyclerView.LayoutManager layoutManager,
#NonNull View targetView) {
int[] out = new int[2];
if (layoutManager.canScrollHorizontally()) {
if (mGravity == Gravity.START) {
out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager), false);
} else { // END
out[0] = distanceToEnd(targetView, getHorizontalHelper(layoutManager), false);
}
} else {
out[0] = 0;
}
if (layoutManager.canScrollVertically()) {
if (mGravity == Gravity.TOP) {
out[1] = distanceToStart(targetView, getVerticalHelper(layoutManager), false);
} else { // BOTTOM
out[1] = distanceToEnd(targetView, getVerticalHelper(layoutManager), false);
}
} else {
out[1] = 0;
}
return out;
}
#Override
public View findSnapView(RecyclerView.LayoutManager layoutManager) {
View snapView = null;
if (layoutManager instanceof LinearLayoutManager) {
switch (mGravity) {
case Gravity.START:
snapView = findStartView(layoutManager, getHorizontalHelper(layoutManager));
break;
case Gravity.END:
snapView = findEndView(layoutManager, getHorizontalHelper(layoutManager));
break;
case Gravity.TOP:
snapView = findStartView(layoutManager, getVerticalHelper(layoutManager));
break;
case Gravity.BOTTOM:
snapView = findEndView(layoutManager, getVerticalHelper(layoutManager));
break;
}
}
mSnapping = snapView != null;
return snapView;
}
/**
* Enable snapping of the last item that's snappable.
* The default value is false, because you can't see the last item completely
* if this is enabled.
*
* #param snap true if you want to enable snapping of the last snappable item
*/
public void enableLastItemSnap(boolean snap) {
mSnapLastItemEnabled = snap;
}
private int distanceToStart(View targetView, OrientationHelper helper, boolean fromEnd) {
if (mIsRtlHorizontal && !fromEnd) {
return distanceToEnd(targetView, helper, true);
}
return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
}
private int distanceToEnd(View targetView, OrientationHelper helper, boolean fromStart) {
if (mIsRtlHorizontal && !fromStart) {
return distanceToStart(targetView, helper, true);
}
return helper.getDecoratedEnd(targetView) - helper.getEndAfterPadding();
}
/**
* Returns the first view that we should snap to.
*
* #param layoutManager the recyclerview's layout manager
* #param helper orientation helper to calculate view sizes
* #return the first view in the LayoutManager to snap to
*/
private View findStartView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
// We should return the child if it's visible width
// is greater than 0.5 of it's total width.
// In a RTL configuration, we need to check the start point and in LTR the end point
if (mIsRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
}
// If we're at the end of the list, we shouldn't snap
// to avoid having the last item not completely visible.
boolean endOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (mSnapLastItemEnabled && endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
// If the child wasn't returned, we need to return
// the next view close to the start.
return layoutManager.findViewByPosition(firstChild + 1);
}
}
return null;
}
private View findEndView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (mIsRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
}
// If we're at the start of the list, we shouldn't snap
// to avoid having the first item not completely visible.
boolean startOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition() == 0;
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (mSnapLastItemEnabled && startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
// If the child wasn't returned, we need to return the previous view
return layoutManager.findViewByPosition(lastChild - 1);
}
}
return null;
}
int getSnappedPosition(RecyclerView recyclerView) {
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
if (mGravity == Gravity.START || mGravity == Gravity.TOP) {
return ((LinearLayoutManager) layoutManager).findFirstCompletelyVisibleItemPosition();
} else if (mGravity == Gravity.END || mGravity == Gravity.BOTTOM) {
return ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition();
}
}
return RecyclerView.NO_POSITION;
}
private OrientationHelper getVerticalHelper(RecyclerView.LayoutManager layoutManager) {
if (mVerticalHelper == null) {
mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
}
return mVerticalHelper;
}
private OrientationHelper getHorizontalHelper(RecyclerView.LayoutManager layoutManager) {
if (mHorizontalHelper == null) {
mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
}
return mHorizontalHelper;
}
public interface SnapListener {
void onSnap(int position);
}
}
Usage is simple:
SnapHelper snapHelper = new GravitySnapHelper(Gravity.START);
snapHelper.attachToRecyclerView(recyclerView);
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 wnat to show and hide the Android ActionBar when the user scrolls the screen. I found some examples, like this question in SO. But the code showed in this question and its answer makes the action hides after the list have scrolled some pixels, and I want to make this scroll like the Inbox App by Google, that is the action bar is pulled by the Layout according to the user scroll the screen up or down, in other words, I want to show/hide the action bar at the same time the user scroll down/up.
Someone face a problema like this? Some idea?
super simple:
ditch the ListView. ListView is the past. Use RecyclerView instead.
add a RecyclerView.OnScrollListener to it, to get pixel-by-pixel scroll.
use a Toolbar on your activity layout. So you can control the position of it.
call setTranslationY(val) on your Toolbar to "scroll" it with the RecyclerView.
a few links with the docs for the mentioned classes:
http://android-developers.blogspot.de/2014/10/appcompat-v21-material-design-for-pre.html
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.OnScrollListener.html
http://developer.android.com/reference/android/widget/Toolbar.html
https://developer.android.com/reference/android/view/View.html#setTranslationY(float)
I created a solution based answer of #Budius and this link
First add this class
public class HidingRecyclerViewScrollListener extends RecyclerView.OnScrollListener {
private final int UP = 0;
private final int DOWN = 1;
private final int margin = 5;
private View mView;
RecyclerView.LayoutManager mLayoutManager;
private float currentPoint = 0;
private int lastDirection = 1;
public HidingRecyclerViewScrollListener(View view, LinearLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
mView = view;
}
public HidingRecyclerViewScrollListener(View view, GridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
mView = view;
}
public HidingRecyclerViewScrollListener(View view, StaggeredGridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
mView = view;
}
public int getFirstVisibleItem(int[] firstVisibleItemPositions) {
int minSize = 0;
for (int i = 0; i < firstVisibleItemPositions.length; i++) {
if (i == 0) {
minSize = firstVisibleItemPositions[i];
} else if (firstVisibleItemPositions[i] < minSize) {
minSize = firstVisibleItemPositions[i];
}
}
return minSize;
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
float nextPoint = currentPoint + dy;
if (nextPoint < 0) {
nextPoint = 0;
}
if (nextPoint > viewSize()) {
nextPoint = viewSize();
}
lastDirection = nextPoint >= currentPoint ? UP : DOWN;
currentPoint = nextPoint;
mView.setTranslationY(-currentPoint);
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (lastDirection == UP) {
if (getFirstVisibleItem() > 0) {
currentPoint = viewSize();
}
}
if (lastDirection == DOWN) {
//Volta para origem
currentPoint = 0;
}
mView.animate().translationY(-currentPoint);
}
}
private int getFirstVisibleItem() {
int firstVisibleItem = 0;
if (mLayoutManager instanceof StaggeredGridLayoutManager) {
int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findFirstVisibleItemPositions(null);
firstVisibleItem = getFirstVisibleItem(lastVisibleItemPositions);
} else if (mLayoutManager instanceof LinearLayoutManager) {
firstVisibleItem = ((LinearLayoutManager) mLayoutManager).findFirstVisibleItemPosition();
} else if (mLayoutManager instanceof GridLayoutManager) {
firstVisibleItem = ((GridLayoutManager) mLayoutManager).findFirstVisibleItemPosition();
}
return firstVisibleItem;
}
private int viewSize() {
return mView.getHeight() + margin;
}
}
Is simple to use, only add using addOnScrollListener of your recyclerView
recyclerView = (RecyclerView) view.findViewById(R.id.mRecyclerView );
layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.addOnScrollListener(new HidingRecyclerViewScrollListener(mView, layoutManager));
mView is the view you want to control
You can user this class with LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager (but i never test with GridLayoutManager)
In RecyclerView use the code below to the list does not stay below the object you want to control, this code is simpler and better to test, but use a Hearder in RecyclerView as is said in the link above has a better result.
android:clipToPadding="false"
android:paddingTop="#dimen/outher_view_dimem"
If you using SwipeRefreshLayout use code below to show ProgressBar
swipeRefreshLayout.setProgressViewOffset(true, 0, mViewHeight + actionBarHeight);