How to create an empty space after last element in a RecyclerView? - android

I am using RecyclerView from support.v7 library to display items on shopping list.
When I'm scrolling to the end of my data, I can't see the price in the right side of the last item.
I want to add some space after scrolling to the last item, so that the button don't cover it.
Here is the image of the App with RecyclerView and FAB:
I can simply add an empty object to the list for an Adapter, but in this case it will behave like the rest of rows (it will have checkbox, and price 00.00 on the right side).
Is there another way to do that?

You can add bottomPadding and disable clipping, such as:
<RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
<!-- Bottom Padding, or space below last item -->
android:paddingBottom="10dp"
<!-- Clipping diabled -->
android:clipToPadding="false" />

Related

LayoutManager.startSmoothScroll scrolls to wrong position

I have a RecyclerView of goods with categories and HorizontalScrollView of good's categories above it. I am trying to implement the following behavior: when you click on category in scroll view, recycler scrolls to first good with this category.
To do it, I find first good with selected category in LiveData corresponding to recycler's content, then I find index of that good and begin to scroll recycler:
viewModel.stateLiveData.observe(viewLifecycleOwner) { state ->
val category = state.category
if (category.isNotEmpty()) {
val smoothScroller = LinearSmoothScroller(context)
val itemPositionWithCategory = viewmodel.getItemPositionWithCategory()
smoothScroller.targetPosition = itemPositionWithCategory
(binding.deliveryGoodsRecycler.layoutManager as LinearLayoutManager).startSmoothScroll(smoothScroller)
}
}
Smooth scroll works strange. By default first category is checked and list is in 0 position. If I click on for instance seventh category, when first good with this category is found correctly and list is scrolled to that good normally.
Problems appear with scrolling "backward". If I check sixth category, when seventh one is selected, the scroll works fine and scrolls to first good with sixth category. But I check fifth category, when seventh one is selected, the recycler scrolls to zero position for some reason. This behavior appears every time, when recycler is scrolled "backward" with none zero gap between categories (scroll to previous category works correct).
I made debug for backward scroll, category is not changing during scroll, index of the first good with target category is correct and is not changing during scroll. I logged index in recycler's OnScrollListener, in function onScrolled. When recycler is scrolled to previous category, this function is called much less times, than recycler is scrolled to top. In both cases index is not changing while scroll.
I have no idea, why smooth scroll works wrong in particular cases. Hope someone, who knows recycler good or had similar problems, could help me.
Update
I am adding part of my layout to make situation clear.
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/main_delivery_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<HorizontalScrollView
android:id="#+id/chips_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.chip.ChipGroup
android:id="#+id/chip_categories"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:selectionRequired="true"
app:singleLine="true"
app:singleSelection="true" />
</HorizontalScrollView>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/delivery_goods_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
Categories, which control position of recycler, are stored in chip_categories (there is no chips in layout, they are loaded from server and are added programmatically). chips_scroll_view allows to see all categories as they are not fit to screen width.
When I check category (chip) in chip_categories, selected category in state updates, this event is observed in fragment, then index of first good with selected category is found and delivery_goods_recycler is scrolled to that index. Bug appears when I check not previous category (one or more categories between them in left direction in chip_categories) and delivery_goods_recycler is scrolled to the top instead of found index.
As I understood you are scrolling a layout, you can scroll your Container(HorizontalScrollView) instead of using Layout Manager, HorizontalScrollView can contain your RecycleView inside the HorzintalScrollview.

Android ListView scroll to bottom

I am developing app with chat and I want my ListView to scroll to bottom when new message been posted by user and when user was at the bottom of the list and there are new messages recieved. I am using this ListView:
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:divider="#null"
android:dividerHeight="0dp"
android:stackFromBottom="true"
android:paddingBottom="9dp"
android:clipToPadding="false"/>
And this method to force scroll when needed:
private void scrollListViewToBottom() {
listView.setSelection(adapter.getCount() - 1);
}
But when chat contains element (big text or image) with height bigger than screen height it is scrolling to the top of it. I need my ListView to scroll exactly to the bottom, not to the last element.
I tried to use listView.scrollTo(0, listView.getBottom()) method but the result is very strange - it is scrolling sometimes to the last message + half-screen gap and sometimes to the place where I cannot see any messages.
Any ideas? Thanks.
You can use android:stackFromBottom="true" for populating list from bottom to top and add android:transcriptMode="alwaysScroll" for auto scrolling your listview.
You just have to call notifyDataSetChanged() and your list will be auto scrolled.
For handling scrolling to absolute bottom in case of large blocks, you can add list items with height of 1 px below every list item so that you will always be directed to end of list no matter what you item's height is.

Move layout up when layout above shrinks in height

