I have a ViewPager of ImageViews, and I overrided the onDraw(..) of the ImageViews so that I draw stuff on top of the imageview. Throughout the run of the app I change these drawings so I manually call invalidate() to make onDraw() get called (and thus updating the drawings).
The weird thing is, the only onDraw() that is called is for the first ImageView and not the others. (Meaning only to the ImageView that is displayed first. After scrolling to the next ImageView, onDraw() stops being called)
I've called setWillNotDraw(false) in the constructor of the ImageView.
Did anyone have the same experience? Why is this happening?
One reason that the onDraw method may not be called for an ImageView is if you haven't set the image resource (i.e. ImageView src parameter) If you're setting it programmatically that would be done by a call to setImageResource. Make sure you're specifying the image resource properly and that the resource exists.
I discovered this issue making a custom control for displaying animated GIFs. For sdk < version 28, I used android.graphic.Movie to accomplish this, and for sdk >= version 28, I an using the new ImageDecode. In order to accomplish that my custom control had to be extended from ImageView. When I did that, my onDraw method no longer got called. The problem went away when I set the image resource. In the case when I using Movie to render the GIF, I'm not really using the ImageView for doing the rendering, but I still had to give Image view a dummy image resource just so I get a call to the onDraw method. The use of Invalidate and SetWillNotDraw(false) methods will not solve this kind of problem.
Related
I am changing a image in an ImageView while already displaying the image. This COULD leed to a change of the layout as the image may be of a different size.
I draw some arrows/marks to special points on an image and animate them... My problem now is, that I need to wait for the setImage... function of the ImageView to finish so that I can calculate all necessary data under consideration of the new image...
first update of image
On my first displayment of my view I wait with ViewTreeObserver().addOnGlobalLayoutListener of my ImageView and calculate all points afterwards...
on following updates of the image (view is already visible)
I don't know how to do it here...
How can I wait for setImage... to finish drawing and only afterwards do my custom work?
Try listening to the ImageView's layout change instead.
Call addOnLayoutChangeListener(...) on the ImageView.
You can recalculate the points every time onLayoutChange... is called.
Actually, I found the solution and it was quite obvious...
Exactly for this reason, view.post(...) exists and this works quite good... This way, I don't need the OnGlobalLayoutListener at all...
Is there any way to create a bitmap that, when you use it in on a view in the setImageBitmap method, it looks like no image was actually set at all?
EDIT: To clarify, I want the bitmap to not be visible, or it can be visible, as long as its nothing, as long as the user cant see it im happy.
EDIT2: I cannot use setVisibility because my ImageView also has a setBackground attribute that I want to remain visible. If I set the view to invisible, the background AND the bitmap image are affected, and I dont want that. I only want the bitmap image to be invisible.
You could call imageView.setImageBitmap(null) to remove the current image and keep the background.
You could make a 1x1 pixel bitmap which is nothing but empty canvas (in photoshop perhaps), then use the draw9patch tool to make it stretch.
EDIT: If you just need it not to draw, you can call setVisibility(View.INVISIBLE) on the view like so:
imageView.setVisibilty(View.INVISIBLE)
← Image is here
above is a 50X50 transparent image created in photoshop download and use it,
I am trying to achieve adding the animated gifs into my application.
1- I am able to download the animated gif from server. 2- I am able to decode the animated gif (using my custom decoder) and have a separate Bitmap corresponding to its frames.
Now I want to animate it using the frame by frame animation. As i read, to perform the frame by frame animation the first thing that is required is "animation-list".
I want to know how i can create the required "animation-list" programatically containing each Bitmap as a separate frame.
You can use AnimationDrawable similiar to http://androidforums.com/application-development/11620-programmatic-frame-frame-animation-examle-animationdrawable.html but use your own files instead of taken from resources.
Note that you have to be careful about density of screen and bitmaps which are downloaded rather than taken from resources otherwise it might look differently on different screen sizes/resolutions. More about it here: http://developer.android.com/guide/practices/screens_support.html see particularly "Scaling Bitmap Objects created at runtime" chapter
It's important to note that the start() method called on the AnimationDrawable cannot be called during the onCreate() method of your Activity, because the AnimationDrawable is not yet fully attached to the window. If you want to play the animation immediately, without requiring interaction, then you might want to call it from the onWindowFocusChanged() method in your Activity, which will get called when Android brings your window into focus
Context:
I have a main activity holding 6 tabs, each tabs holds a gridview with 30+ images, and around 8 images a shown at any moment (each gridview is scollable).
With these many images I implemented a simple caching system, that is to only cache the latest 25 of them, if new image is needed to display and is not in the cache, I will decode that image from /data/date directory and overwrite the oldest entry in the cache. And before overwriting the oldest entry, I will call Bitmap.recycle() on that.
Problem:
At some point, after displying more than 25 images, old images will start to be recycled. if I were to now navigate back to one of the tab where their Image is no longer in the cache, the GetView method will take care to load the picture again. The Issue is other than the first Item in the Gridview will be calling GetView, rest of the image will never get call, and the Gridview will attempt to display a cached image where it has been recycled already.
Any Suggestion? either to force get view or a smart way to cache image in this scenario?
Much Appreciated
Thanks
I kind of solved this by creating my own ImageView extending the Android ImageView. Then Overrided the onDraw(Canvas canvas) method and added logic to reload cache if cache is gone.
looks Hacky... but worked as wanted. really wish i cna do better than that if there is someone who can teach me. Thanks a ton!!
My application uses thumbnails downloaded from the internet. The thumbnails are generated by the server, and one specifies in the request what size the thumbnails should be. Is there a way for me to know, programmatically, while inside a ListAdapter's getView(), the dimensions of an ImageView inside the View that is returned, so my thumbnail comes perfectly scaled? I can always hardcode it, but I'd prefer not to.
Alternatively, is there some sort of listener or callback I can use to request the thumb once the View has been laid out?
EDIT: The ImageViews have fixed layout_height and layout_width, however, I'd want to reuse the same code for different parts of the app, which use different size images, which is why hardcoding is particularly bad.
You won't know dimensions at the construction phase of the ImageView in getView.
(obviously convertViews are different).
I have gotten round this by creating a subclassed ImageView that implements the View.OnLayoutChangeListener onLayoutChanged method and triggers loading of the image
via our resizer proxy (and via a local memcache). Whether this is the most elegant way, I don't know but it works. It all seems ugly compared to iOS!
See also:
Android: Finding size (resolution-wise) of a GalleryView.