模仿美团外卖点评页效果,实现流式布局每两行换页。
如下图
项目使用的是 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
本文介绍如何模仿美团外卖点评页,利用HorizontalScrollView和FlowLayout创建流式布局并实现每两行自动翻页的效果。在实现过程中,通过在FlowLayout上添加调整居中和限制绘制行数的代码,并在数据填充后使用回调通知滚动视图进行下一页的绘制。遇到的一个问题是在处理subList时出现ConcurrentModificationException,解决方法是创建新的List实例。源码可在GitHub的ScrollFlowLayout项目中查看。

782

被折叠的 条评论
为什么被折叠?



