New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Predefined item height before image arrives #1011
Comments
I think you're looking for this: #864 (comment) |
sorry but i'm a bit confused. My placeholder is just a gray color.
inside a LinearLayoutManager. |
When you are using the android:adjustViewBounds="true" don't use the scaleType. It will resolve your issue. |
@maheshwarLigade |
use the RecyclerView with WrapLayout Manager |
@maheshwarLigade |
Can you share your relevant (anything dealing with the imageview in the holder and layout) adapter code please? |
The layout of the item <?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
app:cardCornerRadius="0dp"
android:background="@color/light_gray"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/item_image_img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
tools:src="@drawable/image"
android:contentDescription="@string/img_content"
android:scaleType="fitXY" />
</android.support.v7.widget.CardView> and on bind item Glide.with(mFragment)
.load(image.getImageSrc(mScreenWidth))
.fitCenter().override(image.getWidth(),image.getHeight())
.placeholder(new ColorDrawable(mFragment.getResources().getColor(R.color.light_gray)))
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
if (android.os.Build.VERSION.SDK_INT >= 21){
String transition = Constants.TRANS_NAME + getAdapterPosition();
mImageView.setTransitionName(transition);
}
return false;
}
})
.into(mImageView); |
Wait, you said "it stretches the placeholder", how do you know it is stretched if it's a single color? Is there anything else interacting with the variable |
@TWiStErRob <android.support.percent.PercentFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/item_image_img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/img_content"
app:layout_heightPercent="100%"/>
</android.support.percent.PercentFrameLayout> PercentFrameLayout.LayoutParams layoutParams = (PercentFrameLayout.LayoutParams) mImageView .getLayoutParams();
layoutParams.getPercentLayoutInfo().aspectRatio = image.getWidth() / image.getHeight();
mImageView.setLayoutParams(layoutParams);
Glide.with(mFragment)
.load(image.getImageSrc(mScreenWidth))
.fitCenter().override(image.getWidth(),image.getHeight())
.placeholder(new ColorDrawable(mFragment.getResources().getColor(R.color.light_gray)))
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.into(mImageView); And no nothing else interact with the ImageView. How can i do that ? |
Through the layout system. Try to remove the extra layout params from ImageView to match @bryanstern's code, maybe they conflict. |
Tried that allready. |
How about integer division? ;) |
That did the trick. Now it works ;) Each item has the correct size but there are two issues. Firstly, fast scrolling is painfully choppy. It is ridiculous not be able to achieve a smooth scroll with different item heights using a RecyclerView. Take a look at the Facebook app. When viewing albums you can see different height images and the scroll is smooth as butter. No matter how fast you scroll. Secondly, first time image size is correct but if i scroll back again it has wrong height. |
@bryanstern / @montanax as people who admittedly made this work, do you have any ideas here? |
You're using If it doesn't help try removing most of your extras and see if a bare-bone works remove:
add:
|
I think the <android.support.percent.PercentFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--suppress AndroidDomInspection -->
<ImageView
android:id="@+id/item_image_img"
android:contentDescription="@string/img_content"
app:layout_widthPercent="100%"/>
</android.support.percent.PercentFrameLayout> // use float division
PercentFrameLayout.LayoutParams layoutParams = (PercentFrameLayout.LayoutParams) mImageView .getLayoutParams();
layoutParams.getPercentLayoutInfo().aspectRatio = (float) image.getWidth() / (float) image.getHeight();
mImageView.setLayoutParams(layoutParams);
// no need to override the height because the layout can determine this
Glide.with(mFragment)
.load(image.getImageSrc(mScreenWidth))
.placeholder(new ColorDrawable(mFragment.getResources().getColor(R.color.light_gray)))
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.into(mImageView); This is pretty much exactly what I'm doing for my adapter that provides images of varying heights, but a constant width to RecyclerView with a StaggeredGridLayout. This has worked really well for me (no stutters, etc...) |
Just refreshed and saw @TWiStErRob's post, which is pretty much my recommendation. |
What about
which I read as android:layout_width="match_parent"
|
@TWiStErRob / @bryanstern |
@TWiStErRob I think having both |
it didn't work at all. |
Did you use width or height percent, because it looks like he edited his comment. |
oops Yes changing the app:layout_heightPercent="100%" to app:layout_widthPercent="100%"/> FINALLY it works !!! |
Hmm, maybe Glide doesn't like the absence or the automatic values set by the percent layout. Try adding match_parent(s); or call |
neither match_parent nor layout(0,0,0,0) works... |
But you said it works with override... I guess you could use that. The only thing to be careful is that the resulting image size will match the override dimensions, so using the original size (for example 2304x1536 for digital images) is not recommended as it takes up too much memory on ALL devices. Try to calculate the grid width roughly (screen size / 2?) and calculate a nice fit based on the aspect to save some memory. |
by setting override it solves the issue of keeping the image there. Thats ok Also server returns resized images so there is no problem with memory. |
@TWiStErRob have you sloved this issue? I have the same problem. |
I made a sample app with Staggered Grid and pre-known image sizes: I think in your case the last thing missing might be: #864 (comment) |
@AngleV did you managed to figure this out? |
Yes using the following code layout code <FrameLayout
android:id="@+id/item_image_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/item_image_img"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:adjustViewBounds="true"
tools:ignore="ContentDescription" />
</FrameLayout>
inside adapter mImageView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, (int) (mScreenWidth / mItems.get(position).getRatio())));
Glide.with(mContext)
.load(mItems.get(position).getImage(mScreenWidth))
.override(mScreenWidth, mItems.get(position).getHeight())
.placeholder(new ColorDrawable(ContextCompat.getColor(mContext, R.color.light_gray)))
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(mImageView); it works perfect... Since i know all ready the ratio of each image... Never succeeded to tweak this so that to make it work perfectly smooth. |
Do you really need that override? I think the jumping is caused by mismatching sizes:
Try to remove it, as you already told Glide the size via layout params; or at least log the sizes to see if they always match. |
The reason that i am setting ovveride is that i am using endless scroll and as soon as user reaches the end of scroll and a new data comes in i noticed that without ovveride the last image of previous load flashes a little.. Using the ovveride i got rid of the flashing.... |
That flash probably means that the memory cache was not hit and it's reloading from disk. Try to double-check the numbers, I'm curious if they match. I suggest using |
Ohh nice advanced logging listener.... |
indeed number does not match... log reports
what i am doing wrong ? |
Hmm, try to check what you actually pass in to |
@TWiStErRob |
Try to replace |
i think that did the trick... |
Glide loads a source image (whatever the size) into a target. The target size is read from the view, or override. That param and size are both for the view. The image's (Bitmap's) size is right after the BitmapDrawable. You set the view size via layout params, so that was exact by the view framework. Since you're loading "perfect" sized images, I think you should use |
To be honest i do not fully understand how glide works. Too much science for me. All images are 4:3 ratio. it can be landscape or portrait. So my question is how should i fix my xml layout ? and on glide part... my goal is to display just a gray placeholder with exact size of each incoming photo and let glide do its magic and display the image. Whatever i do never get a perfect smooth scroll as for example instagram app has. Sorry about all these questions but by now i have tried everything... |
Any update on small jumps problem? I'm having a similar setup, though using I also tried I notice that the height and/or width of the bitmap returned by Glide sometimes mismatches the height requested by the |
Here's my solution that worked for me. There's no jumping while scrolling up or down. It requires you to set the aspect ratio of your imageView before loading with Glide. Here are some code snippets.
|
@maxwell10206 Does the solution really work for your? Would you please give us some explanations? Since it does not work in my case. I think, since you assign zero to ImageView's height and width, it totally doesn't show the images. |
@sajastu Are you using a Constraint layout as the parent view for the Imageview? The child views within a constraint layout with 0dp as their layout_width and height are actually equal to match_parent. You may want to study Constraint layouts and how they work first before using my code. |
I was trying to figure out how to do this with coordiantor without percent layout. I also wanted to have the progress bar circle centered where the image would take the space. This works for me:
You must set the layout params before you load the image with Glide
|
@kwong93 this is the final answer. Thank you very much. |
How should i set up Glide and my xml for each item if i all ready know the heights of images.
Until know i set my ImageView to wrap_content
That works fine but as soon as image arrives it stretches the placeholder and the scrolling jumps giving an awful experience to user
The text was updated successfully, but these errors were encountered: