How I can determine if a view was invalidated? I see that the View class has isDirty() method but it doesn't seem to work in my case.
I'm making a custom layout that can animate blurring of it's content. It extends FrameLayout. So at first the layout draws it's first child to a bitmap, and than displays the bitmap instead of actual view. Also it starts AsyncTask that creates blur animation steps.
So I need to know when the child view was changed so I can redraw the bitmap and restart AsyncTask.
I've found that this can be implemented using ViewTreeObserver.OnPreDrawListener
Related
I was trying to understand what's the meaning of inflating a view and found this topic:
What does it mean to inflate a view from and xml file?
But I was not satisfied by the accepted answer, as it mention that inflating a view causes its rendering, while I think it is only responsible of the conversion of the XML layouts into the corresponding code by building the View objects, and I'm wondering if it's the case or not, and if not, what can initiate the drawing of the view on screen?
Can anyone clarify my questioning by providing trusted or official documentation?
Every subclass of View overrides the onDraw() method from the View class. This is where the View actually specifies how it will be drawn on the screen. All drawing takes place on the View's Canvas, and the dimensions of the Canvas are specified by the width and height attributes you set in your layout file for that View.
For instance, here's the onDraw() method for TextView:
https://android.googlesource.com/platform/frameworks/base/+/jb-mr0-release/core/java/android/widget/TextView.java#4738
I have created a class that extends a view which will work as a drawing slate to draw a text. I want to add that drawing slate in image View. And I have main activity which contains a scrollable list on top and a image view below list. Now I want to add that View(Drawing slate) on image View. So how to implement this? I tried lot, but I am not getting how to do this.Do i need to use any other view instead of image View? Please help as soon as possible. Thanks in advance.
just extend ImageView and do your drawing in onDraw method, make sure you call super.onDraw()
I have an FrameLayout which contains many child view. Each child view implements the onDraw() method to draw some shapes it maintains. Whenever I change something on a child view, I see that all other child-views will be invoked to re-draw itself. This makes the application runs slowly. Is there any way to re-draw only current child-view?
I have a layout which contains a ScrollView which contains various components including an ImageView. I've found that I can add a TouchListener to the ImageView and the x,y values I get for the event are offset from the corner of the ImageView (including padding). Thus I can easily handle touch events without worrying about the state of the ScrollView.
The problem is that I don't see a way to add a view on top of the ImageView so that I can make a visual change to the ImageView when it's touched in certain locations.
Specifically, there are various boxes in the image which I'd like to highlight when they're tapped. I can add a view to the activity, but I'd have to take the state of the ScrollView into account in order to display things in the right spot.
What's the best way to approach this? Can I derive a new version of ImageView, overload the draw method, and use that somehow? (not sure how I'd specify it in the xml, I'd probably need to set it in the onCreate of the activity)
You should be able to override the onDraw method of the ImageView as you suggested and draw stuff on top of the ImageView. The onDraw method gives you the Canvas that you could draw on. In the XML, you could just use the name of the new class you created instead of "ImageView" (unless you want to add parameters in addition to the ones offered by ImageView, this should be pretty straight forward).
<your.new.awesome.class.with.the.full.namespace
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/awesome_image_view"
/>
The problem is that I don't see a way to add a view on top of the ImageView so that I can make a visual change to the ImageView when it's touched in certain locations.
It seems that you are more comfortable with having a separate view that you could work on. You could do that by encapsulating the ImageView with a FrameLayout and then adding another view of any kind as a sibling of that ImageView. This view would be drawn on top of the ImageView if it was mentioned in the FrameLayout after the ImageView. This solution may not be the most efficient one, but it might get you started. Overriding the onDraw method of the ImageView would definitely be the best option.
you can make a relativelayout or something with a background as your desired image instead of having just an imageview. then you can have child views within that relativelayout.
i have the following problem.
I am working with a library of maps which paints the icons on the map using drawables and canvas.
Now, i'm trying to modify it in order to the user can click on icons. So i want to attach drawables into different ImageView with a onClickListener.
However, i don't know how i can paint the ImageView using canvas from method onDraw.
I've tried with:
ImageView iv = new ImageView(context);
iv.setDrawableResource(drawable);
iv.draw(c)
But it doesn't appears in screen.
Any idea? Thanks
You might have better luck if you provided more context -- what's "c" represent here? But in any case, you can't just create new imageviews, you need to attach them to your layout, either by inflating them with a parent view argument from XML, or calling your parent layout's addView() programatically.
Generally, you'll rarely call any draw() methods by hand (unless you're implementing a custom view of some sort); you'll inflate your views from XML into your layout, or else instantiate your views, set whatever LayoutParams you need, and add them to a layout. The Android UI libraries handle figuring out when standard views are invalidated and need to be redrawn, for performance reasons and your own sanity.