I'm trying to scroll recycler view item to top of screen when user clicks on an item.
My layout is set as following
- <FrameLayout>
-- <ScrollView>
--- <LinearLayout /> // static content
--- <RecyclerView /> // dynamic content
--- <LinearLayout /> // static content
-- </ScrollView>
-- </FrameLayout>
What I want to achieve is when i click on an item of recyclerview. It should scroll up to top of the screen.
I have tried following so far but no luck.
->
// use recycler view's layout manager to scroll.
recyclerView.layoutManager.scrollToPositionWithOffset(position)
->
// use smooth scroll to scroll
recyclerView.smoothScrollToPosition(ItemPos)
->
// use main scroll view to scroll on the screen. This kind of works but does not move item to top of the page.
val y = recyclerView.y + recyclerView.getChildAt(position).y
activity.binding.mainScrollview?.smoothScrollTo(0, y.toInt())
Any help is appreciated. Thank you
Looks like in your case you don't have enough items.
You can't get recyclerView scroll lower than the last Item So it's either you make your own implementation of recyclerView by extending it,get add scroll amounts and when got to the last item you'll add up the translationY of the recyclerView.
Or you can add a few dummy Items.So they can be View with width and height of your normal Items.That should do it.
Have you tried layoutManager's scrollToPositionWithOffset function:
thirdItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LinearLayoutManager layoutManager = (LinearLayoutManager) mRecyclerView
.getLayoutManager();
layoutManager.scrollToPositionWithOffset(0, 0);
}
});
Related
Scroll in Recyclerview list of card view default when scroll faster than scroll more than one card.I need only shows next of current card when scrolling even user how much scroll amount is applied in android.I Googled but not getting a solution. thanks for helping
my code contained MyRecyclerView and LinearLayoutManager looks following lines
MyRecyclerView = (RecyclerView) view.findViewById(R.id.cardView);
MyRecyclerView.setHasFixedSize(true);
LinearLayoutManager MyLayoutManager = new LinearLayoutManager(getActivity());
MyLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
if (listitems.size() > 0 & MyRecyclerView != null) {
MyRecyclerView.setAdapter(new MyAdapter(listitems));
}
MyRecyclerView.setLayoutManager(MyLayoutManager);
1. You should use smoothScrollToPosition(int position)
Starts a smooth scroll to an adapter position.
recyclerview.smoothScrollToPosition(position);
2. Use scrollToPosition()
void scrollToPosition (int position)
Convenience method to scroll to a certain position. RecyclerView does not implement scrolling logic, rather forwards the call to
RecyclerView.scrollToPosition(postion)
3. rv.getLayoutManager().scrollToPosition(youPositionInTheAdapter).
4. scrollToPositionWithOffset()
void scrollToPositionWithOffset (int position,int offset)
Scroll to the specified adapter position with the given offset from resolved layout start. Resolved layout start depends on getReverseLayout(), getLayoutDirection(android.view.View) and getStackFromEnd().
linearLayoutManager.scrollToPositionWithOffset(1, 10);
You can achieve this by using object of linearLayoutManager.Use this line to move the selected item to show on top of recycler screen.
linearLayoutManager.scrollToPositionWithOffset(YOUR_ITEM_POSITION,OFFSET_YOU_WANT);
For more information on how to use scrollToPositionWithOffset check this link .
https://developer.android.com/reference/android/support/v7/widget/LinearLayoutManager.html#scrollToPositionWithOffset(int,%20int)
I've created an EditText, a Button and a RecyclerView (composed of 1 TextView and 1 ImageView children) to add TextViews that looks like this . In the EditText at the top, users may enter text and hit the + button. This adds their text to a List(String) which is used to update the RecyclerView. The user may hit the x at the right to delete an entry from the RecyclerView. Here is an image of the overall fragment layout
The issue, which you can see in the image, is that after a few submissions, the RecyclerView stops expanding and remains at a fixed size (notice the small blip in the bottom right). You may scroll in the RecyclerView to view the items, items are still added to it, but it will not expand to the full size (the one in the image has 20+ items). If I delete an item, the height grows for some reason but it still won't display all elements and it shrinks back when I add a new item.
Things I've tried
Here is the RecyclerView code. The heirarchy goes
<LinearLayout>
<ScrollView>
<LinearLayout>
<RecyclerView />
</LinearLayout>
</ScrollView>
</LinearLayout>
All heights and widths are set to match parent, all orientations to vertical:
<android.support.v7.widget.RecyclerView
android:id="#+id/ingredientsRecyclerView"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
>
The code to add an entry to the RecyclerView (outside of the adapter):
ingredientsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (ingredientsText.getText().toString().length() > 0) {
mIngredients.add(ingredientsText.getText().toString());
ingredientsText.setText("");
mAdapter.notifyDataSetChanged();
mRecyclerView.setBackgroundResource(R.drawable.rounded_edittext);
}
}
});
And, finally, the code to delete an entry from the RecyclerView (inside the RV adapter):
cancelImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mIngredients.remove(getAdapterPosition());
mAdapter.notifyItemRemoved(getAdapterPosition());
mAdapter.notifyItemRangeChanged(getAdapterPosition(), mIngredients.size());
if(mAdapter.getItemCount() == 0)
mRecyclerView.setBackgroundResource(0);
}
});
Any assistance would be GREATLY appreciated, as I can't figure this out for the life of me!
use NestedScrollView instead of ScrollView and setNestedScrollEnabled(false) on the RecyclerView
k0sh is absolutely right. Just to add, use the full class name, which is android.support.v4.widget.NestedScrollView (make sure you have the v4 support library in your build.gradle file), or Android won't find NestedScrollView class. Source: Error inflating class - NestedScrollView - class not found
Use NestedScrollView instead of ScrollView and on your NestedScrollView set
isNestedScrollingEnabled = false
I am trying to programmatically scroll to a position in my RecyclerView, this is what I've tried until now nothing worked in my case:
musicList.getLayoutManager().smoothScrollToPosition(musicList, null, position);
musicList.scrollToPosition(position);
mLayoutManager.scrollToPosition(position);
musicList.getLayoutManager().scrollToPosition(position);
Is there something I missed?
I have a LinearLayoutManager mLayoutManager; defined and set it to RecyclerView as this:
mLayoutManager = new LinearLayoutManager(this);
musicList.setLayoutManager(mLayoutManager);
RecyclerView XML:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/musicList"
android:scrollbars="vertical"
android:scrollbarThumbVertical="#drawable/custom_scrollbar_vertical"/>
Did you try with LinearLayoutManager method scrollToPositionWithOffset
//position 2 and second param is offset 20
mLayoutManager.scrollToPositionWithOffset(2, 20);
this works for me. Hope to work and for you !
Addendum:
The proposed scroll functions do not work correctly in a scenario with a collapsing toolbar while the toolbar is expanded.
It seems that the recycler view has a fixed height, and while the toolbar is expanded, the recycler is moved down, partially out of the screen. As a consequence also the results of the functions findLast[Completely]VisibleItemPosition() are too high. Example: The last visible item is told to be #9, but in fact item #7 is the last one that is really on screen.
I finally chose a workaround like this:
if (newPos > 2 /* or other number > 0 */)
{
AppBarLayout l = findViewById(R.id.appbar);
if (l != null)
{
l.setExpanded(false, true); // collapse the bar, with animation
}
}
mRecyclerView.scrollToPosition(newPos);
Any hints for a better solution are appreciated!
I'm creating an EPG like view for which I have multiple horizontal RecyclerViews (as tv programs) encapsulated inside a LinearLayout. When I scroll one of the RecyclerView, I want the rest of the views to be scrolled together.
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
layoutContent.setWeightSum(epg.getChannels().size());
//prepare recycler views and add into layoutContent based on epg channels
for(EPG.Channel ch : epg.getChannels()){
AppLog.error(TAG, "Creating RecyclerView for: " + ch.getDisplayName());
//create new recycler view
final RecyclerView rv = new RecyclerView(layoutContent.getContext());
lstRecyclerViews.add(rv);
//set layout manager
rv.setLayoutManager(new LinearLayoutManager(layoutContent.getContext(), LinearLayoutManager.HORIZONTAL, false));
//create adapter
rv.setAdapter(new MyAdapter(ch.getPrograms()));
rv.setItemAnimator(new DefaultItemAnimator());
//add into parent layout
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
lp.weight = 1;
layoutContent.addView(rv, lp);
}
}
I've tried adding a scroll listener to my views but I'm confused with RecyclerView.OnScrollListener's onScrolled method as i can't figure out how to scroll other views.
Any help/suggestion would be helpful.
HorizontelScrollView
{
Linear Layout
{
Vertical list of horizontal recycler views ,
override horizontal recycler view's LayoutManager's
canScroolhorizontally() method to return false ,so that they
all scroll together according to the Grand Parent ScrollView.
}
Our main focus is to scroll that vertical list of horizontal recycler views horizontally ,
first i tried to keep all of them on a horizontal scroll view ,but that is something ,which the android system clearly rejects ,
so i kept one linear layout (in my case vertically oriented ) as a mediator.
so the epg grid now can scroll in vertically as they are inside one vertical recycler view as well as in horizontally because of the Horizontal scroll view.
and we should not allow horizontal list to scroll independentaly ,so I extended layoutmanager and disallow horizontal scrolling ,now they only scroll under grandParent scroll .
You need to always re-calculate position of current items in horizontal recycler views(next h.r.v.)
After scrolling in one h.r.v. re-calculate positions of others based on small amount of scroll movement occured in touched h.r.v.
Then override onViewAttachedToWindow in adapter and use method scrollToPositionWithOffset from LinearLayoutManager of particularly h.r.v to set it to right position.
Also when calculating movement dx, don't forget to disable onScrolled method when finger is down to avoid multiple handling of the same event.
FlexboxLayout (made by Google) lets you make something like this with a RecyclerView and a FlexboxLayoutManager. Since its version 3.0(June 28th 2017) you can drag horizontally through it.
For your example use it like this:
FlexboxLayoutManager layoutManager = new FlexboxLayoutManager(getActivity());
layoutManager.setFlexDirection(FlexDirection.ROW);
layoutManager.setFlexWrap(FlexWrap.WRAP);
recyclerView.setLayoutManager(layoutManager);
And don't forget to set the width of your RecyclerView to a bigger number than the screen size, in order to scroll, do not use match_parent:
<android.support.v7.widget.RecyclerView
android:layout_width="3600dp"
android:layout_height="match_parent"/>
Note: the ViewHolders are recycled by rows, not by columns, so be careful if you have too heavy items on a very long RecyclerView
You need to add textviews in horizontal rows. The length of the textview depends on the duration of the program. I have hosted a sample project on Github. Feel free to clone. https://github.com/xardox69/android_EPG
I've got a RecyclerView using the default Linear Layout Manager.
llm = new LinearLayoutManager(getActivity().getApplicationContext());
llm.setOrientation(LinearLayoutManager.VERTICAL);
ItemListView = (RecyclerView) rootView.findViewById(R.id.Itemlist);
ItemListView.setLayoutManager(llm);
final float scale = getActivity().getBaseContext().getResources().getDisplayMetrics().density;
I am trying to change the height of that one item view to display additional ui elements when the label is clicked.
I tried this with no success
vh.itemView.setMinimumHeight((int)(375 *(scale/160)));
Can I even change the item height? would I need to implement my own layoutManager?
Hide additional ui elements from item view initially by calling
(some_ui_element).setVisibility(View.GONE);
On item click, unhide the elements by calling
(some_ui_element).setVisibility(View.VISIBLE);
and make sure that the item layout in xml is set to wrap-content for its layout-height. The item cardview (or listview) got resized to show the ui elements.