Android RecyclerView 根据屏幕宽度动态调整列

当我们的应用窗口是可以拖动调整宽度的时候,网格列表下,想根据屏幕宽度动态调整网格列数,就需要对RecyclerView进行动态计算GridColumnCount并进行设置。这里就需要对RecyclerView进行自定义,我们直接看代码:

public class GridLayoutRecyclerView extends RecyclerView{
    private int mWidth;
    private int mGridItemWidth;
    private int mGridPaddingLeft;
    private int mGridColumnCount = 1;
    private BaseGridLayoutAdapter mBaseGridLayoutAdapter;


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

    public GridLayoutRecyclerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public GridLayoutRecyclerView(Context context, AttributeSet attributeSet, int defStyle) {
        super(context, attributeSet, defStyle);
        //item width
        mGridItemWidth = getResources().getDimensionPixelSize(R.dimen.item_grid_width_with_margin);
        mGridPaddingLeft = getResources().getDimensionPixelSize(R.dimen.dp_nine);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        setPadding(mGridPaddingLeft != 0 ? mGridPaddingLeft : 0, 0, 0, 0);
        super.onSizeChanged(w, h, oldw, oldh);
        if (mWidth == w) {
            return;
        }
        // calculate column count at:
        // 1).RV first init
        // 2).Window size changed
        calculateColumnCount();
    }

    @Override
    public void setLayoutManager(RecyclerView.LayoutManager layout) {
        super.setLayoutManager(layout);
        calculateColumnCount();
    }

    public int getGridColumnCount() {
        return mGridColumnCount;
    }


    @Override
        public void setAdapter(Adapter adapter) {
        mBaseGridLayoutAdapter = (BaseGridLayoutAdapter) adapter;
        super.setAdapter(adapter);
    }


    private void calculateColumnCount() {
        mWidth = getWidth();
        if (mWidth <= 0) {
            return;
        }
        RecyclerView.LayoutManager manager = getLayoutManager();
        if (manager != null) {
            mGridColumnCount = (mWidth - getPaddingLeft()) / mGridItemWidth;
            if (mGridColumnCount < 1) { //at least 1.
                mGridColumnCount = 1;
            }
            ((GridLayoutManager) manager).setSpanCount(mGridColumnCount);
        }
        setRecycledViewPoolSizeAndCacheSize();
    }

    private void setRecycledViewPoolSizeAndCacheSize() {
        //#0288832 we should set cache > mGridColumnCount to avoid invoke onCreateViewHolder() frequently in grid mode.
        if (mBaseGridLayoutAdapter != null) {
            getRecycledViewPool().setMaxRecycledViews(mBaseGridLayoutAdapter.getDefaultItemViewType(), mGridColumnCount);
        }
        setItemViewCacheSize(mGridColumnCount);
    }

    private MyGridLayoutManager mGridLayoutManager;

    public void updateShowMode() {
        if (null == mGridLayoutManager) {
            mGridLayoutManager = new MyGridLayoutManager(getContext(), getGridColumnCount());
        }
        setLayoutManager(mGridLayoutManager);
    }


    private static class MyGridLayoutManager extends GridLayoutManager {
        private boolean mScrollEnabled = true;

        public MyGridLayoutManager(Context context, int spanCount) {
            super(context, spanCount);
        }

        public boolean isScrollEnabled() {
            return mScrollEnabled;
        }

        public void setScrollEnabled(boolean scrollEnabled) {
            mScrollEnabled = scrollEnabled;
        }

        @Override
        public boolean canScrollVertically() {
            return mScrollEnabled && super.canScrollVertically();
        }
    }
}

适配器:

import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public abstract class BaseGridLayoutAdapter<T> extends RecyclerView.Adapter {

    public static final int VIEW_TYPE_GRID_ITEM = 0;

    private List<T> mData = new ArrayList<>();

    @Override
    public int getItemCount() {
        return mData.size();
    }

    protected T getItem(int pos) {
        if (mData.size() <= pos || pos < 0) {
            return null;
        }
        return mData.get(pos);
    }

    public int getPosition(T info) {
        return mData.indexOf(info);
    }

    public int getDefaultItemViewType() {
        return VIEW_TYPE_GRID_ITEM;
    }

    @Override
    public int getItemViewType(int position) {
        return getDefaultItemViewType();
    }

    public void setData(List<T> data) {
        mData.clear();
        mData.addAll(data);
        notifyDataSetChanged();
    }

    public List<T> getData() {
        return mData;
    }

    public void clear() {
        mData.clear();
        notifyDataSetChanged();
    }
}

如需要对item设置margin,可以在适配器中进行动态设置:

public class GridLayoutAdapter extends BaseGridLayoutAdapter<FileItem>{

    private Context mContext;

    private int mGridItemMargin;

    public GridLayoutAdapter(Context context) {
        mContext = context;
        mGridItemMargin = context.getResources().getDimensionPixelSize(R.dimen.dp_three);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_new_recyl, parent, false);
        return new ItemViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        if (holder instanceof ItemViewHolder) {
            View itemView = ((ItemViewHolder) holder).mItemView;

            RecyclerView.LayoutParams param =
                    (RecyclerView.LayoutParams) itemView.getLayoutParams();
            param.topMargin = mGridItemMargin; /*fix 0452504: Cause item height inconsistency remove 0 marginTop*/

            itemView.setLayoutParams(param);

        }
    }

    @Override
    public void setData(List<FileItem> data) {
        super.setData(data);
    }


    class ItemViewHolder extends RecyclerView.ViewHolder{
        View mItemView;
        public ItemViewHolder(@NonNull View itemView) {
            super(itemView);
            mItemView = itemView;
        }
    }

}


版权声明:本文为cmyperson原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。