【问题标题】:Equal height and width of RecyclerView itemsRecyclerView 项目的高度和宽度相等
【发布时间】:2020-01-11 18:35:13
【问题描述】:

从下面的图片可以看出,我几乎已经达到了我想要的效果。但是,RecyclerView 项目的大小不同。特别是,第 2 列 RecyclerView 与第 1 列的大小不同。

请注意,我已尝试实施来自 How to make RecyclerView's grid item to have equal height and width? 的解决方案,但我无法解决我的问题。

RecyclerView 项目:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.jackandphantom.circularimageview.RoundedImage
        android:id="@+id/launcher_icon"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:layout_constraintDimensionRatio="1:1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

XML 片段:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="@dimen/medium_margin"
        android:layout_marginRight="@dimen/medium_margin" />

</LinearLayout>

片段.java:

 public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);

        RecyclerView recyclerView = view.findViewById(R.id.recycler);
        recyclerView.setHasFixedSize(true);
        recyclerView.addItemDecoration(new ItemOffsetDecoration(getActivity(), R.dimen.medium_margin));
        GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);
        recyclerView.setLayoutManager(layoutManager);

        RecyclerViewAdapter adapter = new RecyclerViewAdapter(getActivity());
        recyclerView.setAdapter(adapter);

        return view;
    }

ItemOffsetDecoration.java

public class ItemOffsetDecoration extends RecyclerView.ItemDecoration {
    private int mItemOffset;

    private ItemOffsetDecoration(int itemOffset) {
        mItemOffset = itemOffset;
    }

    public ItemOffsetDecoration(@NonNull Context context, @DimenRes int itemOffsetId) {
        this(context.getResources().getDimensionPixelSize(itemOffsetId));
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
                               @NonNull RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        int position = parent.getChildLayoutPosition(view);

        GridLayoutManager manager = (GridLayoutManager) parent.getLayoutManager();

        if (manager != null && position < manager.getSpanCount()) outRect.top = mItemOffset;

        if (position % 2 != 0) {
            outRect.right = mItemOffset;
        }

        outRect.left = mItemOffset;
        outRect.bottom = mItemOffset;
    }
}

【问题讨论】:

    标签: android


    【解决方案1】:

    其实这不是height / widthRecyclerView 的问题。这是您的ItemDecoration 的问题。尝试改变你的装饰如下:

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent,
                               @NonNull RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
    
        int position = parent.getChildLayoutPosition(view);
    
        GridLayoutManager manager = (GridLayoutManager) parent.getLayoutManager();
    
        if (manager != null && position < manager.getSpanCount())
            outRect.top = mItemOffset;
    
        if (position % 2 == 0) {
            outRect.right = mItemOffset / 2; // Right offset for left child
        } else {
            outRect.left = mItemOffset / 2; // Left offset for Right child
        }
    
        outRect.bottom = mItemOffset;
    }
    

    示例结果: 每边的空间相等

    【讨论】:

    • 是的,我认为这可能是问题所在,但后来我为 recyclerview 删除了 ItemOffsetDecoration 并得到了相同的结果。如果我的问题得到解决,我将尝试您的 ItemOffsetDecoration 代码并在此处更新。
    【解决方案2】:

    好像你在矩形的右边添加了额外的偏移量

      if (position % 2 != 0) {
            outRect.right = mItemOffset;
      }
    

    此条件适用于每个奇数位置,因为适配器中的位置从 0 开始。 无论如何,您确定需要自定义项装饰来在 GridLayoutManager 中添加偏移量吗?

    【讨论】:

    • 是的,感谢您的回答。实际上,我只是在左侧、右侧、顶部和底部放置相等的空间,但问题是我只在偶数列项索引(即 0,2)中放置左填充,而在奇数列项索引(即 1,3)中放置左、右填充。
    【解决方案3】:

    如上所述,尝试删除此块,看看它是如何工作的

        if (position % 2 != 0) {
            outRect.right = mItemOffset;
        }
    

    您有一个网格布局,在您给定的图片中,右上角和右下角是索引 1 和 3。您正在更改每个奇数项目的偏移量。

    【讨论】:

    • 我只是在左侧、右侧、顶部和底部放置相等的空间,但问题是我只将左侧填充放在偶数列项目索引中,即 0,2 并将左侧、右侧填充放在奇数列项目索引即 1,3。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2017-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多