我正在构建一个购物车RecyclerView,它在RecyclerView中显示购物车中的所有项目,并且在底部有一个额外的视图来总结购物车(总欠款,优惠券折扣(如果适用的话))。
如果购物车中有>3项,它看起来很好,因为用户必须滚动到底部才能查看“摘要视图”。但是,如果有1项或2项,则会出现第一项,而不是摘要视图,然后是空白。我更喜欢第一个项目,然后是空白,然后是摘要视图。
我尝试过添加空项,但是,根据设备的分辨率,它看起来不一致。
当前外观小于3项(如不需要滚动):
-----------
| Item1 |
| ------- |
| Item2 |
| ------- |
| Summary |
| ------- |
| |
| |
| |
| |
----------
期望的外观:
-----------
| Item1 |
| ------- |
| Item2 |
| ------- |
| |
| |
| |
| |
| ------- |
| Summary |
----------
发布于 2015-04-15 08:06:42
我在考虑你的任务,最后整理了一些你可能觉得有用的代码。不过在这个舞台上有个问题。
我所做的是在回收商的视图中添加了一个物品装饰师:
recyclerView.addItemDecoration(new StickySummaryDecoration());
下面是我对基本装饰器的实现(坦率地说,这是我第一次使用项目装饰器,所以它可能不是最优的或者完全正确的,但我已经尽力了):
public class StickySummaryDecoration extends RecyclerView.ItemDecoration {
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int childCount = parent.getAdapter().getItemCount();
int lastVisibleItemPosition =
((LinearLayoutManager) parent.getLayoutManager()).findLastVisibleItemPosition();
int firstVisiblePosition =
((LinearLayoutManager) parent.getLayoutManager())
.findFirstCompletelyVisibleItemPosition();
if ((firstVisiblePosition == 0) && (lastVisibleItemPosition == (childCount - 1))) {
View summaryView = parent.getChildAt(parent.getChildCount() - 1);
int topOffset = parent.getHeight() - summaryView.getHeight();
int leftOffset =
((RecyclerView.LayoutParams) summaryView.getLayoutParams()).leftMargin;
c.save();
c.translate(leftOffset, topOffset);
summaryView.draw(c);
c.restore();
summaryView.setVisibility(View.GONE);
}
}
}
所以我从这得到了什么。
在短列表中,底部停靠的摘要:
您需要向下滚动以查看长列表中的摘要:
现在是关于一个问题。这个副作用,当滚动回长的名单是我还没有解决。
我的实验被上传到github回购,以防万一:)
编辑
刚才我告诉我,回收器视图中缺少的行元素是我的回收摘要视图持有者,它具有GONE
可见性。应该有办法把它带回来..。
编辑2
我重新考虑了我的第一个解决方案,并稍微修改了代码,以考虑长列表的情况(在这种情况下,项目装饰是禁用的(我认为它更接近您想要实现的目标),这自动解决了丢失的行问题。
发布于 2016-05-02 08:16:08
基于伊吉特的回答,我创建了一个工作实现。扩展ItemDecoration
和覆盖getItemOffsets()
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int childCount = parent.getAdapter().getItemCount();
if (parent.getChildLayoutPosition(view) != childCount - 1) return;
int lastViewBottom = calculateViewBottom(parent.getLayoutManager().findViewByPosition(childCount - 2));
view.measure(parent.getWidth(), parent.getHeight());
int height = view.getMeasuredHeight();
int topOffset = parent.getHeight() - lastViewBottom - height;
if (topOffset < 0) topOffset = itemOffset;
outRect.set(itemOffset, topOffset, itemOffset, itemOffset);
}
private int calculateViewBottom(View view) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
return (int) view.getY() + view.getHeight() + params.topMargin + params.bottomMargin;
}
发布于 2015-04-14 21:06:52
这不是一个预期的用例,但是您创建了一个ItemDecorator,当在底部视图上调用getItemOffsets时,计算它上面的空间并将其设置为decorOffsetTop。
每次添加项时,都应该使项目装饰偏移无效,以便RecyclerView再次调用您的回调以进行新的计算。
这不会是微不足道的,但这应该有效。
https://stackoverflow.com/questions/29637693
复制相似问题