I have an app which loads an image using the fresco library. I have 2 problems.
1. If I use the fresco image like this
<com.facebook.drawee.view.SimpleDraweeView
android:id="#+id/feedImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
it won't display anything but a thin line of colors where the image should be.
However if I do something like
<com.facebook.drawee.view.SimpleDraweeView
android:id="#+id/feedImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
fresco:viewAspectRatio="1.33"
android:scaleType="fitXY"
/>
everything is working fine(but I don't see the full image).
I want to achieve the same view as facebook(images full width and height).
I load the images in a list in a recycler. The images are loaded into cache(I verified that) but if I go all the way down and then back up I can see the images being loaded(facebook doesn't have this problem and they use the same library). If I scroll really slow there is no problem. I recently changed from volley and I did not have this problem before(so it's not the recycler). How can I solve this ?
Edit: And something else that I noticed is that if I disable the disk cache and kill the app the cache is not deleted as the documentation says. I know that if I call ImagePipeline imagePipeline = Fresco.getImagePipeline(); Uri uri; imagePipeline.evictFromMemoryCache(uri); the cache will be deleted, but shouldn't this be automatically ?
So for problem #2 I am not entirely sure I understand the problem correctly it isnt a problem at all. The image may very well be in memory cache, however the image stored in cache still needs to be decoded before it can be displayed on screen, which is probably that loading issue you speak of. The reason you only see this when scrolling through quickly is because the RecyclerAdapter that you are using is catching up to the scroll position.(this is an educated guess, by no means should this be assumed to be correct). When you move slowly and dont see the image loading is because the Adapter starts to load the next ViewHolder before it is on screen, but not much before that point. SO when you scroll quickly I believe it is simply the Adapter playing catching up with its OnBindViewHolder call, as opposed to moving through slowly it doesnt need to play catch up and has the image loaded before you reach the next item in the recyclerview.
The disk cache is not cleared when the app is backgrounded like memory cache, so if needed you will need to evict it.
I am not sure about issue #1 but I will try to find out why that may be. Maybe try setting the scaletype to CropCenter or something and see if that rids you of the lines.
Related
I have the problem with image loading in listview. I'm using Picasso to load pictures from network into my imageViews in each row. When I'm scrolling first time there always white background before image loaded in its place. Even if I scroll very slow or even stop scrolling before new item is showing, there still white background showing before the image is loaded. Even if these pictures wasn't taken from the network, but already from cache (yellow indicator). But when these pictures already in memory (green indicator) pictures don't loading each time when scrolling, they already loaded into imageView, so I don't have this white background (or it may appear on fast scrolling, but it's ok).
This how I use Picasso in my adapter:
Picasso.with(context).load(url).fit().centerCrop().into(imageView);
I know this is complicated topic and we can have OOM, but there should be some variants, as I can see it implemented in popular social networks, so I guess it possible.
P.S. fetch() doesn't helped me in this case, changing fit() with harcoded resize(200, 200) method also doesn't helped.
Please write your thoughts without silent minusing this post. Thanks!
Picasso.with("Pass Context") //
.load("Pass URL") //
.transform(new RoundedTransformation(5, 0))
.placeholder(R.drawable.*) //
.error(R.drawable.*) //
.fit() //
.tag(mcontext) //
.into("Your ImageView");
I have a huge image to render (1024x25373p) cut into 99 images of 1024x256p.
I have tried to use a ListView, but without success : it crashes when scrolling, whithout any error (exept one line saying the proccess was stopped).
So, my question is, how do I render this huge image ?
Please note that I have tried to use TileView by moagrius, without success (I can't get it to work with navigation drawer)
As a suggestion ,
If this is listview, you may not need such larger size images "1024x256p" .
Actual size of your imageView may much for less than that. So its a wastage of
heap if you try to load those images directly without some processing.
Definitly you need to do some scaling down for your image based on actual size that you need. Nice exapmple and code has been published on the official doc
You need to deallocate memory or clear the all bitmaps which are not visible on the listview for particular moment.
You can use progressing loader in order to load your images in to the listview. Then loading will be happen based on the scrolling.
Also you can define lager heap enable in your manifest though it is not recommended but has to do in highly memory consumable apps.
android:largeHeap="true"
I'm using Android-Universal-Image-Loader in a ListView of mine and I'm trying to find the best solution to following:
using resetViewBeforeLoading is necessary or else I get the same image in my ConvertViews, but this causes jitter, unless..
I use PauseOnScrollListener which is otherwise great, except that it shows a blank in some ConvertViews even for images that are already downloaded (I'm using memory and disk caches), so it's confusing to the user who sees a blank for an image they saw only 2 swipes ago
So it seems that I can't get an instant image load (for already-downloaded images) on scroll without jitter, even for images in memory, is this about right? Is there a better or more standard way to do this? (Vertical list-view showing screen-width images, sort of like the Instagram app, which does it buttery-smooth)
Otherwise, is there a way to lengthen the number of convertViews in my ListView to prevent unnecessarily aggressive re-use?
Thanks in advance
I am bulding up a grid of images for an app I'm building. It works like so:
Build up a list of Image IDs, which I must query using a different content provider each (these are images from MMS threads)
Create new activity, which hosts an ImageGridFragment. This fragment has a custom adapter that takes the grid of images, and loads each one as a bitmap asynchronously.
After images are loaded, they are cached in an LRU cache so I don't need to run unnecessary computation
So far, everything works quite well. However, I would like to pre-buffer images so that when the user scrolls down, s/he doesn't have to wait for images to load. They should already be loaded. The stock Android Gallery accomplishes. I've had a look at the source, but think there must be a more straightforward way.
To answer members' questions
Images are loaded one by one using the content://mms/part/xxx, where xxx is the ID of an image. These are MMS images, and to my knowledge, cannot be loaded as a batch process (though, maybe I'm wrong). I use a content provider in an AsyncTask to load each image
I've tried the following:
Pre buffer 30 images or so right when the fragment is created. This is not ideal because the massive I/O request, actually prevents the on-screen images from loading quickly (but the buffering does work well!)
Detect when the requested view to load is at the very bottom-right hand corner of the screen, which could work, but then would fail in the case that the GridView takes up only part of the screen. It also seems like there should be a cleaner way to do this
Thought about, but did not try, an OnScrollListener, but this will not pre-buffer images until I start scrolling, which is not ideal
So, my questions are:
Is there a good way to detect when the last GridView item is requested to load? I found that the GridView.getlastvisibleposition() method is not useful here, because it is actually returning the last element for which Adapter.getView() has been called for. If I can do this accurately, I can launch the buffer request at that time
Is there a better way to do this?
you can do right this
if(GridView.getlastvisibleposition() = mAdapter.count()-1)
how you load the images?
is it from URL or from sdcard?
are you using a image loader library?
Hi guys i am new to android and i posted a question a week ago in this link which basically stated that i was getting a java.lang.outofmemory error when i was using a lot of different backgrounds for my activities.
why am I getting errors when I use different backgrounds in xml
So as a new developer I have searched and searched for a solution as to how to clear the memory as i go from activity but none have been clear or precise. Then i stumbled across this site http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/
which described exactly what i was going through except they use 10 activities and i am only using 4. However when i implemented his code it my project i ended up with null pointer exceptions and after fiddling with his code I ended up back were i started with the same out of memory error.
So can anybody direct me to someone who can show me how to have as many backgrounds as i want with out running out of memory. Or does android as great as it is does not let you simply use more than a certain amount of backgrounds? help?
It's not that there is a limit on the amount of backgrounds, but each background image you load is a loaded into memory as a bitmap and held there until the activity is destroyed. If you are opening multiple activities one after another, each background image will need to be held in memory and so eventually you will get an out of memory exception.
If you set a large background image, you will also experience some blocking on the ui thread, while the image is loaded into memory.
One way around this that worked for me was to use an imageloader. This decodes the image off the ui thread, caches it on disk, loads it into memory and if memory is running low, will clear an image from memory and fallback to the disk cache. You may get a slight delay/fade in as the image is loaded but this is not so bad visually, and when loaded once, will load straight away if you go back to that activity.
Check out Picaso Picasso which is really easy to implement and a great api or Universal Image Loader.
My layouts were all RelativeLayouts and the first child (will be behind all other views) was an ImageView with scaleType centercrop and width and height set to match_parent. When each activity loads (onCreate), just grab a reference to the imageview in your layout and set the required background image using your ImageLoader of choice.
The other option is to have multiple copies of your background image in your resources, with each one resized to perfectly fit your resolutions of choice (drawable-mdpi/-hdpi/-xhdpi etc). This way, you ensure you are never loading images that are way bigger than you need to be displayed and your app will be more forgiving in terms of memory consumption.