Change view size to match drawn shape - android

Within the onDraw() method of the view, I paint a small line. When the view is dynamically added to my layout, it takes up the entire screen. How can I make sure the view is the size of my line that I drew?

In Constructor write this :
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(WidthOfYourLine,HeightOfYourLine);
this.setLayoutParams(lp);

Related

How to draw bounding box around face on frameLayout android

I have a frameLayout in xml:
<FrameLayout
android:layout_width="150px"
android:layout_height="200px"
android:id="#+id/preview">
</FrameLayout>
This preview is for displaying camera view:
mPreview = new CameraSurfacePreview(MainActivity.this, cameraObj,...);
preview.addView(mPreview2);
....
It successfully displaying face from the front camera. And I have the face rectangle x and y coordinates. How can I display a bounding box of face on the frameLayout?
Thank you.
well, you could use a ShapeDrawable, and set it's layout parameters to be the size and location you need, and add it to the FrameLayout along with your CameraSurfacePreview.
It's not all the difficult. First create a ShapeDrawable with the properties you want. Then set it as the background of a standard View object, and add the view with the layout parameters to size it how you want. So if you want the
ShapeDrawable sd = new ShapeDrawable(new RectShape());
sd.getPaint().setColor(0xFFFFFFFF);
sd.getPaint().setStyle(Paint.Style.STROKE);
sd.getPaint().setStrokeWidth(1);
View shapeView = new View(context);
shapeView.setBackground(sd);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(100, 100);
params.setMargins(left, top, 0, 0);
frameLayout.addView(shapeView, params);
In this particular case, i've made it a 100x100 view, so the shape will auto size to the view. and i've set it up so that it's offset from the top corner by the values left and top.
There's lots of ways to do this, but this seems the simplest. Of course you could do all this in XML too. There's lots of tutorials out there on how to do this.

Can't position child of RelativeLayout View without changing its size

If I try to set the top/left margins of the child of a RelativeLayout view so that the child view would appear partially off the right/bottom of the screen, the problem is that the view is shrunk in size and appears fully on the screen (which satisfies the top/left margins, but changes the size). I don't want the size to change.
I programmatically set the position of a child view of a RelativeLayout view by setting the top and left margins, something like this:
RelativeLayout.LayoutParams childViewParams = new RelativeLayout.LayoutParams(250,250);
childView = new ImageView(this);
relLayoutView.addView(childView);
childViewParams.leftMargin = somethingBigEnoughToPutOffRightHandSide;
childViewParams.topMargin = something;
childView.setLayoutParams(childViewParams);
If I set the top/left margins such that this child view should appear partly off left/top part of the screen, everything works as expected, no change in size, and the view moves partially off screen.
How can I specify the position of the view so that the size of the view is never changed, no matter the position, partially or fully off screen?
All that is needed is to also set the right and bottom margins to negative values exceeding the possible size of the view and the screen. Something like this:
RelativeLayout.MarginLayoutParams params = (RelativeLayout.MarginLayoutParams) someView.getLayoutParams();
params.setMargins(leftMargin,rightMargin,-1000,-1000);
someView.setLayoutParams(params);

Canvas in my View sets up as full screen dimensions, rather than View dimensions... why?

