You can register scroll listener to the RecyclerView
, and when the scroll is over (i.e. it's in SCROLL_STATE_IDLE
state); the snapHelper.findSnapView()
shouldn't return a null
value; so you can set its color.
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
// Detect scroll end
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
// Resetting all the loaded items to the default color
int firstVisibleItemPosition =
layoutManager.findFirstVisibleItemPosition();
int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
for (int i = firstVisibleItemPosition; i <= lastVisibleItemPosition; i++) {
RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(i);
// Rest to the default color of other loaded items
holder.itemView.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.defaultColor, null));
}
// Changing the background of the snaphelper centered item
View centerView = snapHelper.findSnapView(layoutManager);
if (centerView != null)
centerView.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.centerColor, null));
}
}
});
Kotlin:
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
// Detect scroll end
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
val firstVisibleItemPosition =
layoutManager.findFirstVisibleItemPosition()
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
for (i in firstVisibleItemPosition..lastVisibleItemPosition) {
val holder =
recyclerView.findViewHolderForAdapterPosition(i)
// Resetting all the loaded items to the default color
holder!!.itemView!!.setBackgroundColor(ResourcesCompat.getColor(resources, R.color.defaultColor, null))
}
// Changing the background of the snaphelper centered item
val centerView: View? = snapHelper.findSnapView(layoutManager)
centerView.setBackgroundColor(ResourcesCompat.getColor(resources, R.color.centerColor, null))
}
}
})
UPDATE:
There is a better approach than iterating over all the RV loaded items, to reset to the default color; by just saving the previous centeredView into a local field, and update its color instead of updating the entire loaded items:
View previousCenteredView;
final LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
// Detect scroll end
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
// Changing the background of the snaphelper centered item
View centerView = snapHelper.findSnapView(layoutManager);
previousCenteredView = centerView;
if (centerView != null)
centerView.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.centerColor, null));
} else if (previousCenteredView != null){
// Resetting previous centered view to the default color
previousCenteredView.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.defaultColor, null));
previousCenteredView = null;
}
}
});
Kotlin:
var previousCenteredView: View? = null
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
// Detect scroll end
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
// Changing the background of the snaphelper centered item
val centerView: View? = snapHelper.findSnapView(layoutManager)
previousCenteredView = centerView
centerView.setBackgroundColor(ResourcesCompat.getColor(resources, R.color.centerColor, null))
} else if (previousCenteredView != null){
// Resetting previous centered view to the default color
previousCenteredView.setBackgroundColor(ResourcesCompat.getColor(resources, R.color.defaultColor, null))
previousCenteredView = null
}
}
})