Is there a way to get a RectF of the Android Device Screen Bounds? I'm trying to scale my Path to a RectF that is the exact screen size. I tried
int width = Resources.getSystem().getDisplayMetrics().widthPixels;
int height = Resources.getSystem().getDisplayMetrics().heightPixels;
screenBounds.set(0,0,width,height(;
Doesn't actually work. I've tried getDrawingRect() on my View that is match_parent and match_height but it did nothing.
Related
I'm trying to create the control, that allows moving view with the finger. To do this, I follow recommendations from this post.
But presented method needs some modification, to prevent my view from being moved beyond the screen. I found out how to get maxY and maxY coordinates - for my Samsung Galaxy A6 it's 1080x1920. But the problem is, that my maxY is deep beyond the visible bottom edge of the device.
So my control almost disappears, when reaches Y about 1650. What 300 more pixels go for. I can suppose, that this is NavigationBar height + my control view height, but this also doesn't place my control as expected.
I define max coordinates with this method.
private void setMaxCoordinates(int viewWidth, int viewHeight) {
Display display = getWindowManager().getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
maxX = displaySize.x - viewWidth;
maxY = displaySize.y - viewHeight;
}
Please, help me to define the correct formula to detect bottom edge coordinate.
I've found a solution. First of all I was wrong with getting bottom coordinates with the help of WindowManager. This just gives you height of your screen in pixels, that is not related to the container. So to detect your bottom coordinate this way, you have to consider:
StatusBar height.
NavigationBar height.
Height of all views that lokated higher, then your container.
Height of your own control view (ImageView in my case).
So formula will look like this.
maxY = windowHeight - (statusBarHeight + navBarheight + allUpperViewsHeight + yourViewHeight)
The correct way to define the bootom of your container, is to get the container's height and deduct your control height.
maxY = containerHeight - yourViewHeight;
I'm having a small issue with my android code . This is the first time i'm using canvas and i want to set an image to it but keep some type of aspect ratio.
This is what i'm doing right now and this maps the image onto the canvas completely . It sets the image width-height to canvas width-height.
Drawable drawable = image; // gets the image
drawable.SetBounds(0, 0, canvasWidth, canvasHeight);
drawable.Draw(canvas);
This works well on certain devices but when the device is large , the stretching is really bad . I want to set the bounds in such a way that it keeps an aspect ratio . If the canvas width-height is not the same aspect ratio , it will try to fill the canvas with an aspect ratio but might leave some space off in x or y axis .
int imgWidth = 500;
int imgHeight = 800;
I want to map the image on the canvas based on these values and stretch as necessary but keeping this aspect ratio even if part of the canvas is not filled .
What is the best way to do this ?
Thanks
I've already answered a similar question here.
To preserve the aspect ratio I did this:
val drawable = resources.getDrawable(R.drawable.my_vector, null)
val aspectRatio = drawable.intrinsicWidth.toFloat() / drawable.intrinsicHeight
val desiredWidthInPx = 100 // could be your view size or canvas size
val derivedHeightInPx = (desiredWidthInPx / aspectRatio).toInt()
drawable.setBounds(0, 0, desiredWidthInPx, derivedHeightInPx)
drawable.draw(canvas)
The above is for when the drawable width is smaller than its height.
If the drawable height is larger than its width, then first set the height to your desired size and then calculate the width.
Provide correct images in each resource folder. Correct images means correct resolution and screen density. Refer to this link http://developer.android.com/guide/topics/resources/providing-resources.html
I'm trying to make a bounding rectangle around an ImageView for collision detection. Unfortunately, I can only find code for sprites and not ImageViews. Is there a way to make a rectangle that goes outside of an image for an ImageView? One of the ImageViews moves through animation while the other one stays still.
Using imageViews for move animation isn't best idea. It takes too many resources. However you can set width and height of imageView to WRAP_CONTENT and use sizes of ImageView as bounding rect
In your xml layout set android:layout_height and android:layout_width of your ImageView to "wrap_content". And when you need bounding rect of ImageView:
...
int[] l = new int[2];
imageView.getLocationOnScreen(l);
int x = l[0];
int y = l[1];
int w = imageView.getWidth();
int h = imageView.getHeight();
...
x, y, w ,h — required bounding rect in screen coordinates
I have a live wallpaper all set up (for simplicity's sake, assume it consists of two rotating bitmaps positioned side by side, each rotating at different speeds; also note that the bitmaps' edges (not the invisible box around the image, but rather the actual pixels of the drawing) are touching.)
I described the translate for each as a percentage of the canvas size (a value between 0 and 1 multiplied by c.getHeight(), and c.getWidth() (where c is a canvas).)
Anyways, everything works fine as long the aspect ratio is maintained. So xxhdpi and xhdpi # 1080x1920 and 720x1280 is all good, but then when i run it on a nexus s # 480x800, the two bitmaps are no longer positioned properly.
I do not want to distort my images (they are circles and must remain circles), so I was thinking the best way would be the limit the size of the canvas and center it.
So for the nexus s # 480x800, i would actually want to only draw in a 450x800 area which i would center on my screen.
In fact, I would always want to have my 2 bitmaps in an area respecting the height = width * 0.5625.
How should I go about doing this?
NB: I based my live wallpaper around the cube sample.
Please let me know if I left any important details out,
Thank you!
Werner
inside your Engine, implement following to capture the screen's height and width
int screenHeight, screenWidth;
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
screenHeight = height; screenWidth = width;
}
and wherever you decode your bitmap, do it like this:-
//get bitmap
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap);
//scale bitmap
bitmap = Bitmap.createScaledBitmap(bitmap, screenWidth, screenWidth * 0.5625, true);
This will fill your entire screen with a circle of correct aspect ratio (width * 0.5625).
And then make it centred by:-
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
final SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = holder.lockCanvas();
int x = ( screenHeight - screenWidth*0.5625 ) / 2;
canvas.drawBitmap(bitmap, 0, x, paint);
I am using a Nexus 7 1280x800 android 4.2.2 API 17
I want to get the size of the screen to divide it in square sections of the same height and width.
I am using FrameLayout and my squares are subclass of ImageView.
I do this
context.getResources().getDisplayMetrics().heightPixels; ----> 1205
context.getResources().getDisplayMetrics().widthPixels; ------> 800
I suppose 1205 is not 1280 because there are two Android menus on top and bottom of the screen.
Each of my squares is 30x30 px.
To know how many squares I can draw as maximun I do:
int x=1205/30;
When I try to paint my image on coords (x-1)*30 ,y it is drawn partially out of the screen.
How can I know the portion of screen my application can use?
I hope I explained well my issue.
Many thanks.
If all the squares are in the same ImageView, then I would guess that the easiest way is to create your own imageView:
class MyImageView extends ImageView {
Context context;
int myWidth = 0;
int myHeigh = 0;
int numBoxesX = 0;
int numBoxesY = 0;
private final int boxWidth = 30;
private final int boxHeight = 30;
ImageView(Context c) {
super(c);
context = c;
}
}
In the class, you override the onSizeChange function
#Override
protected void onSizeChanged (int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
myWidth = w;
myHeight = h;
// Set up other things that you work out from the width and height here, such as
numBoxesX = myWidth / boxWidth;
numBoxesY = myHeight / boxHeight;
}
On then create a function to draw the box:
public void drawSubBox(int x, int y, ...) {
// Fail silently if the box being drawn doesn't exist ...
if ((x<0) || (x>=numBoxesX)) return;
if ((y<0) || (y>=numBoxesY)) return;
// Your code to draw the box on the screen ...
}
Once you have created this View, you can add it to a layout, and access the functions for it just like any other view, including any you add to define the size of the subboxes etc etc. So in the class for the Activity with this layout
MyImageView miv;
miv = topView.findViewById("idforMyImageViewSetInLayoutXMLfile");
miv.drawSubBox(0,0, ...);
As to finding out the pixel dimensions of the screen I think you are correct. heightPixels and widthPixels will give you the absolute pixel dimensions of the screen you are using. Just something to be conscious about - I'd be worried about using px as the base measurement since the results will change depending on the density of the screen. It seems like a much safer idea to use dp and after finding the absolute number of pixels in the screen, scalling that number by the dpi so that the rectangles draw the same on every phone. Also the absolute pixel value does not represent the actual free space just the total number of pixles.
Oherwise I don't know that the math works out for this layout to fit on the screen perfectly. x = 1205/30 = 40.166667. Plugging that number in (x-1)*30 = 1,175. Assuming that the x direction on your phone does in fact include 1205px (#JRowan - it could be landscape) adding 30px would seem to make these rectangles fit on the screen. However, this only works if there is no boarder or offset between any of the rectangles. Using the numbers you provided there is only 4.8px of leeway across the 1205px width of the screen. With 40 rectanlges in that space, even a thin boarder would push the drawing off the screen.
I just solved the problem while wondering about margins.
The key is the title bar, which is actualy part of the application screen, but out of the drawing screen.
If I delete the title bar it works perfectly.
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
I spent two days with this and found the answer just now doing the correct question. I leave here links to the posts where I found it.
How to increase the size of the title bar in an Android application?
Height of status bar in Android
Thanks for the answers.
If the grid is in a fragment then the issue is getting the usable screen size before the fragment's view is inflated. In a similar scenario, I got the width and height of the fragment container in the hosting activity and passed these as parameters to the fragment with the grid