Generating non icon images - android

I want to add image resources to an Android app that won't be used for icons. I wanted to know what is the right way of doing it while supporting multiple device screen sizes. The only solution I can think of is resizing the image to different pixel (width, height) combinations and storing them in their appropriate drawable folders.
For images that are icons, I use the Android studio image asset tool to automatically generate different sized icons. I want that for images that are not icons(won't be placed in the toolbar and similar places).
Solution that worked for me
Used Android Asset Studio, Generic Icon Generator
to generate the resource images for the different device resolutions.

I think you can try this:
Create folder drawable-nodpi and put your images inside it.
Use this code to find the width of the device:
public static int getWidth() {
int width = 400;
try {
WindowManager wm = (WindowManager) DataBackApplication.getInstance().getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if (Build.VERSION.SDK_INT > 12) {
Point size = new Point();
display.getSize(size);
width = size.x;
} else {
width = display.getWidth(); // Deprecated
}
} catch (Exception e) {
e.printStackTrace();
}
return width;
}
Build your layout.
Load image using this code:
int width = getWidth();
int imgWidth = width/6;
int imgHeight = width/9;
Glide.with(PermissionActivity.this)
.load(R.drawable.privacy_mobile_img)
.override(imgWidth, imgHeight )
.into(imgUserPerm);
Use Glide to load the image because it will resize it for small, mid, or any size device. I used width / 6 as an example, you can adjust as needed.

Related

Does getSize() in Android include the height of the status bar?

Is there a way to tell if getSize() includes the height of the status bar? From testing on a few different phones it seems it does on some but not on others and it is frustrating when trying to make everything in the layout line up properly.
After spending a week on this problem and checked Google's documentation & many other posts here on Stackoverflow (about getting the screen size in pixels via getSize(), getRealSize(), getMetrics(DisplayMetrics metrics), getRealMetrics(DisplayMetrics metrics), etc ... I still have no clue about it.
This picture is giving a better picture of the problem.
On some phones and according to the above picture, the line 'Y/2' should be exactly at size.y / 2 (exact half of the screen between the navigation & the status bars), but is actually not in the middle : The 'Not X' distance on my picture is therefore equal to 'X - getStatusBarSize()'.
I have to add that i am using a ring object with an innerRadiusRatio 2.1 in XML.
But i don't think it's the reason because once i am using the code below, it works on phones where getSize() seems to include the height of the status bar :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Screen dimensions
display = getWindowManager().getDefaultDisplay();
size = new Point();
display.getSize(size);
//Get the screen dimensions
maxWidth = size.x
maxHeight = size.y - getStatusBarSize();
}
private int getStatusBarSize() {
Resources resources = getResources();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
return 0;
}
While it works simply with maxheight = size.y on others phones (where it does not include the status bar height).
Thanks in advance guys for any help !
I was facing to the same issue more or less and this could be helpful :
// Get the size between the status & the navigation bars
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
// Real size of the screen (full screen)
Point realSize = new Point();
Display realDisplay = getWindowManager().getDefaultDisplay();
realDisplay.getRealSize(realSize);
//Get the screen dimensions
maxWidth = size.x;
maxHeight = size.y;
if (realSize.y - getNavBarSize() == size.y || realSize.y == size.y) {
Log.d(TAG, "onCreate: getSize() includes the status bar size");
maxHeight = size.y - getStatusBarSize();
}
I've had the same question and this is how I solved it.
Display.getSize() only sometimes includes the status bar height.
For the solution with .getRealSize() you also need the navigation bar height.
With the following solution you don't need the navigation bar height:
View contentView = requireActivity().getWindow().findViewById(Window.ID_ANDROID_CONTENT);
int height = contentView.getHeight() - statusBarHeight - actionBarHeight;
(You might have to get the height in contentView.post() if it returns 0.)

Android proper way to fit layout on all devices horizontally and vertically

Hello I want to ask about the most efficient way to adjust layout in all devices mobile and tablets sometimes I can't use wrap_content and layout_weight
I set size in some percentage to the device size in java like this:
ImageView img;
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
img.getLayoutParams().width = width* 7 / 10;
and when rotating screen I use this method to change percentage
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE&& getResources().getBoolean(R.bool.isTablet)) {
width=(int) (width * 0.7);
}
I am asking If this procedure is more efficient than using multi XML files for each screen size / orientation
Actually it depends on the scenario. Sometimes maintaining xml is efficient and easy sometimes dynamic calculation is necessary. You can go through the link https://developer.android.com/guide/practices/screens_support.html . It will give you some ideas. In your above code for width/height calculation sometimes you may not get proper result for some devices. Below is the code that will support all version of android device Resolution(Width, Height) accurately at runtime.
private void calculateDeviceResolution(Activity context) {
Display display = context.getWindowManager().getDefaultDisplay();
if (Build.VERSION.SDK_INT >= 17) {
//new pleasant way to get real metrics
DisplayMetrics realMetrics = new DisplayMetrics();
display.getRealMetrics(realMetrics);
realWidth = realMetrics.widthPixels;
realHeight = realMetrics.heightPixels;
} else if (Build.VERSION.SDK_INT >= 14) {
//reflection for this weird in-between time
try {
Method mGetRawH = Display.class.getMethod("getRawHeight");
Method mGetRawW = Display.class.getMethod("getRawWidth");
realWidth = (Integer) mGetRawW.invoke(display);
realHeight = (Integer) mGetRawH.invoke(display);
} catch (Exception e) {
//this may not be 100% accurate, but it's all we've got
realWidth = display.getWidth();
realHeight = display.getHeight();
Constants.errorLog("Display Info", "Couldn't use reflection to get the real display metrics.");
}
} else {
//This should be close, as lower API devices should not have window navigation bars
realWidth = display.getWidth();
realHeight = display.getHeight();
}
}

