android position TextView on "fixed" position on image - android

I'm trying to display values that a user enters on an image, there are 4 versions of image (ldpi, mdpi, hdpi and xhdpi).
I want to position the textViews on a "fixed" location that adjusts to the right screensize.
Has anyone got some advice on how I could achieve this?
Here is a sketch of what I'm trying to do.
http://dl.dropbox.com/u/251053/stackoverflow.png
edit
Thanks for the fast responses.
Uploaded a new image, this isn't possible with relative layout I guess?
http://dl.dropbox.com/u/251053/stackoverflow1.png

Look at the "RelativeLayout" documentation: http://developer.android.com/reference/android/widget/RelativeLayout.html
You will be able to put your textView around your ImageView.

The best way to solve this I think is to create a custom layout that expects the ImageView as its first child.
All the other children will be the TextView's that you can either:
position relatively to the position of your ImageView
position proportionally to the height/width of your parent custom layout that matches the height/width of your ImageView
The left/top position information of the child TextView's can be given through a custom LayoutParams class that suits your needs.

I think the best way is to create a custom view by extending View class. It is not so complicated as it may look. Here you can find more info about custom UI components.
The main idea is to override onDraw(Canvas canvas) and onMeasure(int widthMeasureSpec, int heightMeasureSpec) methods.
In onMeasure you should return the dimensions of your view and also you may calculate the size and angle of the rectangle and also the size of text you want to draw. Or you can implement custom resize() method that will be called explicitly on you view from the activity and make text and image calculations.
When you know all the measurements you can position and draw both image and text in onDraw(Canvas canvas) method.
#Override
protected void onDraw(Canvas canvas) {
myImageDrawable.setBounds(0,0,50,50);
myImageDrawable.draw(canvas);
canvas.drawText(myText, 10, 10, myTextPaint);
}
You can find more info about Canvas class here.
Also you may use StaticLayout to measure text.

Related

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.

How it is possible to stretch the image manually to our required pixel position

How it is possible to stretch the image manually to our required pixel position.in my android application i want to stretch my image to the specified position by dragging the end points of it.can anybody suggest me how to do this............
You can use an imageview with the attribute
android:scaleType="fitXY"
This will make the image to fit the bounds of the imageview.
To modify the image on click or touch, you will need add a ontouchlistener to the view. And on the based on the view getTop and and getLeft, you will need to set the layout params of the view to increase or decrease the size.
Or you will need to extend a view and override the onDraw method, in that method you can use the canvas.drawBitmap method to specify the size of the bitmap.
Either way you will need to use the onTouchListener.

Drawing custom view using Android

I am drawing a custom view in my application which basically takes arguments(XML) as the text to display and then keeps on rotating it infinitely.
While I was making this control I had a few doubts which I want to ask:
I have made 2 of my stylable attributes which I have declared in the attrs.xml file. These attributes are to set the width and the width of the circle used in my control. These values I would use in the ondraw method and the onmeasure method. I ran my program by declaring just these but there was an error which asked me to put android:width and android:height attributes. My question is why would I need those if I am already using my custom attributes to define the height and the width of my view
I am coding on a mac. Now when I was making my attrs.xml file, to get the autocomplete list which we usually get by ctrl+space was not showing up. Why is that. For e.g., i wanted to know what values can I give the format attribute of my custom attribute that like I am demostrating in the following:
<attr name ="somename" format="value I wanted to find out through autocomplete"> . Why is the autocomplete not popping up? It does pop up when I am making a.java file.
In my ondraw() method I wanted to draw a circle. Now for this I would require the co-ordinates of the center of the circle. So what I do is put 0, 0. But this is not correct. I want the circle to be at the center of the parent view it is in. So if my view is in a hierarchy I want it to respect that. I want to give the co-ordinates relative to the parent view. What is happeining right now is that it is being drawn at the top left corner of my screen. This is what I don't want. What do I do to achieve this?
why would I need those if I am already using my custom attributes to define the height and the width of my view?
This is because Android needs to know how and where to put your view in the layout. You can implement your view to make use of your custom height/width requirements by overriding View.onMeasure() to return your own size parameters. You can then just set android:layout_width="wrap_content" android:layout_height="wrap_content" in your layout file.
Why is the autocomplete not popping up? It does pop up when I am making a.java file.
Autocomplete and autodoc implementation for Android xml files is shaky at best, so it's not really surprising that it doesn't work. I'm not aware of a fix and AFAIK it's an IDE bug.
In my ondraw() method I wanted to draw
a circle. Now for this I would require
the co-ordinates of the center of the
circle. So what I do is put 0, 0. But
this is not correct. I want the circle
to be at the center of the parent view
it is in. So if my view is in a
hierarchy I want it to respect that. I
want to give the co-ordinates relative
to the parent view. What is happeining
right now is that it is being drawn at
the top left corner of my screen. This
is what I don't want. What do I do to
achieve this?
If you implemented onMeasure() correctly, the coordinates relative to parent should be taken care of already. To get the center of your view use the following code:
void onDraw(Canvas canvas)
{
int centerX = this.getWidth() / 2;
int centerY = this.getHeight()) / 2;
//..draw code here
}
Edit
Here's an example with source code that should help: http://mindtherobot.com/blog/272/android-custom-ui-making-a-vintage-thermometer/

