在客户端的实际开发中,feed 流的样式还是有很多的,但是在实际的开发中,有一套方案直接拿来 用可以可以的,在recycleView 中,StaggeredGridLayoutManager 这种manager 就支持这种样式,我们看下最基本的实现方式:
recyclerView = rootView.findViewById(R.id.feed_recycler_view);
adapter = new RecyclerAdapter(thisActivity);
layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
recyclerView.setItemAnimator(null);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
这样就是最基本的feeds 流定义,recycleView 就是我们原生的recycleView,我们看下recycleView 中的adpter 是怎么实现的
public class RecyclerAdapter extends BaseRecyclerAdapter {
private List<E> dataList = new ArrayList<>();
public void appendData(List<E> list) {
if (list == null) {
return;
}
int startPosition = dataList.size();
dataList.addAll(list);
notifyItemRangeChanged(startPosition, list.size());
}
@Override
public RecyclerView.ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
// 绑定viewHolder 的地方
}
return viewHolder;
}
@Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) { // 绑定ViewHolder
if ( position < dataList.size()) {
holder.onBindViewHolder(dataList.get(position));
}
}
@Override
public int getRealItemCount() {
return dataList.size();
}
@Override
public int getRealItemViewType(int position) {
// 获取type 的地方
if (position < dataList.size()) {
return dataList.get(position).getType();
}
return -1;
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
// 这个地方是处理通栏的UI 处理
p.setFullSpan(true);
}
}
我们看下BaseRecyclerAdapter 父类中的
public abstract class BaseRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> {
private View header;
private View footer;
public static final int TYPE_HEADER = 10001;
public static final int TYPE_FOOTER = 10002;
public abstract ViewHolder onCreateItemViewHolder(ViewGroup var1, int var2);
public abstract void onBindItemViewHolder(ViewHolder var1, int var2);
public abstract int getRealItemCount();
public abstract int getRealItemViewType(int position);
public void setHeaderView(View headerView) {
header = headerView;
}
public void setFooterView(View footerView) {
footer = footerView;
}
public View getHeaderView() {
return header;
}
public View getFooterView() {
return footer;
}
@Override
public final ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewHolder holder = null;
switch (viewType) {
case TYPE_HEADER:
holder = new SimpleViewHolder(header);
break;
case TYPE_FOOTER:
holder = new SimpleViewHolder(footer);
break;
default:
holder = onCreateItemViewHolder(parent, viewType);
break;
}
return holder;
}
@Override
public final void onBindViewHolder(ViewHolder holder, int position) {
if (holder == null) {
return;
}
switch (getItemViewType(position)) {
case TYPE_HEADER:
break;
case TYPE_FOOTER:
break;
default:
onBindItemViewHolder(holder, position - (header == null ? 0 : 1));
break;
}
}
@Override
public final int getItemCount() {
return getRealItemCount() + (header == null ? 0 : 1) + (footer == null ? 0 : 1);
}
@Override
public final int getItemViewType(int position) {
if (position == 0 && header != null) {
return TYPE_HEADER;
}
if (position == getItemCount() - 1 && footer != null) {
return TYPE_FOOTER;
}
return getRealItemViewType(position - (header == null ? 0 : 1));
}
public class SimpleViewHolder extends ViewHolder {
public SimpleViewHolder(View itemView) {
super(itemView);
}
}
在recycleView 滑动的过程中添加滑动到下一页的逻辑
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// loadNextData(dy)
}
});
在loadNextData(int dy)中去判断滑到下一页的条件,在这个地方可以添加
通常的写法是:
int[] lastPositions = null;
lastPositions = layoutManager.findLastCompletelyVisibleItemPositions(lastPositions);
int lastVisibleItem = findMax(lastPositions);
int totalItemCount = recyclerView.getAdapter().getItemCount();
if (lastVisibleItem >= totalItemCount - LOAD_THRESHOLD
&& dy >= 0)
{
// 下拉刷新业务
}
}
其中 findMax 的实现方式为:
private int findMax(int[] lastPositions) {
int max = lastPositions[0];
for (int value : lastPositions) {
if (value > max) {
max = value;
}
}
return max;
}
其中 LOAD_THRESHOLD = 4;