I have a ViewGroup with several children, and I want to be able to get the bitmap of the view group itself, before any of its children are added. I need it because I want to rotate the bitmap without affecting the children. Is there any way to do that? Thanks.
Don't add the Bitmap until after View inflation is done. In other words, if it's in the xml layout, take it out and do what you need in Java.
EDIT: in light of your comment.
Get the ViewTreeObserver, like so:
ViewTreeObserver theObserver = viewGroup.getViewTreeObserver();
Then add whatever listener you need to the ViewTreeObserver.
I found out that the onDraw function actually handles only the drawing of the view itself. The children, if exist, are handled in a later stage of the drawing process, so I can do all the bitmap manipulations there.
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'm currently trying to design a ViewGroup (specifically a subclass of FrameLayout) that can layout any number of subviews and enable them for drag/drop outside the layout group. It's almost identical to a LinearLayout:
Curently I am able to drag the views outside the ViewGroup and draw them, however after letting go of the view it can't be re-selected and further dragged around.
I'm wondering if there is a way to do this in a way that isolates the logic to the Layout subclass and doesn't involve needing to do much/any extra stuff in consuming fragments/view groups.
I've tried overriding getHitRect(Rect) in my FrameLayout subclass but it never seems to be called. dispatchTouchEvent(MotionEvent) is of course not called either, presumably because the parent ViewGroup has decided not to deliver the touch to it because it was outside the bounds. I've tried implementing a TouchDelegate as well, but I think that needs to be set on the parent view, which means needing to know about this and doing this additional step when using this Layout.
Any ideas on if/how this is possible? On iOS it can be implemented fairly easily by overriding hitTest: to take into account the frames of the child views. Is there a similar method like this on Android?
Your help is greatly appreciated!
Without any code it is very hard to see what you are doing, but best guess would be that each view should a child view of the relative layout.
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
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.