Detect device screen size

Hi i want to fit my app to all screen sizes and to do so i need to get the screen width and height.
but if i use this code for example
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels
It gives me the pixels so there can happen a situation that it gives me the same dimentions for tablet and a smaller phone.
how can i get the actual screen size?
and another thing, i have a game i made with bitmaps and on my phone it is working fine but on tablet the bitmaps are too small how can i resize them according to screen size?
You need screen density and pixel size. (Number of pixels) / (dots per inch) gives screen size in inches.
See: getting the screen density programmatically in android?
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels
int realWidth = (int)((float)width/metrics.density);
int realHeight = (int((float)height/metrics.density);
Answer to the second question depends on how are you loading your bitmaps. You should provide multiple sizes for different devices. Then you can use built-in scaling mechanism - simply place bitmaps in their matching drawable-(dpi)-(screen size) folders. Other way you would have to load images from assets folder and scale them if necessary.
For your 2nd problem of bitmap appearing too small on tablet, try to nine patch your image and then place those images in their respective folders (hdpi, mdpi, xhdpi, xxhdpi)
Make sure you use the high quality resolution image for nine patching otherwise your image will get stretch (poor quality).
You can nine patch your image from here also nine patching image
try this:
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
You can get screen dimensions with this code:
public int getScreenHeight() {
return getDisplay().getHeight();
}
private Display getDisplay() {
return ((WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE)).getDefaultDisplay();
}
public int getScreenWidth() {
return getDisplay().getWidth();
}
Try this.
Add this to onCreate() Method. Declare point!
WindowManager wm = ((WindowManager) getSystemService(WINDOW_SERVICE));
Display display = wm.getDefaultDisplay();
point = getDisplaySize(display);
//here is the method to get device size.
#Deprecated
#SuppressLint("NewApi")
private static Point getDisplaySize(final Display display) {
final Point point = new Point();
try {
display.getSize(point);
} catch (java.lang.NoSuchMethodError ignore) { // Older device
point.x = display.getWidth();
point.y = display.getHeight();
}
return point;
}

Android code to set wallpaper to phone screen size

I make use of the following code to set my static images as wallpaper from my android app.. The image dimensions are like 425*700, 280*180, 600*400 etc., so the image dimensions are not the same.
try {
WallpaperManager myWallpaperManager = WallpaperManager
.getInstance(context);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int fullWidth = size.x;
int fullHeight = size.y;
// int fullWidth = wManager.getDesiredMinimumWidth();
// int fullHeight = wManager.getDesiredMinimumHeight();
Log.d("Debug", Integer.toString(fullWidth));
Log.d("Debug", Integer.toString(fullHeight));
Bitmap bitmap = BitmapFactory.decodeStream(getResources()
.openRawResource(R.drawable.hello));
Bitmap bitmapResized = Bitmap.createScaledBitmap(bitmap, fullWidth,
fullHeight, true);
myWallpaperManager.suggestDesiredDimensions(
bitmapResized.getWidth(), bitmapResized.getHeight());
myWallpaperManager.setBitmap(bitmapResized);
} catch (IOException e) {
e.printStackTrace();
}
But the images are quite streched and doesn't look good after setting as a wallpaper in the phone.. What am I doing wrong?
I guess problem lies in the resources as you have already mentioned. For a good view/quality of wallpaper we have to use different resources of images as according to the resolution of your device, if you want to use your application of setting the wallpaper to be used by many devices without making any changes(an apk). The crux is, you need a better quality image matching the resolution of your device. Hope it helps.
Edit: The distortion is again because you are resizing your image for covering full screen size. I guess if you do not resize it, it might work, though I havent use it till now.

How to get screen size in Android, including virtual buttons?

For normal uses you can use the DisplayMetrics class and get the "renderable" size, but I want to figure out the actual physical screen size, which includes the virtual buttons height.
On my Galaxy Nexus the reported size no matter what I tried is 1196x720, what can I use to get the physical one which is 1280x720 ? Same goes for Nexus 7, Nexus 4 and Nexus 10 devices.
UPDATE : This is the final code I now use, including the fix :
//Activity A = this;
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager) A.getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
Display disp = wm.getDefaultDisplay();
int API_LEVEL = android.os.Build.VERSION.SDK_INT;
if (API_LEVEL >= 17)
{
disp.getRealMetrics(displayMetrics);
}
else
{
disp.getMetrics(displayMetrics);
}
int Width = displayMetrics.widthPixels;
int Height = displayMetrics.heightPixels;
You should use Display.getRealSize(Point) From the official docs here
The display area is described in two different ways.
The application display area specifies the part of the display that
may contain an application window, excluding the system decorations.
The application display area may be smaller than the real display area
because the system subtracts the space needed for decor elements such
as the status bar. Use the following methods to query the application
display area: getSize(Point), getRectSize(Rect) and
getMetrics(DisplayMetrics).
The real display area specifies the part
of the display that contains content including the system decorations.
Even so, the real display area may be smaller than the physical size
of the display if the window manager is emulating a smaller display
using (adb shell am display-size). Use the following methods to query
the real display area: getRealSize(Point),
getRealMetrics(DisplayMetrics).
The answer in the similar question seems to have a solution to get the real size of the display when API < 17 https://stackoverflow.com/a/15699681/601298
WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
Point realSize = new Point();
Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
widthPixels = realSize.x;
heightPixels = realSize.y;
} catch (Exception ignored) {
}

Categories

Resources