アリコートピッチRecyclerView GridLayoutManager

達成するRecyclerViewテーブル

テーブル状のスタイルでRecyclerView GridLayoutManager共有を実現するために、達成することができ、親要素のレイアウトに合わせてアダプタ幅、即ち、アンドロイド:layout_width =「match_parent」。

RecyclerView rvPhotoAlbums = findViewById(R.id.rv_photoAlbums_content);
rvPhotoAlbums.setLayoutManager(new GridLayoutManager(this, 4));
rvPhotoAlbums.setAdapter(new PhotoAlbumsAdapter());

次のような効果があります

間隔ItemDecorationを追加

ItemDecorationソースコード解析

androidx.recyclerview.widget.RecyclerView#addItemDecoration(androidx.recyclerview.widget.RecyclerView.ItemDecoration)。
この方法では簡単にはルックItemDecoration:

public abstract static class ItemDecoration {
    // ....省略其他方法介绍.....

    /**
     * Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies
     * the number of pixels that the item view should be inset by, similar to padding or margin.
     * The default implementation sets the bounds of outRect to 0 and returns.
     * 解读:获取给定item view的偏移量,用outRect 表示。outRect的每个字段分别表示不同方向的偏移量,类似于填充或边距。
     * 默认设置为0,即没有间距。
     *
     * <p>
     * If this ItemDecoration does not affect the positioning of item views, it should set
     * all four fields of <code>outRect</code> (left, top, right, bottom) to zero
     * before returning.
     * 如果不想影响item view 的位置,需要置outRect 的left, top, right, bottom 为0
     *
     * <p>
     * If you need to access Adapter for additional data, you can call
     * {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the
     * View.
     *
     * @param outRect Rect to receive the output.
     * @param view    The child view to decorate
     * @param parent  RecyclerView this ItemDecoration is decorating
     * @param state   The current state of RecyclerView.
     */
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
            @NonNull RecyclerView parent, @NonNull State state) {
        getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
                parent);
    }
}

私たちは、コードのコメントを通じて、相続androidx.recyclerview.widget.RecyclerView.ItemDecorationクラスを介して距離を扱うことができることを知っています。

カスタムItemDecoration

public class GridSpaceItemDecoration extends RecyclerView.ItemDecoration {

    private int mSpanCount;//横条目数量
    private int mRowSpacing;//行间距
    private int mColumnSpacing;// 列间距

    /**
     * @param spanCount     列数
     * @param rowSpacing    行间距
     * @param columnSpacing 列间距
     */
    public GridSpaceItemDecoration(int spanCount, int rowSpacing, int columnSpacing) {
        this.mSpanCount = spanCount;
        this.mRowSpacing = rowSpacing;
        this.mColumnSpacing = columnSpacing;
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view); // 获取view 在adapter中的位置。
        int column = position % mSpanCount; // view 所在的列

        // 列间距
        outRect.left = mColumnSpacing;

        // 如果position > 行数,说明不是在第一行,则不指定行高,其他行的上间距为 top=mRowSpacing
        if (position >= mSpanCount) {
            outRect.top = mRowSpacing; // item top
        }
    }
}

ItemDecorationを追加

// 添加间距
rvPhotoAlbums.addItemDecoration(new GridSpaceItemDecoration(4,
        DpPxSpTool.INSTANCE.dip2px(this, 30),
        DpPxSpTool.INSTANCE.dip2px(this, 20)));

:[OK]を、私たちはの効果を見て

:(アイテムビューの範囲を区別するために、私はストロークを識別するために、異なる色を使用します。注)
見ることができ、アイテム全体の右、項目に割り当てられている幅GridLayoutManager、なぜなら我々しばらくItemDecorationアイテムビューは、左マージンを設定し、その全権利があるだろう、例の内容を絞ります。

アリコートピッチ

アイデアの実現

同じピッチを達成するために、我々は、アイテムの左右の余白を設定する必要があり、右マージン列ピッチ+ビュー=左余白の設定の左側面図、ピッチからの視覚効果が均等に分割されているようです。

ピッチのように満たすべき条件を整理するために最初に:

  1. 各モジュールの等しい大きさ、すなわち、各行は+右の値が等しい左。
  2. これは、列間隔後列のピッチ、左右+の即ち最前線=列に等しいです。

10の間隔は、カラムは、文字Iの列の代わりに、特定の便宜のために、想定されます
ケース2では:

チェック条件1:a.left + a.right = b.left + b.right = 5つの結果:満足する
チェック条件2:a.right + b.left = 10の結果:会います

事例3:

チェック条件1:a.left + a.right = b.left + b.right = c.left + c.right≈6.66 結果:満たす
条件2をチェックしてください:a.right + b.left = b.right + c.left≈10結果:会います

:推論は数式描画することができる
左= *(列ピッチ*(列1 /数))列の列数
-列間隔後に左の列= -列の数(列右=行のは、間隔を+1)*(*列ピッチ(1 /列の数))
注:本明細書で使用されるカラムの数は0であります

最終的には

/**
 * 描述 : RecyclerView GridLayoutManager 等间距。
 * <p>
 * 等间距需满足两个条件:
 * 1.各个模块的大小相等,即 各列的left+right 值相等;
 * 2.各列的间距相等,即 前列的right + 后列的left = 列间距;
 * <p>
 * 在{@link #getItemOffsets(Rect, View, RecyclerView, RecyclerView.State)} 中针对 outRect 的left 和right 满足这两个条件即可
 * <p>
 * 作者 : shiguotao
 * 版本 : V1
 * 创建时间 : 2020/3/19 4:54 PM
 */
public class GridSpaceItemDecoration extends RecyclerView.ItemDecoration {

    private final String TAG = "GridSpaceItemDecoration";

    private int mSpanCount;//横条目数量
    private int mRowSpacing;//行间距
    private int mColumnSpacing;// 列间距

    /**
     * @param spanCount     列数
     * @param rowSpacing    行间距
     * @param columnSpacing 列间距
     */
    public GridSpaceItemDecoration(int spanCount, int rowSpacing, int columnSpacing) {
        this.mSpanCount = spanCount;
        this.mRowSpacing = rowSpacing;
        this.mColumnSpacing = columnSpacing;
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view); // 获取view 在adapter中的位置。
        int column = position % mSpanCount; // view 所在的列

        outRect.left = column * mColumnSpacing / mSpanCount; // column * (列间距 * (1f / 列数))
        outRect.right = mColumnSpacing - (column + 1) * mColumnSpacing / mSpanCount; // 列间距 - (column + 1) * (列间距 * (1f /列数))

        Log.e(TAG, "position:" + position
                + "    columnIndex: " + column
                + "    left,right ->" + outRect.left + "," + outRect.right);

        // 如果position > 行数,说明不是在第一行,则不指定行高,其他行的上间距为 top=mRowSpacing
        if (position >= mSpanCount) {
            outRect.top = mRowSpacing; // item top
        }
    }
}

効果:

海岸に一度、一日それを呼び出します!

22元記事公開 ウォン称賛44 ビューに10万+を

おすすめ

転載: blog.csdn.net/JM_beizi/article/details/105364227