adapter = new ImageAdapter(this);
recyclerView.setAdapter(adapter);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this,3);
gridLayoutManager.setSpanSizeLookup(adapter.obtainGridSpanSizeLookUp(3));
recyclerView.setLayoutManager(gridLayoutManager);
SpaceViewItemLine itemDecoration = new SpaceViewItemLine(20);
recyclerView.addItemDecoration(itemDecoration);
複製代碼
adapter = new ImageStageredAdapter(this);
recyclerView.setAdapter(adapter);
StaggeredGridLayoutManager staggeredGridLayoutManager =
new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
SpaceViewItemLine itemDecoration = new SpaceViewItemLine(20);
recyclerView.addItemDecoration(itemDecoration);
複製代碼
ViewGroup.LayoutParams params = imgPicture.getLayoutParams();
//假設有多種不一樣的類型
int type = getAdapterPosition()%5;
//計算View的高度
int height = 300;
switch (type){
case 0:
height = 500;
break;
case 1:
height = 750;
break;
case 2:
height = 880;
break;
case 3:
height = 360;
break;
case 4:
height = 660;
break;
default:
break;
}
params.height = height;
imgPicture.setLayoutParams(params);
複製代碼
// 實現上拉加載重要步驟,設置滑動監聽器,RecyclerView自帶的ScrollListener
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
// 在newState爲滑到底部時
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
// 若是沒有隱藏footView,那麼最後一個條目的位置就比咱們的getItemCount少1,本身能夠算一下
if (!adapter.isFadeTips() && lastVisibleItem + 1 == adapter.getItemCount()) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
updateRecyclerView(adapter.getRealLastPosition(),
adapter.getRealLastPosition() + PAGE_COUNT);
}
}, 2500);
}
// 若是隱藏了提示條,咱們又上拉加載時,那麼最後一個條目就要比getItemCount要少2
if (adapter.isFadeTips() && lastVisibleItem + 2 == adapter.getItemCount()) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
updateRecyclerView(adapter.getRealLastPosition(),
adapter.getRealLastPosition() + PAGE_COUNT);
}
}, 2500);
}
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// 在滑動完成後,拿到最後一個可見的item的位置
int positions[] = staggeredGridLayoutManager.findLastVisibleItemPositions(null);
for(int pos : positions){
if(pos > lastVisibleItem){
lastVisibleItem = pos;//獲得最後一個可見的item的position
}
}
}
});
複製代碼
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
if (layoutParams != null && layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) layoutParams;
int position = holder.getLayoutPosition();
//若是是上拉加載更多類型,則設置setFullSpan爲true,那麼它就會佔一行
if (getItemViewType(position) == footType) {
params.setFullSpan(true);
}
}
}
複製代碼
recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
@NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
int spanCount = 0;
int spanIndex = 0;
RecyclerView.Adapter adapter = parent.getAdapter();
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (adapter==null || layoutManager==null){
return;
}
if (layoutManager instanceof StaggeredGridLayoutManager){
spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
spanIndex = ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();
}
//普通Item的尺寸
//TODO 會出現錯位的問題
int itemCount = adapter.getItemCount();
int childCount = layoutManager.getChildCount();
RefreshLogUtils.d("SpaceViewItemLine--count--"+itemCount + "-----"+childCount+"---索引--"+position+"---"+spanIndex);
if (position<itemCount && spanCount==2) {
if (childCount % 2 == 0){
//這個是右邊item
outRect.left = 5;
outRect.right = 20;
} else {
//這個是左邊item
outRect.left = 20;
outRect.right = 5;
}
if (childCount==1 || childCount==2){
outRect.top = 0;
} else {
outRect.top = 20;
}
RefreshLogUtils.d("SpaceViewItemLine--間距--"+childCount+"----"+outRect.left+"-----"+outRect.right);
}
}
});
複製代碼
recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
@NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
int spanCount = 0;
int spanIndex = 0;
RecyclerView.Adapter adapter = parent.getAdapter();
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (adapter==null || layoutManager==null){
return;
}
if (layoutManager instanceof StaggeredGridLayoutManager){
spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
spanIndex = ((StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();
}
//普通Item的尺寸
int itemCount = adapter.getItemCount();
int childCount = layoutManager.getChildCount();
RefreshLogUtils.d("SpaceViewItemLine--count--"+itemCount + "-----"+childCount+"---索引--"+position+"---"+spanIndex);
if (position<itemCount && spanCount==2) {
if (spanIndex != GridLayoutManager.LayoutParams.INVALID_SPAN_ID) {
//getSpanIndex方法無論控件高度如何,始終都是左右左右返回index
if (spanIndex % 2 == 0) {
//這個是左邊item
outRect.left = 20;
outRect.right = 5;
} else {
//這個是右邊item
outRect.left = 5;
outRect.right = 20;
}
if (childCount==1 || childCount==2){
outRect.top = 0;
} else {
outRect.top = 20;
}
}
//outRect.top = space;
RefreshLogUtils.d("SpaceViewItemLine--間距--"+spanIndex+"----"+outRect.left+"-----"+outRect.right);
}
}
});
複製代碼
public class CustomStaggeredGridLayoutManager extends StaggeredGridLayoutManager {
private static final String TAG = "LOG_CustomStaggered";
public CustomStaggeredGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public CustomStaggeredGridLayoutManager(int spanCount, int orientation) {
super(spanCount, orientation);
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
}catch (Exception e){
Log.i(TAG, "onLayoutChildren: e " + e.getMessage());
}
}
}
複製代碼
public void setDatas(List mDatas ) {
this.dataList = mDatas;
notifyDataSetChanged();
}
/**
* 注意這個是未關注時候的瀑布流刷新數據
* 上拉加載更多時,建議刷新上拉加載那一部分數據便可,不用刷新全部數據
* @param puBuList 瀑布流集合
*/
public void setMoreData(List<BasePubuBean> puBuList) {
int start = mayContentList.size();
if (puBuList!=null && puBuList.size()!=0){
mayContentList.addAll(puBuList);
int end = mayContentList.size();
mRecommendPuBuAdapter.notifyItemRangeInserted(start,end);
}
}
複製代碼
@Override
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
int width = 0;
int height = 0;
switch (holder.getItemViewType()) {
case BasePubuBean.content_type9:
break;
//發佈的短視頻的寬高也是限制爲3:4
case BasePubuBean.content_type2:
int videoWidth = (SysUtils.getScreenWidth((Activity) mContext)-SysUtils.Dp2Px(mContext,43)) / 2;
int videoHeight = (int) (videoWidth * (4/3.0f));
RelativeLayout.LayoutParams puBuParams2 = ViewUtils.getPuBuParams(mContext, videoWidth, videoHeight);
holder.getView(R.id.mImageView).setLayoutParams(puBuParams2);
break;
//活動頭圖,自適應拿到圖片寬度,而後寬高比是4:3
case BasePubuBean.content_type4:
int imageWidth = (SysUtils.getScreenWidth((Activity) mContext)-SysUtils.Dp2Px(mContext,43)) / 2;
int imageHeight = (int) (imageWidth * (3/4.0f));
RelativeLayout.LayoutParams puBuParams4 = ViewUtils.getPuBuParams(mContext,imageWidth, imageHeight);
holder.getView(R.id.mImageView).setLayoutParams(puBuParams4);
break;
//推薦車系,寬高比是4:3
case BasePubuBean.content_type10:
int imageWidth10 = (SysUtils.getScreenWidth((Activity) mContext)-SysUtils.Dp2Px(mContext,43)) / 2;
int imageHeight10 = (int) (imageWidth10 * (3/4.0f));
ImageView imageView = holder.getView(R.id.mImageView);
ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
layoutParams.height = imageHeight10;
layoutParams.width = imageWidth10;
imageView.setLayoutParams(layoutParams);
break;
case BasePubuBean.content_type1:
case BasePubuBean.content_type3:
case BasePubuBean.content_type5:
case BasePubuBean.content_type6:
case BasePubuBean.content_type7:
case BasePubuBean.content_type8:
int imageWidth = (SysUtils.getScreenWidth((Activity) mContext)-SysUtils.Dp2Px(mContext,43)) / 2;
width = mData.get(position).getWidth();
height = mData.get(position).getHeight();
if( width!=0 && height!=0){
RelativeLayout.LayoutParams puBuParams1 = ViewUtils.getPuBuParams(mContext,imageWidth, height);
holder.getView(R.id.mImageView).setLayoutParams(puBuParams1);
}else {
int video_width = mData.get(position).getVideo_width();
int video_height = mData.get(position).getVideo_height();
if(video_width!=0 && video_height!=0){
holder.getView(R.id.mImageView).setLayoutParams(ViewUtils.getPuBuParams(
mContext,imageWidth, video_height));
}else {
holder.getView(R.id.mImageView).setLayoutParams(ViewUtils.getPuBuParams(
mContext,imageWidth , 125));
}
}
break;
default:
break;
}
}
複製代碼
@Override
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
//獲取屏幕寬度
if (screenWidth==0){
screenWidth = SysUtils.getScreenWidth((Activity) mContext);
}
//16+11+16
if (padding==0){
padding = SysUtils.Dp2Px(mContext,43);
}
if (imageWidth==0){
imageWidth = (screenWidth-padding) / 2;
}
//寬高爲3:4的圖片高度
if (imageHeight34 ==0){
imageHeight34 = (int) (imageWidth * (4/3.0f));
}
//寬高4:3的圖片高度
if (imageHeight43 ==0){
imageHeight43 = (int) (imageWidth * (3/4.0f));
}
//長寬爲16:9的圖片高度
if (imageHeight169 ==0){
imageHeight169 = (int) (imageWidth * (16/9.0f));
}
switch (holder.getItemViewType()) {
case BasePubuBean.content_type9:
break;
//發佈的短視頻的是限制爲3:4
case BasePubuBean.content_type2:
int width34 = imageWidth;
int height34 = imageHeight34;
ImageView imageView34 = holder.getView(R.id.mImageView);
ViewGroup.LayoutParams layoutParams34 = imageView34.getLayoutParams();
layoutParams34.height = height34;
layoutParams34.width = width34;
imageView34.setLayoutParams(layoutParams34);
break;
//行情文章也是4:3
case BasePubuBean.content_type8:
//活動頭圖,自適應拿到圖片寬度,而後是4:3
case BasePubuBean.content_type4:
//文章詳情也是4:3
case BasePubuBean.content_type5:
//推薦車系是4:3
case BasePubuBean.content_type10:
int width43 = imageWidth;
int height43 = imageHeight43;
ImageView imageView43 = holder.getView(R.id.mImageView);
ViewGroup.LayoutParams layoutParams43 = imageView43.getLayoutParams();
layoutParams43.height = height43;
layoutParams43.width = width43;
imageView43.setLayoutParams(layoutParams43);
break;
//長視頻16:9
case BasePubuBean.content_type3:
int width169 = imageWidth;
int height169 = imageHeight169;
ImageView imageView169= holder.getView(R.id.mImageView);
ViewGroup.LayoutParams layoutParams169 = imageView169.getLayoutParams();
layoutParams169.height = height169;
layoutParams169.width = width169;
imageView169.setLayoutParams(layoutParams169);
break;
case BasePubuBean.content_type1:
case BasePubuBean.content_type6:
case BasePubuBean.content_type7:
ImageView imageView= holder.getView(R.id.mImageView);
int width = mData.get(position).getWidth();
int height = mData.get(position).getHeight();
if( width!=0 && height!=0){
//這種方式會建立大量的對象
//RelativeLayout.LayoutParams puBuParams1 = ViewUtils.getPuBuParams(mContext,width, height);
//holder.getView(R.id.mImageView).setLayoutParams(puBuParams1);
ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
layoutParams.height = height;
layoutParams.width = imageWidth;
imageView.setLayoutParams(layoutParams);
}else {
int videoWidth = mData.get(position).getVideo_width();
int videoHeight = mData.get(position).getVideo_height();
if(videoWidth!=0 && videoHeight!=0){
ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
layoutParams.height = videoHeight;
layoutParams.width = imageWidth;
imageView.setLayoutParams(layoutParams);
//holder.getView(R.id.mImageView).setLayoutParams(ViewUtils.getPuBuParams(
// mContext,imageWidth, video_height));
}else {
ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
layoutParams.height = 125;
layoutParams.width = imageWidth;
imageView.setLayoutParams(layoutParams);
//holder.getView(R.id.mImageView).setLayoutParams(ViewUtils.getPuBuParams(
// mContext,imageWidth,125));
}
}
break;
default:
break;
}
}
複製代碼
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
final View view = LayoutInflater.from(mContext).inflate(R.layout.item_me_gv_grid, parent, false);
final MyViewHolder holder = new MyViewHolder(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onItemClick(view, holder.getLayoutPosition());
}
}
});
return holder;
}
複製代碼
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onItemClick(holder.itemView, holder.getAdapterPosition());
}
}
});
}
複製代碼
class MyViewHolder extends RecyclerView.ViewHolder {
MyViewHolder(final View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onItemClick(itemView, getAdapterPosition());
}
}
});
}
}
複製代碼
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
LogUtil.i("yc---initRecyclerView"+ "恢復Glide加載圖片");
Glide.with(RecommendFragment.this).resumeRequests();
}else {
LogUtil.i("yc---initRecyclerView"+"禁止Glide加載圖片");
Glide.with(RecommendFragment.this).pauseRequests();
}
}
});
複製代碼
Glide.with(mImageView)
.load(imgUrl)
.apply(RequestOptions.bitmapTransform(multiTransformation)
.placeholder(R.drawable.glide_load)
.error(R.drawable.glide_error))
.into(mImageView);
複製代碼
/**
* 低內存的時候執行
*/
@Override
public void onLowMemory() {
Log.d("Application", "onLowMemory");
super.onLowMemory();
Glide.get(this).clearMemory();
}
/**
* HOME鍵退出應用程序
* 程序在內存清理的時候執行
*/
@Override
public void onTrimMemory(int level) {
Log.d("Application", "onTrimMemory");
super.onTrimMemory(level);
if (level == TRIM_MEMORY_UI_HIDDEN){
Glide.get(this).clearMemory();
}
Glide.get(this).trimMemory(level);
}
複製代碼
Don't use wrap_content. Even if you don't use Glide, wrap_content necessarily means that the size of your views in RecyclerView are going to change from item to item. That's going to cause all sorts of UI weirdness. One option is to try to obtain the image dimensions in whatever metadata you're using to populate the RecyclerView. Then you can set a fixed View size in onBindViewHolder so the view size at least doesn't change when the image is loaded. You're still likely to see weird scroll bar behavior though.
If nothing else, you can always pick a uniform size that's large enough for all items and use the same consistent size for every item. For the image file size, you can downscale or upscale by setting the ImageView size manually to 150dp x 150dp. Ultimately either you need uniform view sizes or predetermined view sizes. There's nothing else that will prevent content from expanding or shrinking in your RecyclerView.
For the placeholder bit, I think that will be fixed by 648c58e, you can check by trying the 4.2.0-SNAPSHOT version: http://bumptech.github.io/glide/dev/snapshots.html.
複製代碼