Introduction to Catalogue
01. Realization of Rule Waterfall Flow
02. Realization of Irregular Waterfall Flow
2.1 Implementation
2.2 Problems encountered
03. Pull-up Loading of Waterfall Flow
04. Set up a dividing line for the waterfall flow
05. Custom Manager Crash
06. How to avoid refresh jitter
07. Why does it sometimes jump?
08. Waterfall Flow Picture Optimization
09.onBindViewHolder optimization
10. Waterfall Stream item Click Event Optimization
11.Glide loading optimization
12. It is recommended to specify the width of the picture.
Welcome colleagues to discuss the optimal scheme of waterfall flow
If peers see this article, there are good waterfall flow optimization programs, welcome to give suggestions, or give links can also.
Demand:
The waterfall stream has about 10 item views of different type s in the past 10 years. Then the view is set dynamically according to the width and height, and the server will return the proportion.
Items in waterfalls need to cut corners
Now use glide to load pictures
The product said that the reference tremble fast hand app, let the waterfall flow sliding effect is particularly smooth... But the current problem is that it's okay to slide more than a dozen pages, but when you slide thirty or forty pages, you'll get Carlton. Welcome colleagues to give suggestions!
Hot wire
Blog Notes Summary [March 16 to date], including Java foundation and in-depth knowledge points, Android technology blog, Python learning notes and so on, including the usual development of the bug summary, of course, also in the spare time to collect a large number of interview questions, long-term updates and maintenance and correction, continuous improvement... Open source files are in markdown format! At the same time, life blog has also been open source. Since 12 years, it has accumulated a total of N articles [nearly 1 million words, one after another moved to the Internet]. Please indicate the source for reprinting. Thank you!
Link Address: https://github.com/yangchong2...
If you feel good, you can start. Thank you. Of course, you are also welcome to make suggestions. Everything starts at a slight moment, and quantitative change causes qualitative change.
01. Realization of Rule Waterfall Flow
The simplest rule waterfall flow implementation is to set three columns of data, and then group the data at the same height. It's a regular waterfall.
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);
02. Realization of Irregular Waterfall Flow
The simplest irregular waterfall flow implementation, the following is to set up two columns of data, and then the height of the data is different, the height of the picture is random.
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);
This is pseudocode. Assuming different heights are set, the code is as follows. Simply set different image heights, this is done in onBindViewHolder.
ViewGroup.LayoutParams params = imgPicture.getLayoutParams();
// Assuming that there are many different types
int type = getAdapterPosition()%5;
// Calculate View Height
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);
2.2 Problems encountered
Meeting problems
1. How can RecyclerView achieve more drop-down loading?
2. When the Staggered Grid Layout Manager shows more loading, loading more as the last item does not occupy the screen width alone, but only the width of one item.
3. How does Staggered Grid Layout Manager randomly set the height of item?
4. When the Staggered Grid Layout Manager uploads the data to refresh the UI, the page item jitter is caused by the high randomness.
5. Recycler View's inexplicable Inconsistency detected crash;
Carton and Memory Release
It feels good to slide a few pages over the waterfall, but once you slide thirty or forty pages, it feels like the page is a bit cartridged.
03. Pull-up Loading of Waterfall Flow
First of all, add the listening method, add this method to load more data. But there was a problem. The layout with more pull-up loads only took up 1/span Count column, which was particularly ugly. So how to deal with it, and then look down...
First, you need to be able to listen for recyclerView sliding events.
Determine whether recyclerView slides to the last item;
recyclerView loads more RecyclerView.Adapter settings: RecyclerView.Adapter related code, mainly defines two ViewHolder types, footType for the bottom viewHolder, normalType for the normal item viewHolder, according to the position to display different viewholders;
// Implementing important steps of pull-up loading, setting up sliding listener, ScrollListener with RecyclerView
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); // When newState slides to the bottom if (newState == RecyclerView.SCROLL_STATE_IDLE) { // If you don't hide footView, then the location of the last entry is 1 less than our getItemCount, so you can figure it out for yourself if (!adapter.isFadeTips() && lastVisibleItem + 1 == adapter.getItemCount()) { handler.postDelayed(new Runnable() { @Override public void run() { updateRecyclerView(adapter.getRealLastPosition(), adapter.getRealLastPosition() + PAGE_COUNT); } }, 2500); } // If the prompt bar is hidden and we pull it up again, the last entry will be 2 fewer than getItemCount 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); // After the sliding is completed, get the last visible item's position int positions[] = staggeredGridLayoutManager.findLastVisibleItemPositions(null); for(int pos : positions){ if(pos > lastVisibleItem){ lastVisibleItem = pos;//Get the position of the last visible item } } }
});
Because it's a waterfall flow, you need to set footerView to occupy a line. The code is as follows
@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(); //If more types are loaded by pull-up, set setFullSpan to true, and it takes up one line if (getItemViewType(position) == footType) { params.setFullSpan(true); } }
}
04. Set up a dividing line for the waterfall flow
Let's first look at the code where there are dislocations and partitioning lines are problematic. The following method judges the different spacing between odd and even number settings according to child Count.
For example, when it is odd, set the item to 20 on the left and 5 on the right; when it is even, the item to 5 on the left and 20 on the right.
If the odd items are on the left and even items are on the right, the spacing is fine.
If the first item is on the left [high], the second, the third, the fourth item is on the right, and the fifth item is on the left... Think about it, then, when the third item is on the right, the spacing will be irregular.
Obviously, it is impossible to set the distance between item s according to odd or even numbers, and there will be dislocation.
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(); } //Dimensions of ordinary Item //TODO will be misaligned int itemCount = adapter.getItemCount(); int childCount = layoutManager.getChildCount(); RefreshLogUtils.d("SpaceViewItemLine--count--"+itemCount + "-----"+childCount+"---Indexes--"+position+"---"+spanIndex); if (position<itemCount && spanCount==2) { if (childCount % 2 == 0){ //This is the right item. outRect.left = 5; outRect.right = 20; } else { //This is the left item. outRect.left = 20; outRect.right = 5; } if (childCount==1 || childCount==2){ outRect.top = 0; } else { outRect.top = 20; } RefreshLogUtils.d("SpaceViewItemLine--spacing--"+childCount+"----"+outRect.left+"-----"+outRect.right); } }
});
The solution can be judged by the getSpanIndex() in Staggered Grid LayoutManager. LayoutParams, which starts from left to right regardless of your height.
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(); } //Dimensions of ordinary Item int itemCount = adapter.getItemCount(); int childCount = layoutManager.getChildCount(); RefreshLogUtils.d("SpaceViewItemLine--count--"+itemCount + "-----"+childCount+"---Indexes--"+position+"---"+spanIndex); if (position<itemCount && spanCount==2) { if (spanIndex != GridLayoutManager.LayoutParams.INVALID_SPAN_ID) { //The getSpanIndex method always returns the index left or right regardless of the height of the control. if (spanIndex % 2 == 0) { //This is the left item. outRect.left = 20; outRect.right = 5; } else { //This is the right 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--spacing--"+spanIndex+"----"+outRect.left+"-----"+outRect.right); } }
});
05. Custom Manager Crash
RecyclerView's inexplicable Inconsistency detected crash;
The reasons for this anomaly are as follows:
When using RecyclerView and official drop-down refresh, if the bound List object is clear before updating the data, and then the user quickly slides up RV, it will cause crash, and the exception will not be reported to your code, which is an internal RV error.
Custom a Custom Staggered Grid Layout Manager to capture exceptions in onLayout Children:
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()); } }
}
About Staggered Grid Layout Manager Exception Description
06. How to avoid refresh jitter
When the Staggered Grid Layout Manager pulls up to load data refresh UI, it causes the problem of page item jitter because of the high randomness; here, it is global refresh because notify DataSetChanged is called directly; and when refresh, the height of item is redistributed randomly, which will cause jitter when data refresh. It is recommended that notify ItemRangeChanged be used for local refresh:
public void setDatas(List mDatas ) {
this.dataList = mDatas; notifyDataSetChanged();
}
/**
- Note that this is the waterfall flow refresh data when it's not noticed
- When the pull-up load is more, it is recommended to refresh the part of the data loaded by the pull-up, instead of refreshing all the data.
- @ param puBuList Waterfall Flow Set
*/
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); }
}
07. Why does it sometimes jump?
Because the height of the image we loaded is uncertain (the width is determined because it can be divided according to the screen width and the number of Items per line), and when we slide a distance below RecyclerView, the size of item is uncertain due to the recovery mechanism of ViewHolder. Item needs to be redrawn when it slides back to the top, so Item needs to redraw itself. This leads to redrawing, so there will be blinking, jumping, blank and other issues. In the final analysis, as long as we determine the size of Item before redrawing, we can avoid Item to recalculate its size and avoid many problems caused by redrawing.
08. Waterfall Flow Picture Optimization
Specific optimization scheme
Step 1: Reduce layout nesting and avoid creating a large number of temporary Layout Params objects when setting the width and height of the image control in onBindViewHolder after getting the size of the server
Step 2: Use glide to load, bind the life cycle of activity or fragment, and try not to use global or static context. Note that the instance passed in with() method determines the lifetime of the Glide loading image. If an instance of Activity or Fragment is passed in, the image loading will stop when the Activity or Fragment is destroyed. If the application Context is passed in, the image loading will stop only when the application is killed.
Step 3: For list entries, especially waterfall streams, it is not recommended to use Transition Options to load the set animations, especially not to use your own custom animations.
Avoid using round corner ImageView
In practical projects, some images with rounded corners are often used, or they are directly circular. Round images, mostly for some users'avatars and other display effects.
Under Android, there are also a lot of open source controls like XxImageView, which are used to manipulate Bitmap to achieve the effect of a rounded image, such as the relatively hot Rounded Image View on Github.
Most of them are based on the principle of receiving Bitmap you pass on and then outputting a new Bitmap such as the original Bitmap. On this basis, some rounded corners are processed. This leads to the fact that one more Bitmap is held in memory, and the memory occupied by a single image is doubled.
So now that Glide has been chosen, it is recommended to use glide-transformations as an open source library. Glide-transformations uses Glide's bitmap Transfrom () interface to implement some transformation operations on loaded Bitmap. Glide-transformations provide a series of classes to transform loaded images, from shape transformation to color transformation, all support, basically meet most of the development needs, and it will reuse Glide's BitmapPool to achieve the purpose of saving memory.
09.onBindViewHolder optimization
In this method, data is mainly bound to the View view. Because waterfall streams have many different type s of views, some need to set the width and height, others need to get the width and height data from the server and then dynamically modify the view properties. So the calculation of width and height can also be optimized.
Let's first look at the original code, which shows only the code that dynamically sets width and height. As follows
Looking at the following code, you will find these problems. First, the widths of different types of waterfall flow are calculated frequently. The widths are screen widths minus spacing, and then divided by 2. The waterfall flow is divided into two lines. Second, create LayoutParams objects frequently, and then set the width and height attributes.
@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; //The width of published short videos is also limited to 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; //Movable header image, adaptively get the width of the picture, and then the aspect ratio is 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; //Recommended car system, aspect ratio is 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; }
}
Then take a look at the optimized code.
Then the following code can greatly reduce the frequent dynamic calculation of wide and high attributes. Getting layoutParams through imageView34.getLayoutParams() avoids creating a large number of objects through new. You know, it's okay to use the above code as usual, but in the recyclerView waterfall stream, you can also optimize it slightly.
@Override
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position) {
super.onBindViewHolder(holder, position); //Get screen width 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; } //Picture Height with 3:4 Width and Height if (imageHeight34 ==0){ imageHeight34 = (int) (imageWidth * (4/3.0f)); } //Picture Height 4:3 Width and Height if (imageHeight43 ==0){ imageHeight43 = (int) (imageWidth * (3/4.0f)); } //Height of 16:9 Length and Width if (imageHeight169 ==0){ imageHeight169 = (int) (imageWidth * (16/9.0f)); } switch (holder.getItemViewType()) { case BasePubuBean.content_type9: break; //Short videos are limited to 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; //Market articles are also 4:3 case BasePubuBean.content_type8: //Active header image, adaptive to get the width of the picture, and then 4:3 case BasePubuBean.content_type4: //Details of the article are also 4:3. case BasePubuBean.content_type5: //The recommended car system is 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; //Long Video 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){ //This approach creates a large number of objects //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; }
}
10. Waterfall Stream item Click Event Optimization
There are two ways to set item click events for rv: 1. Write in onCreateViewHolder; 2. Write in onBindViewHolder; 3. Write in ViewHolder. So what kind of good is it?
1. Write in onCreateViewHolder
@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;
}
2. Write in onBindViewHolder
@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()); } } });
}
3. Write in ViewHolder
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()); } } }); }
}
It is not necessary to create new onClickListener instances frequently in onBindViewHolder(). It is suggested that the new View should be set up once in onCreateViewHolder().
11.Glide loading optimization
glide optimizes the program code, forbids loading pictures when sliding, and restores loading pictures after stopping sliding.
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"+ "recovery Glide Loading Pictures"); Glide.with(RecommendFragment.this).resumeRequests(); }else { LogUtil.i("yc---initRecyclerView"+"prohibit Glide Loading Pictures"); Glide.with(RecommendFragment.this).pauseRequests(); } }
});
Life Cycle of Binding Control
When an interface is gone, we would prefer the current image to be unloaded, so how does Glide do that? When item slides from visibility to invisibility in the recyclerView list, how to control the lifetime of the picture request can be bound to the lifetime of the control.
Glide.with(mImageView)
.load(imgUrl) .apply(RequestOptions.bitmapTransform(multiTransformation) .placeholder(R.drawable.glide_load) .error(R.drawable.glide_error)) .into(mImageView);
Actively clear the cache in the case of low memory, see the latest version of glide, its source code and processing the following related logic.
/**
- Execution at low memory
*/
@Override
public void onLowMemory() {
Log.d("Application", "onLowMemory"); super.onLowMemory(); Glide.get(this).clearMemory();
}
/**
- HOME key exits application
- Programs are executed during memory cleanup
*/
@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);
}
12. It is recommended to specify the width of the picture.
Glide Setting Picture Control Wap_content does not recommend support
Officially, wrap_content is not supported and recommended for imageview. Because glide doesn't know how many pictures to load for us, it's also reflected in its Sizes and dimensions. Ordinary ImageView is also good. If we put it in the Recycler View, because we don't know what the size of the target image is, we choose wrap_content, and scroll back and forth, it will lead to small bug s in the picture.
The official issue author replies as follows:
So, if you can, specify the width of the picture control.
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/gli...
01. Summary of blog links
1. Summary of Technical Blogs
2. Summary of Open Source Projects
3. Summary of Life Blog
4. Himalayan Audio Summary
5. Other summaries
02. About my blog
github: https://github.com/yangchong211
Knowing: https://www.zhihu.com/people/...
Brief Book: http://www.jianshu.com/u/b7b2...
csdn: http://my.csdn.net/m0_37700275
Himalayas listen to books: http://www.ximalaya.com/zhubo...
Open Source China: https://my.oschina.net/zbj161...
Days spent online: http://www.jcodecraeer.com/me...
Mailbox: yangchong211@163.com
Aliyun Blog: https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
segmentfault headlines: https://segmentfault.com/u/xi...
Nuggets: https://juejin.im/user/593943...
Amateur demo link: https://github.com/yangchong2...