自定义HorizontalScrollView结合FlowLayout实现流式布局翻页效果

来源:互联网 发布:2016双色球预测软件 编辑:程序博客网 时间:2024/06/15 22:20

模仿美团外卖点评页效果,实现流式布局每两行换页。

如下图

这里写图片描述 这里写图片描述 这里写图片描述

项目使用的是 HorizontalScrollView 结合 FlowLayout实现效果
FlowLayout是在鸿洋的代码上修改FlowLayout

添加了调整居中以及只绘制两行的代码

    //居中对齐    private void adjust() {        int count = mAllViews.size();        if (count == 0) {            return;        }        if (count > 2) {            count = 2;        }        for (int i = 0; i < count; i++) {            List<View> list = mAllViews.get(i);            if (list.size() == 0) {                return;            }            View rightView = list.get(list.size() - 1);            int right = rightView.getRight();            int padding = (getWidth() - right) / 2;            for (int j = 0; j < list.size(); j++) {                View view = list.get(j);                view.layout(view.getLeft() + padding, view.getTop(), view.getRight() + padding, view.getBottom());            }        }    }

绘制完成通知

        //填充完毕一页        if (onFillCallback != null) {            int n = 0;            for (int i = 0; i < mAllViews.size(); i++) {                n = n + mAllViews.get(i).size();            }            onFillCallback.onFill(n);        }

调用 setData填充数据,每绘制两行使用回调通知JLHorizontalScrollView 进行下一页的绘制,一直到所有数据绘制结束

    public void setData(final List<String> list, final OnCompleteCallback onCompleteCallback) {        //延迟以获取距离屏幕左侧的距离用来支持 margin 和 padding        post(new Runnable() {            @Override            public void run() {                clearLastPage();                mData.clear();                if (mContainer != null) {                    mContainer.removeAllViews();                    mPageCount = 0;                }                mOnCompleteCallback = onCompleteCallback;                int[] xy = new int[2];                getLocationOnScreen(xy);                mMargin = xy[0];                mRealWidth = mScreenWidth - mMargin * 2;                if (list == null) {                    return;                }                mList = list;                JLFlowLayout jlFlowLayout = new JLFlowLayout(mContext);                jlFlowLayout.setOnFillCallback(onFillCallback);                mJLFlowLayoutList.add(jlFlowLayout);                addPage(jlFlowLayout);                fillData(mList, jlFlowLayout);            }        });    }
   /**     * 填满一页返回再填下一页     */    JLFlowLayout.OnFillCallback onFillCallback = new JLFlowLayout.OnFillCallback() {        @Override        public void onFill(final int index) {            //一个一个加载,否则回调顺序就乱掉了            post(new Runnable() {                @Override                public void run() {                    int count = mList.size();                    if (index > count) {                        return;                    }                    //subList生成子列表后,不要试图去操作原列表 解决ConcurrentModificationException                    List<String> cache = new ArrayList<String>();                    cache.addAll(mList.subList(index, count));                    if (cache.isEmpty()) {                        mOnCompleteCallback.onComplete(mPageCount);                        return;                    }                    mList = cache;                    JLFlowLayout jlFlowLayout = new JLFlowLayout(mContext);                    jlFlowLayout.setOnFillCallback(onFillCallback);                    mJLFlowLayoutList.add(jlFlowLayout);                    addPage(jlFlowLayout);                    fillData(cache, jlFlowLayout);                }            });        }    };

其中有个坑,对subList的返回值进行 subList会报ConcurrentModificationException异常,原因subList的缺陷,解决办法重新创建一个 List 并赋值

使用 post保证绘制按顺序执行

具体细节看源码
GitHub地址ScrollFlowLayout

原创粉丝点击