I got a RecyclerView whose element contains a EditText widget.
1.currently focusing on the second EditText,the first EditText is partly showed on the screen.
the first EditText is partly showed
2.when click the first EditText, it got focus, then RecyclerView would automatically scroll down to fully show the first EditText.
RecyclerView automatically scroll down when first EditText got focused
This is great,but what I want is RecyclerView should not automatically scroll.
Any solution?
thanks!
Actually, there is a scroll state of RecycleView that you can control like this;
Create your own LayoutManager and override the scrollHorizontallyBylike this.
#Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
int nScroll = 0;
// Do not let auto scroll
if (recyclerView.getScrollState() != RecyclerView.SCROLL_STATE_SETTLING){
nScroll = super.scrollHorizontallyBy(dx, recycler, state);
}
}
So, what is the SCROLL_STATE_SETTLING?
The RecyclerView is currently animating to a final position while not
under outside control.
I finally fixed it by disable the RecyclerView from scrolling except it receive a touch event.
first, I custom a LayoutManager:
#Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
if(!horizontal) {
return 0;
}
#Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
if(!vertical) {
return 0;
}
when receive click event :
I set horizontal and vertical to false ,these cause RecyclerView cannot scroll any more!
and I subClass The recyclerView and Override onTouchEvent:
public boolean onTouchEvent(MotionEvent e) {
//we enable scrollHorizontallyBy and scrollVerticallyBy only in Touch Event, set layoutManager vertical and horizontal to true
......
return super.onTouchEvent(e);
}
so MyRecyclerView cannot scroll when click to find that the focus child is an EditText. But it can scroll when Receive Touch Event!
Related
I have a GridLayout RecyclerView with a PageSnapHelper attached that essentially acts like a Vertical Linear RecyclerView (I inherited the code, not sure why this was done). The goal is to highlight the item currently centered in the view. Scrolling is done from code driven by two menu items to simulate going forward and backward from a remote. Scrolling of the view works fine. The issue seems to be that when I listen for the end of scrolling event there is animation going on which messes up my code to draw the highlight around the item. Here's the code I use to scroll the view based on the menu item:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//Get which arrow was pressed
int id = item.getItemId();
//Get count of items
int itemCount = recyclerView.getAdapter().getItemCount();
//Condition to moving down the list
if (id == R.id.next) {
//Make sure we're within bounds of the of the view from the top
if(count>=itemCount-1) {
return super.onOptionsItemSelected(item);
}
//Increment to count to next ViewHolder
count++;
//Condition for moving up list
} else if (id == R.id.prev) {
//Make sure we're within bounds
if(count == 0){
return super.onOptionsItemSelected(item);
}
//Decremennt to previous ViewHolder
count--;
}
//Scroll the RecyclerView to the position we want
layoutManager.setIsNext(id == R.id.next);
recyclerView.smoothScrollToPosition(count);
//If the item is already in view, then no scroll event is necessary and we can access the ViewHolder
HighlightViewHolder(count);
//In the event that the ViewHolder is off-screen listen for the end of the scrolling event to ensure the ViewHolder
//is created and in correct position on the screen
RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
//Add a listener to that looks out for when the scrolling is complete
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Log.i("ScrollListener", "Scrolling has ended");
HighlightViewHolder(count);
recyclerView.removeOnScrollListener(this);
}
};
recyclerView.addOnScrollListener(scrollListener);
return super.onOptionsItemSelected(item);
When the app first begins and I the forward button, the first item is highlighted just fine:
On the next selection, which engages a scrolling event is where I have an issue:
What I would expect to happen is that when the scrolling event has ended, the item is in its centered position. Based on what I'm seeing I think there's some animation event that's still happening that I should be looking for the completion of. My highlighting code relies on the view in question to be in its expected location. I'm new to android and my searches for RecyclerView animations brought me to ItemAnimator. But reading the docs I'm not sure if this is what I'm looking for. Any ideas?
I couldn't find any events related to what I was looking for so I went ahead and used a Handler to wait an arbitrary amount of time before drawing the highlight. I updated the Listener as so:
//Add a listener to that looks out for when the scrolling is complete
#Override
public void onScrolled(final RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Handler handler = new Handler();
Runnable task = new Runnable() {
#Override
public void run() {
HighlightViewHolder(count);
}
};
handler.postDelayed(task, 500);
recyclerView.removeOnScrollListener(this);
}
I have recycler view with adapter. Need deny user to scroll to item with 0 index, when it was scrolled. F.e user scrolls to 5 item and when scrolls back first visible will be item with index 1.
Will be glad any ideas how to implement this feature.
Use smoothScrollToIndex(1) inside addOnScrollListener of the recycler view.
Keep a if check with !recyclerView.canScrollVertically(-1) there if it succeeded then use like :
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(!recyclerView.canScrollVertically(-1))
{
mRecyclerView.smoothScrollToIndex(1);
}
}});
So if you have a RecyclerView that extends to the end of the screen and use a FloatingActionButton or the third-party FloatingActionMenu, then there is a slight problem with cover-up: If you scroll to the end of the list, the floating button covers up part of the row and there is no way to see or get to what's underneath it.
Is there a way Android allows you to:
Detect if your list has a sufficient number of items in it, i.e. if there is a row at the bottom of the screen visible.
and
Slide the buttons out of the way if you scroll down to the very end, and then slide them back in if you start scrolling back up?
Edit: Or, alternatively, add dynamic padding to the end of the RecyclerView that only shows up if you've scrolled all the way down?
The common pattern to solve the problem of covering up parts of UI is to hide FAB as soon as the user starts scrolling down ... You can achieve this by this code fragment (used with RecyclerView):
fDemandsRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(dy > 0 ){
if(fFab.isShown()) fFab.hide();
} else {
if(!fFab.isShown()) fFab.show();
}
}
});
If you insist on hiding it on the very end and you are using RecyclerView with LinearLayoutManager, you can check method findLastCompletelyVisibleItemPosition() on the LayoutManager object during the OnScrollListener callback ...
Of course it is possible. The solution was posted here.
The main idea behind it is that FloatingActionButton.Behavior is overriden and changed, so that it reacts to RecyclerView and CoordinatorLayout scrolling.
However, in your case RecyclerViewScrollListener must be different. Here is the implementation:
private class RecyclerViewScrollListener extends RecyclerView.OnScrollListener {
FloatingActionButton mChild;
public RecyclerViewScrollListener(FloatingActionButton child) {
this.mChild = child;
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE && recyclerView.canScrollVertically(Integer.MAX_VALUE)) {
mChild.show();
} else {
mChild.hide();
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!recyclerView.canScrollVertically(Integer.MAX_VALUE)) {
mChild.hide();
}
}
}
Edit:
When filling RecyclerView with data, invoke such function on it in order to disable or enable scrolling:
private void changeCoordinatorLayoutScrollPossibility(final RecyclerView recyclerView) {
new Handler().post(new Runnable() {
#Override
public void run() {
if (recyclerView.getMeasuredHeight() < alertsRecyclerView.computeVerticalScrollRange()) {
recyclerView.setNestedScrollingEnabled(true);
} else {
recyclerView.setNestedScrollingEnabled(false);
}
}
});
}
I want to add back to top button in my app. I use recyclerview for displaying items. I added button and when I click on it, view is going to top, but my goal is to show this button only if application is scrolled down or up, and my first item is not visible (I hope thats clear explanation). I tried with
LayoutManager.findFirstCompletelyVisibleItemPosition();
and other methods for LayoutManager but without acceptable effects.
My solution is showed below. I add OnScrollListener on my RecyclerView, and when view is scrolled I check if the first item is visible and I set visibility of my button.
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) {
int visibility = (MyLayoutManager.findFirstCompletelyVisibleItemPosition() != 0) ? View.VISIBLE : View.GONE;
btn.setVisibility(visibility);
}
});
I have an activity which contain horizontal RecyclerView which display icons of movies retrieved from server
When the user scroll the recycler view to its end - making the last item of the recycler view visible i want to show "More" button to allow the loading of additional icons
How can i get indication when the user scroll to the end of the recycler view?
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition() == LAST_POSITION) {
// code here
}
}
});