Hi I have a fragment with two RecyclerViews in it, one above the other.
The first is a list of items for the user to take an action on and the second is where the items will be populated once the action is taken. So when an item is removed from the top list it is added to the bottom list.
The issue I am having is when I remove an item from the top RecyclerView all the remaining items in the top RecyclerView move up to fill in the space left by the removed item, but this leaves a gap between the top and bottom RecyclerViews.
How can I move the bottom recyclerview up to fill in the gap created once an item is removed from the top RecyclerView
Here is my layout xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_alignParentTop="true"
android:id="#+id/pending_tasks"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:layout_below="#id/pending_tasks"
android:id="#+id/completed_tasks"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
I have tried calling invalidate() on the bottom RecyclerView but that has not worked. Any help would be appreciated, thanks!
It's impossible to update layout size once it's been displayed on the screen. If you modify the content of your RecyclerView you can't just simply refresh the layout to shrink it.
I would suggest using single RecyclerView and storing lower bound of the first list in some variable. Then simply update it accordingly to modifications in your first list.
Another solution which may help you:
Change Relative layout width and height dynamically

Minus paddingTop on Android ListView, is it possible?

I have top margin of 30dp inside some of my list view items (including always the first one). However I don't want this top margin on my first list view item.
I have tried offsetting this by adding the following to the ListView
android:paddingTop="-30dp"
However, it doesn't seem to have any effect and the first list view item is still 30dp below the top edge of the list view.
Is there a way of getting minus top padding to work on an Android ListView?
XML
<ListView
android:choiceMode="singleChoice"
android:divider="#null"
android:dividerHeight="0dp"
android:paddingTop="-30dp"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
Then some of the list view items content is as follows:
<LinearLayout
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="match_parent"/
android:layout_marginTop="30dp">
<!--other content here-->
</LinearLayout>
The first list view item always uses the above template and im trying to offset that 30dp top margin.
Try setting android:layout_marginBottom="30dp" in your linear layout, so that you'll have the top of list without any margin but between list items still with margin. Does it look like what you want? Because minus padding is normally possible but in your case its overridden by the margin in list items.

Android: Data list scrolling along with other components

I'm trying to show a list of data in an android activity. Normally anyone would do that with a simple ListView which I have used many times before. But now I'm having an application with a fixed header and footer, with the middle part (the content) scrolling underneath both the header and the footer. In the middle section I would like to add other components both above and below the list of data, but the entire part must be scrollable. I tried adding components (like a button, textview etc) to a listview but the lay-out builder in Eclipse won't let me do that.
So I started using a ScrollView where you can easily add any component you like. But I am not allowed to add a ListView to a ScrollView, which I can understand as it would create a strange effect (as both are able to scroll).
Next I wanted to use a TableLayout to dynamically add TableRows, but on multiple websites it is said to be slow and 'not the way to do it'. I also couldn't find an elegant way to add the seperator between each item. With a ListView that would all be done very easily.
The following image probably explaines at best the effect I want: http://tinyurl.com/bvkec5d
The table with the 'Table Data' header can possibly have a lot of items and thus can become very large in length. What I don't want is that the table has a fixed size and the items are scrollable within that table. I actually want the table to grow in size and the ScrollView containing the table should therefore be growing as well. I also want the infobox above the table to scroll along (as with any other components which might be added later).
What is the best way to achieve this effect?
You can use a simple vertical LinearLayout (or a RelativeLayout) that contains your static header and footer, and use a ListView between them. You can set header and footer views on the ListView to add the scrollable header and footer content. For simplicity of example here's the LinearLayout way:
<LinearLayout android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent">
<!--static header content... can be any kind of view-->
<TextView
android:layout_width="match_parent"
android:layout_weight="0"
android:layout_height="wrap_content"/>
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<!--static footer content... can be any kind of view-->
<TextView
android:layout_width="match_parent"
android:layout_weight="0"
android:layout_height="wrap_content"/>
</LinearLayout>
And in code, you can say:
ListView theList = (ListView)findViewById(R.id.list);
// example of creating header and footer views from inflation or by instantiation in code
View myHeaderView = getLayoutInflater().inflate(R.layout.myHeaderLayout,theList,false);
View myFooterView = new TextView(this, some layout params);
theList.addHeaderView(myHeaderView);
theList.addFooterView(myFooterView);
ListView.addHeaderView and ListView.addFooterView should enable you to add other static views (whose content could be updated dynamically) to the top or bottom of a ListView:
public void addHeaderView (View v)
Since: API Level 1 Add a fixed view to appear at the top of the list.
If addHeaderView is called more than once, the views will appear in
the order they were added. Views added using this call can take focus
if they want.
NOTE: Call this before calling setAdapter. This is so ListView can
wrap the supplied cursor with one that will also account for header
and footer views.

Categories

Resources