GridLayout combined with RecyclerView.Adapter to realize the display of single-page grid list

Go to Github first, there are also specific usages in github, if it is useful to you, please help me with a star

Encountering a requirement is a requirement, which is to display a layout similar to the nine-square grid within one page, but each item occupies a different size.

The final effect: The
Insert picture description here
design is shown in the figure: I
Insert picture description here
tried some other layouts. I feel that GridLayout is the most convenient. The layout is divided according to rows and columns. It is easy to realize our one-to-N, and the realization is simpler than Ali's Tangram , and ours The interface is not complicated and does not require overkill. And our layout can also easily realize the nine-square grid layout.

Not much nonsense, as we all know that RecyclerView.Adapter can create ViewHolder and bind the position in the list to the ViewHolder, so that we can bind the View and position and data of each position in the GridLayout.

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.GridLayout;

import androidx.annotation.Nullable;

/**
 * @package com.mgo.uikitimpl.view.mygrid
 * @user by lvyaodong
 * @date 2020/8/20
 * @email [email protected]
 */
public class DynamicGridLayout<D extends GridData, A extends BaseAdapter<D, BaseViewHolder<D>>> extends GridLayout {
    private static final String TAG = "DynamicGridLayout";

    private A mAdapter;
    private int mMargin = 10;
    private int mHalfMargin = mMargin / 2;

    public void setAdapter(A mAdapter) {
        this.mAdapter = mAdapter;
        loadView();
    }

    public DynamicGridLayout(Context context) {
        this(context, null);
    }

    public DynamicGridLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DynamicGridLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private void loadView() {
        if (mAdapter == null) {
            Log.e(TAG, "Adapter can not be null!");
            return;
        }
        for (int i = 0; i < mAdapter.getItemCount(); i++) {
            //创建ViewHolder
            BaseViewHolder<D> viewHolder = mAdapter.createViewHolder(this, 0);
            //绑定ViewHolder
            mAdapter.onBindViewHolder(viewHolder, i);

            D data = mAdapter.getItem(i);

            viewHolder.itemView.setTag(data);
            GridLayout.LayoutParams params = new GridLayout.LayoutParams();

            params.width = 0;
            params.height = 0;

            int leftMargin = data.getStartX() == 0 ? mMargin : mHalfMargin;
            int topMargin = data.getStartY() == 0 ? mMargin : mHalfMargin;
            int rightMargin = data.getEndX() % getColumnCount() == 0 ? mMargin : mHalfMargin;
            int bottomMargin = data.getEndY() % getRowCount() == 0 ? mMargin : mHalfMargin;

            params.setMargins(dp2px(this.getContext(), leftMargin), dp2px(this.getContext(), topMargin), dp2px(this.getContext(), dp2px(this.getContext(), rightMargin)), dp2px(this.getContext(), bottomMargin));
            params.columnSpec = GridLayout.spec(data.getStartX(), data.getEndX() - data.getStartX(), (float) (data.getEndX() - data.getStartX()));
            params.rowSpec = GridLayout.spec(data.getStartY(), data.getEndY() - data.getStartY(), (float) (data.getEndY() - data.getStartY()));

            addView(viewHolder.itemView, params);
        }
    }

    private int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

}

Then, because the first picture has exceeded the height assigned to him, temporarily the layout of the first position is not loaded, and then a picture is placed separately. If the big guys have a better plan, you can help me optimize it, haha.

In addition, each list return must have several position assignment fields, the coordinates of the upper right corner and the lower left corner.

package com.mgo.uikitimpl.view.mygrid;

/**
 * @package com.mgo.uikitimpl.view.mygrid
 * @user by lvyaodong
 * @date 2020/8/19
 * @email [email protected]
 */
public class GridData {
    private String imgUrl;
    private String text;
    private String page;
    private String tabId;
    private int startX;
    private int startY;
    private int endX;
    private int endY;

    public String getImgUrl() {
        return imgUrl;
    }

    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public String getTabId() {
        return tabId;
    }

    public void setTabId(String tabId) {
        this.tabId = tabId;
    }

    public int getStartX() {
        return startX;
    }

    public void setStartX(int startX) {
        this.startX = startX;
    }

    public int getStartY() {
        return startY;
    }

    public void setStartY(int startY) {
        this.startY = startY;
    }

    public int getEndX() {
        return endX;
    }

    public void setEndX(int endX) {
        this.endX = endX;
    }

    public int getEndY() {
        return endY;
    }

    public void setEndY(int endY) {
        this.endY = endY;
    }
}

	private int startX;
    private int startY;
    private int endX;
    private int endY;

These fields are necessary and others can be set according to requirements.

GridLayout usage understanding

Guess you like

Origin blog.csdn.net/u011148116/article/details/108666833