Android - Square TableLayout

I have a need to create a perfect square TableLayout. The table is a grid of equal sized objects. The problem here is that in landscape layout, the table should take up the maximum amount of space but nothing more. In other words, I need the width of the table equal to the maximum height allowable. An ad appears ~10 seconds or so after the activity starts so that also adds to the complexity.
Here is what I've tried so far to accomplish this:
I created a invisible view that was aligned horizontally center. I then aligned the right side of the table to this view. This works but for some devices, the screen ratio doesn't make this setup perfect. On devices like the droid, the bottom row is squinched in because the table width is smaller than the height.
I created an ImageView with adjustViewBounds set to true. I sourced it with a very large square image. I have it set to be above the adView and align top and align left. I then set the table layout to align to the bounds of that ImageView. This didn't work because it was a memory hog and the image bounds never fully adjusted when the ad popped up. The image source would go to a smaller scaled square but the right bound never adjusted to the new bounds.
I think this could be very easy if I made a custom class of the TableLayout and set the tablewidth = tableheight. I am struggling with this idea because I don't know where all I would need place the necessary logic. I suppose I would need to add it when the table gets initially drawn and again when the Table adjusts after the ad moves into place.
Can someone help with some sample code on the TableLayout class? Is there another way to do this?
Update 3/30 9:05PM PST
I've made some progress with a custom TableLayout class after looking through the suggestion from CommonsWare. I'm closer to achieving the solution using this class but have one left thing to solve. The new TableLayout doesn't adjust it's bounds so the width is still taking up additional space even though the contents are sized correctly. The width looks to be set when there isn't an ad and it never changes after that.
Here is my really simple extended TableLayout class. Note the onMeasure method where I set the width and height both equal to the height:
public class SquareTableLayout extends TableLayout {
public SquareTableLayout(Context context) {
super(context);
}
public SquareTableLayout (Context context, AttributeSet attrs) { super(context, attrs); }
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
}
}
Here is a screenshot of the problem. I added apurple background to the TableLayout to highlight the problem.
http://ribzy.com/images/tile_takedown_landscape.png
TableLayout cannot accomplish what you seek, for the reasons you have determined. There is no built-in layout that has the notion of tying width and height together. Most likely, you will need to create a custom layout manager from scratch, like this one.

Custom view object using up full height of screen even when layout_height is set to wrap_content

I created an object that extends android.view.View, overriding draw() and have it displaying on the screen. To put you in the picture, it is a display of digits to represent a game score. It's displaying correctly horizontally, however, it is taking up the full height of the screen - pushing all other elements off the screen.
I've put layout_height="wrap_content" in the xml, but it has no effect.
Does anyone know what I am doing wrong?
I've figured it out...
I was supposed to override onDraw() but that wasn't what caused the problem.
The main thing was, I needed to override onMeasure() like this:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(DIGIT_WIDTH * getNumberOfDigits(), DIGIT_HEIGHT);
}
DIGIT_WIDTH and DIGIT_HEIGHT are constants set to the dimensions of each digit image I used. getNumberOfDigits() is just a getter for a custom property set from the xml attributes.
Hope that helps anyone else coming across this.

Categories

Resources