刚写完 RecyclerView 瀑布流后,来回的滑动会发现各种问题:滑动图片闪烁,顶部留有空白,左右位置来回切换;
下面针对这些问题稍微做了以下优化,下面是优化完的效果图:
滑动较快,但是没出现闪烁、留白和位置切换的问题=-=;下面看是如何优化的。
首先加入下面代码,防止item交换位置:
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);//防止item 交换位置
其次加入去掉 RecyclerView 动画代码,防止闪烁:
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
recyclerView.getItemAnimator().setChangeDuration(0);
最后监听 RecyclerView 滑动,防止第一行留有空白:
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);
layoutManager.invalidateSpanAssignments();//防止第一行到顶部有空白
}
});
代码加入完毕,下面是完整的代码:
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
//防止item 交换位置
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
recyclerView.setLayoutManager(layoutManager);
adapterFind = new Adapter_find(mContext, rankList, nearbyList, videoList);
((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
recyclerView.getItemAnimator().setChangeDuration(0);
recyclerView.setAdapter(adapterFind);
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);
//防止第一行到顶部有空白
layoutManager.invalidateSpanAssignments();
if (isSlideToBottom(recyclerView)) {
if (Integer.valueOf(listCount) != videoList.size() - 1) {
page++;
sendHttp(Constant.HttpCode.HTTP_DIALOG_NULL, false);
}
}
}
});
这样看似已经好了,但是在 adapter 中动态设置图片宽高时,尽量让服务器返回宽高;这样就可以直接设置图片大小,避免开启线程去获取图片宽高。
下面是服务器返回宽高,直接动态设置图片大小代码:
if (videoList.get(position).getHeight() != null && !videoList.get(position).getHeight().equals("")
&& !videoList.get(position).getHeight().equals("0")) {
height = Integer.valueOf(videoList.get(position).getHeight());
width = Integer.valueOf(videoList.get(position).getWidth());
videoHeight = height * (Utils.getScreenWidth(context) / 2) / width;
} else {
videoHeight = 500;
}
//动态设置控件宽高
ViewGroup.LayoutParams params1 = myViewHolder.iv_photo.getLayoutParams();
params1.height = videoHeight;
params1.width = Utils.getScreenWidth(context) / 2;
myViewHolder.iv_photo.setLayoutParams(params1);
上面的代码中,height 为服务器返回的图片高度,width 为服务器返回的图片宽度,videoHeight 为按比例缩放后的图片高度,Utils.getScreenWidth(context) 这是一个获取屏幕宽度的方法。按比例缩放后图片就不会变形拉伸了,适配也就做好了。
最后我是用的 Glide 加载图片的:
Glide.with(context)
.load(url)
.error(R.drawable.cat_error_circle)
.placeholder(R.color.colerTextHui)
.bitmapTransform(new RoundedCornersTransformation(context, radius, 0, RoundedCornersTransformation.CornerType.ALL))
.crossFade(1)
.override(width,SIZE_ORIGINAL)
.into(imageView);
这样关于瀑布流的优化就完成了。