How to get the middle of the screen for API>=19 - java

The button should move to the middle of the screen when clicked. But every time I get different position of button in different devices. And I don't know how can I fix it.
This code what I use:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
float middleScreen = metrics.xdpi;
final TranslateAnimation animation = new TranslateAnimation(0, -middleScreen, 0, 0);
animation.setDuration(3000);
animation.setFillAfter(true);
buttonToNextView.setAnimation(animation);

First of all, what DisplayMetrics.xdpi gave us is the exact physical pixels per inch of the screen in the X dimension which is not the number of pixels on the x-axis.
So, we should use half of widthPixels and heightPixels (based on screen orientation) to achieve the middle of the screen on the x-axis.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
boolean isDisplayPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
float middleScreen = isDisplayPortrait ? metrics.widthPixels / 2 : metrics.heightPixels / 2;
final TranslateAnimation animation = new TranslateAnimation(0, -middleScreen, 0, 0);
animation.setDuration(3000);
animation.setFillAfter(true);
buttonToNextView.setAnimation(animation);
Notice that to place the button exactly at the middle of the screen, you need to subtract half of its width from the middleScreen value.

Related

Android add buttons on image programmatically

I have an image inside of a Constraint layout, I want to programmatically add buttons to it, so it makes sense with the image. Imagine an image of multiple squares where each square should correspond with a button.
I let it scale the image so it takes up the entire width of the screen.
I know the pixel coordinates of where the button should be located but I'm having trouble placing them correctly on the screen.
I tried converting the pixel location to the location on the screen by getting the width of the screen to calculate the multiplier which should be the same horizontally and vertically as it keeps the aspect ratio. But it's off by quite a bit.
float mult = ((float) x) / ((float) SIZE_IMG.x); # x is the width of the screen
ConstraintLayout viewById = context.findViewById(R.id.constraintLayout);
ConstraintSet constraintSet = new ConstraintSet();
Button button = new Button(context);
button.setId(View.generateViewId());
viewById.addView(button);
constraintSet.clone(viewById);
constraintSet.connect(button.getId(), ConstraintSet.START, R.id.constraintLayout, ConstraintSet.START, (int) (mult * START.x));
constraintSet.connect(button.getId(), ConstraintSet.TOP, R.id.constraintLayout, ConstraintSet.TOP, (int) (mult * START.y));
constraintSet.applyTo(viewById);
X is found by
ViewTreeObserver vto = viewById.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
viewById.getViewTreeObserver().removeOnPreDrawListener(this);
int finalHeight, finalWidth;
finalHeight = viewById.getHeight();
finalWidth = viewById.getWidth();
yellowScoreBoard.initBoardOn(finalWidth, finalHeight, mainActivity);
return true;
}
});

setRotation change the ImageView position

In the code below, I'm trying to replace a sticker with an imageView keeping the same [Width, Height, TranslateX, TranslateY, and Rotation] of the sticker to give it to the imageView :
transX = selectedSticker.getTransX();
transY = selectedSticker.getTransY();
rotation = selectedSticker.getCurrentAngle();
ImageView mHoverView = findViewById(R.id.drawingView);
mHoverView.setLayoutParams(new FrameLayout.LayoutParams((int) stickerWidth, (int) stickerHeight));
mHoverView.setTranslationX(transX);
mHoverView.setTranslationY(transY);
mHoverView.setRotation(rotation);
mHoverView.setImageResource(R.drawable.dog);
mHoverView.setBackgroundColor(Color.BLUE);
When I click on REPLACE button to replace the sticker with imageView, everything works just fine, the problem starts when I rotate the sticker and clicks on the REPLACE button, the imageView takes the same rotation as the sticker, but it set in the wrong position (the imageView is not rotated around it center) :
e.g.
NO ROTATION :
WITH ROTATION :
Perhaps, you have to obtain correct translation values by re-calculating the transform matrix that is compatible to the View's transform.
//mHoverView.setTranslationX(transX);
//mHoverView.setTranslationY(transY);
Matrix m = new Matrix();
m.setTranslate(transX, transY);
m.postRotate(rotation);
float[] offset = { 0.0F, 0.0F };
m.mapPoints(offset);
mHoverView.setTranslationX(offset[0]);
mHoverView.setTranslationY(offset[1]);
The issue was I didn't set the PivotX and PivotY so the view is not rotated around the center, here's the full code :
float[] values = new float[9];
selectedSticker.getMatrix().getValues(values);
float dx = values[2];
float dy = values[5];
mHoverView.setPivotX(0.0f);
mHoverView.setPivotY(0.0f);
mHoverView.setTranslationX(dx);
mHoverView.setTranslationY(dy);
mHoverView.setRotation(rotation);
mHoverView.invalidate();

Android getDisplayMetrics() not returning accurate display size