I have a class that extends View that I draw into.
In spite of the fact that the view is set up as a child to a RelativeLayout that has specific dimensions, the View's canvas reports that it is 1280 wide (which is as wide as the device).
I'm trying to understand what I need to do to have the canvas be constrained by the dimensions of its View (as common sense would dictate).
Curious what I'm overlooking... here are the relevant code snippets...
dv = new DrawView(this, getWindowManager());
dv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
//this wrapper is 500x500
((RelativeLayout)findViewById(R.id.drawWrapper)).addView(dv);
L.log("DRAWVIEW WIDTH = " + dv.getWidth()); //this reports 0... why?
inside DrawView...
#Override
public void onDraw(Canvas canvas) {
L.log("CANVAS WIDTH ON DRAW = " + canvas.getWidth()); //this always reports 1280 on xoom
this.canvas = canvas;
drawElementsOntoCanvas(canvas, true, false);
...
}
Is there something I'm overlooking or is the canvas inside a View always the width and height of the entire screen?
The XML for the relative layout:
<RelativeLayout
android:id="#+id/drawWrapper"
android:layout_width="500px"
android:layout_height="500px"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dip"
android:clipChildren="true"
android:background="#drawable/cut_out_frame"
/>
Ah, now I see it :)
You have clipChildren = true but this applies to the containing layout. Child views can draw outside the bounds of their parent but the drawing will simply be clipped to the parent dimensions.
It seems that here, you are using the window manager to construct your DrawView
dv = new DrawView(this, getWindowManager());
dv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
Without seeing the constructor, I am guessing that the subsequent setLayoutParams is using FILL_PARENT, i.e. the entire screen.
If I were you, I would implement the standard constructors for your DrawView and then lay it out in the layout XML. This is the "Android" way. You can also override onMeasure() to track how big DrawView is, storing the x and y in internal fields, which you can use to do any scaling you need. That way, if your layout every changes (orientation change, different resolution support, new version) your code doesn't need to change.
Finally, never (unless you REALL know why) use PX in layouts. Use DIP instead.

Android Custom View sizing

I am attempting to experiment in creating my own Views by subclassing "View." I want to simulate a new Button type class that will be drawn with the onDraw where I simply draw a rectangle from the canvas being passed in. I then add that custom View into the layout XML file, but I cannot control its size. For example, I set the width to "fill_parent" and the height to "wrap_content" but I don't know what the content of my View is. (BTW, the LinearLayout that my view is in is oriented to "vertical")
Can anyone give me some pointers in how to control the size of my View? For example, how does my custom view know what parameters were set in the XML file?
Android cannot detect the contents of your Canvas, so it assumes the contents are 0x0.
To do what you're looking for, you have to override onLayout or onMeasure (onLayout is specified by Android developers as a way to lay out children instead). You will also need a way to calculate the size of your contents.
First, start with a member variable called Point mSize = new Point(0, 0);. In a method other than onDraw, but called just as often, you will want to replace this with the size of your contents. If you draw a circle that has a radius of 25, do: mSize.x = 50; mSize.y = 50;.
Next, I'll introduce you to this answer (for onMeasure). It shows how to set the size of an item based on its parent's dimensions (divided by 2, in this case). Then, you can pull the size from mSize.x and mSize.y and apply those dimensions.
Finally, calling invalidate() after you measure your new mSize should force the View to lay itself out again, and adjust to your new parameters. This is the one part I'm unsure of in this regard.
NB: Also, you could call setLayoutParams using a fixed width and height once you calculate the size of your Canvas contents. Not sure of the performance implications for this, though.

TextView on Canvas

Is it possible to add TextView and ImageView on canvas?
Canvas does not inherit from ViewGroup, so it does not have the ability to add child views to it.
With Canvas, you use drawBitmap and drawText methods to draw images and text instead of adding child controls like TextView and ImageView.
It's a round about way, but this tutorial adds a textview to his canvas:
http://www.helloandroid.com/tutorials/how-draw-multiline-text-canvas-easily
If you need to freely position ImageViews and TextViews, you should use a RelativeLayout.
The RelativeLayout has advanced positioning features and allows overlapping.
- put your view (which is using canvas) inside the RelativeLayout,
public class YourComponent extends View{
#Override
protected void onDraw(Canvas canvas)
...
public void onDraw(){
....
....
ImageView yourImageView = .....
RelativeLayout.LayoutParams fParams = new RelativeLayout.LayoutParams(25,25);
fParams.leftMargin = 100; //x coordinate
fParams.topMargin = 25; /y coordinate
yourImageView.setLayoutParams(fParams);
((RelativeLayout) YourComponent.this.getParent()).addView(yourImageView);
}
}
above code : i created layout params which shows 25x25 dimensions for view. and after that , i used margins to set proper position on the parent layout. and set this LayoutParams to ImageView. and for last, i added this imageView to parent Layout.
But beware that during the onDraw() execution, calling operation on external view may stop onDraw(). so if you want to use this way be sure you already completed all onDraw operation.
I am not so sure why this happens. I did not try to observe too much on it yet.

Categories

Resources