I'm trying to get the pixel width/height of the device for placing elements and mapping touch events on the screen but not getting the desired effect (notice lower right square should be completely flush with the bottom right):
// screen size
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
float ScrDensity = metrics.density;
int metricHeight = metrics.heightPixels;//
int metricWidth = metrics.widthPixels;//
Log.i("AllMetrics", metrics.toString());
// temp
int rightButton_diameter = 100;
int rightButton_xpos = metricWidth - rightButton_diameter;
int rightButton_ypos = metricHeight - rightButton_diameter;
Where AllMetrics returns:
DisplayMetrics{density=2.0, width=720, height=1184, scaledDensity=2.0, xdpi=320.0, ydpi=320.0}
I notice that the returned height is also different from the 720x1280 listed in the Virtual Device Manager (API 19, Android 4.4) and the x/y positions of the touch events seems accurate to the drawn elements (ie the clickable area of the button is the same as where it is being drawn)
Is this a configuration error or am I using the incorrect method of fetching screen position?
Check this code it works for me
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
Outside of activity you can try this
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(dm)
To access the DisplayMetrics members, initialize an object like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

Getting the actual screen height (android)

I want to get the actual screen height of the device that runs my app. To achieve this i try the following:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int Height = metrics.heightPixels;
TextView HeightView = (TextView) findViewById(R.id.screenHeight);
HeightView.setText("Screen Height: " + Height);
int Width = metrics.widthPixels;
TextView WidthView = (TextView) findViewById(R.id.screenWidth);
WidthView.setText("Screen Width: " + Width);
The device that I run using the emulator has a screen width of 1080 pixels and a screen height of 1920 pixels. The width is displayed correctly (1080 pixels) but the height is according to the app only 1776 pixels. What do I need to make my app display the correct screen height? Is metrics.heightPixels a bad way of getting the screen height?
see this answer
if your API level > 13 try this if you are in activity
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
If you're not in an Activity you can get the default Display via WINDOW_SERVICE:
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
getWidth and getHeight is for API level 13 or less
UPDATE
For API 17 and higher method Display.getRealSize() returns full size of screen, as mentioned in documentation:
Gets the real size of the display
without subtracting any window decor or applying any compatibility
scale factors.
The size is adjusted based on the current rotation of the display.
The real size may be smaller than the physical size of the screen when
the window manager is emulating a smaller display (using adb shell am
display-size).
int width=Resources.getSystem().getDisplayMetrics().widthPixels;
int height=Resources.getSystem().getDisplayMetrics().heightPixels;
I needed to get the actual available height, and out of all the options this is the only thing that worked for me.
Create a rectangle, and get its dimensions:
Rect r = new Rect();
activityRootView.getWindowVisibleDisplayFrame(r);
int screenHeight = r.bottom - r.top;
where activityRootView is the root view of your layout.
If you need to extract the toolbar height:
int availableScreenHeight = screenHeight - toolbar.getHeight();
where toolbar is your toolbar view.
availableScreenHeight will now be without the statusbar, without the toolbar, and without the navigation bar (if the device is using it).
you can use this code:
val display = windowManager.defaultDisplay
val size = Point()
display.getSize(size)
val width: Int = size.x
val height: Int = size.y
You can try this:
WindowManager wm = getWindowManager();
Display d = wm.getDefaultDisplay();
Point size = new Point();
d.getSize(size);
Log.i("LOG", "W=" + size.x + " , H=" + size.y);

Sprite size for all devices

How to set Sprite size for all device? i am using this for sprite :
final Display display = getWindowManager().getDefaultDisplay();
CAMERA_WIDTH = display.getWidth();
CAMERA_HEIGHT = display.getHeight();
Log.e(Integer.toString(CAMERA_WIDTH), Integer.toString(CAMERA_HEIGHT));
camera = new BoundCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
facebook = BitmapTextureAtlasTextureRegionFactory.createFromAsset(
this.mBitmapTextureAtlas, this, "facebook.png", 0, 0);
mHardware1[active] = new Sprite(pX, pY, facebook,
this.getVertexBufferObjectManager());
but when i run game on devices with smaller screen, the sprite size remains same. How to overcome this?
Try using the "dp" unit on your sprite size. if you're using "px" it will not scale on other devices.
Please read this link for more details :)
The answer give by #Siddharth in the comment is correct. In AndEngine, you are not supposed to scale Sprites to fit screen sizes yourself. Instead you should use built-in AndEngine functionality to scale the whole scene accordingly.
#Override
public EngineOptions onCreateEngineOptions() {
final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
camera.setCenter(0, 0);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_SENSOR, new RatioResolutionPolicy(.CAMERA_WIDTH, CAMERA_HEIGHT), camera);
}
Now when you set CAMERA_WIDTH and CAMERA_HEIGHT, to 1280x720 and your Sprite size is 640x360, AndEngine will scale the whole scene up or down including your Sprite on any screen to 1280x720. Your Sprite will always take one quarter of the screen.
Replace
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT)
with this
new FillResolutionPolicy()
with FillResolutionPolicy you only need work in one dimension and it automatically this resize for all devices

Categories