Is it possible to get correctly scaled item drawable in android layer-list item?
I prepared something like this:
bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/splash_bg" />
<item
android:gravity="center"
android:drawable="#drawable/logo_white">
</item>
</layer-list>
The sizes for drawable/logo_white vector has: 200dp width and 100dp height. It looks nice for small devices, but on tablet this logo is too small.
Is it possible to make it responsive for bigger screens?
Many thanks for help.
You can use attribute width and height in API level 23 and higher:
<item
android:width="#dimen/your_size" android:height="#dimen/your_size"
android:drawable="#drawable/logo_white"/>
And create different dimens files, for normal phones, tab, etc
Android has multiple folder system for multiple resolutions.
layout-hdpi,
layout-xhdpi, etc.
and same goes for drawable folder too. So by implementing same filename but edited xml based on dimension for different folder you can make in responsive. You might find other different technique for this.
Is it possible to create a splash screen with a logo that maintains its aspect ratio while the background image can be resized independently? I'm currently using several .png files for different resolutions and they look great on most devices. However, there are a few phones that distort my logo severely (i.e. the Samsung S8, with move vertical screen space).
I can deal with some distortion for my splash screen background, but the skinny/squashed logo is unacceptable. Does anyone know how to do this? And would a vector drawable logo be better than a .png for the new layout?
Rendering a splash view in a layout.xml instead of as a theme background (like other answers here recommend) takes longer to load. This is because the app's theme is loaded first, then the Activity is constructed and the layout inflated last. Since the purpose of a splash screen is to display something while the app loads, having a ~0.5s delay in loading the splash screen itself results in a noticeable delay. Loading a splash as a theme windowBackground performs better (renders almost instantly after tapping the launcher icon), but has some restrictions to work around. Your current method of defining multiple logo sizes depending on the screen width is the correct way to handle this situation. Here is an example configuration, which handles differences between pre and post Android v21:
values/themes.xml:
<style name="SplashThemeCommon" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowBackground">#drawable/splash_logo_theme</item>
</style>
<style name="SplashTheme" parent="SplashThemeCommon">
<item name="android:windowFullscreen">true</item>
</style>
values-v21/themes.xml:
<style name="SplashTheme" parent="SplashThemeCommon">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
drawable/splash_logo_theme.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap
android:gravity="center"
android:src="#drawable/splash_logo"/>
</item>
</layer-list>
Next you can include a copy of "splash_logo.png" for different screen configurations. You have a couple reasonable options here. An exhaustive approach might include different logos for each screen size:
drawable-sw320dp-xxxhdpi/splash_logo.png
drawable-sw400dp-xxxhdpi/splash_logo.png
drawable-sw480dp-xxxhdpi/splash_logo.png
drawable-sw600dp-xxxhdpi/splash_logo.png
drawable-sw720dp-xxxhdpi/splash_logo.png
drawable-sw820dp-xxxhdpi/splash_logo.png
The "swXXXdp" means that XXX is the smallest screen dimension (width or height) in dp. 820dp is going to be a huge tablet, 320dp will be an old small device, and most flagship devices today will be in the 400dp category. A 450dp wide device would use the 400dp image.
Why did I define xxxhdpi here? Because if you don't specify, Android will assume it is an mdpi image and try to upscale/resize for higher dpi devices (most flagship phones today are xxhdpi). This upscaling will result in your image being blocky, and larger than the original. By specifying xxxhdpi here, Android will only try to downscale the image ensuring that the image never goes blocky; this is a optimization so we don't also need to define separate images for ldpi, mdpi, hdpi, xhdpi etc.
Having 6 images in the APK is kind of a waste though. We can futher optimize this approach in order to include less images in the app and ensure a smaller APK size. Instead, let's include only the following two images:
drawable-sw600dp-xxxhdpi/splash_logo.png
drawable-xxxhdpi/splash_logo.png
Any devices 600dp and larger (tablets) have a larger copy of the image to take advantage of the larger screen real estate, while all other phones use a smaller copy located in the bin with no screen width qualifier. The drawback here is since each bin covers such a large range of screen widths, the logo on a 4" device will take up a larger portion of the screen than on a 6" devices. This is a compromise to cut down the APK size, and most users won't notice so long as the image never gets cut off even on the smallest device.
So what size png's should we include? They need to be a particular size to be displayed in a theme, since unlike in a layout.xml we cannot specify a width/height in the XML (drawable width/height support was only added in API 23). This means if you include a non-optimal png size, it will appear too small or two big; if its too big it will actually get cut off. A good plan to get the right size is:
Create an layout/test.xml file with just the default LinearLayout and no visible content
Open it in Android Studio and select the Design tab in the layout editor's bottom left corner
Change the theme to SplashTheme in the layout editor's top bar
Change the device to "Pixel XL"
Place an image under drawable-sw400dp/splash_logo.png
Open the image in an external image editor such as Photoshop or Gimp, change the size, save, then check the layout in Android Studio (you may need to close and reopen the editor for the change to take effect). Repeat until the image looks the correct size in the layout
Generate images for the other screen widths proportionately; for example the sw320dp image should be 320/400 or 67% of the 400dp image size, while the 720dp image should be 720/400 or 180% of the 400dp image size. Remember not to upscale your 400dp image for the larger images as you will lose quality. Instead, generate all the images based on your high quality original copy
Place the generated images in the different drawable directories as specified above
Select devices of different screen sizes (including tablets) in the layout editor and make sure they logo is large enough, but not cut off, for all screen sizes
How do you know which device screen resolution belongs to which swXXXdp category? This requires a simple calculation. Lets look at the Pixel XL:
The screen size is 1440x2560
The smallest dimension is therefore 1440
The screen dpi is 534
The screen width in inches is 1440/534=2.69"
Open the website: http://angrytools.com/android/pixelcalc/
Enter 2.69 in the inches ("in") box
One of the green boxes on the left will display the dp, in this case 431
With a 431 dp wide screen, the Pixel XL will use the drawable-sw400dp/splash_logo.png image if you have all 6 image categories, or the drawable-xxxhdpi/splash_logo.png image if you only have the two image categories
If you only have a portrait image for your splash screen, here's a solution which is full screen on portrait, and centred but not cropped on edit:
portrait landscape:
splash_screen.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layoutSplash"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/splash_screen_background">
<ImageView
android:contentDescription="#string/splash_screen_description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
style="#style/SplashScreen" />
</LinearLayout>
values/styles.xml
<style name="SplashScreen">
<item name="android:src">#drawable/splash</item>
<item name="android:adjustViewBounds">true</item>
<item name="android:scaleType">fitCenter</item>
</style>
values-port/styles.xml
<style name="SplashScreen">
<item name="android:src">#drawable/splash</item>
<item name="android:adjustViewBounds">true</item>
<item name="android:scaleType">centerCrop</item>
</style>
Have you looked into maintaining the aspect ratio for the ImageView? Here is a relevant question that should point you in the right direction: How to scale an Image in ImageView to keep the aspect ratio
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/logo"/>
</RelativeLayout>
This will do this
This is on a nexus 10
No need to use layouts at all, use a LayeredList, and set it as the background. Here is an example;
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/gray"/>
<item>
<bitmap android:gravity="center" android:src="#drawable/splash_image"/>
</item>
</layer-list>
In Android resources/res folder, create a folder "drawable-xxxhdpi" and "drawable-sw600dp"
In "drawable-sw600dp" folder, add 'splash_logo.png' with resolution 4096x4096 pixels. This should cover tablets.
In "drawable-xxxhdpi" folder, add another 'splash_logo.png" with resolution 1440x2560 pixels. This should cover smart phones.
That's how to solve all distortions!
I have a Radio Group. 5 Radio Buttons. The Radio Button's DrawableTop are set as, android:drawableTop="#drawable/Timeline_icon_drawable"
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#mipmap/explore_icon_pressed" />
<item android:drawable="#mipmap/explore_icon" />
</selector>
How do I make the png smaller?
click on this link.. and download this 9 PATCH RESIZER..
9PATCH-RESIZER
It is specifically designed for developers of android. when you will drag any image on this software it will create every version of drawable images such as
xxxhdpi, xxhdpi, xhdpi, hdpi, mdpi, ldpi.
after customizing png or icon with this software you can use it comfortably in your app.
hope it helps!
first, sorry if my english is not correct, (i'm french) and I've not find the solution for my problem in french websites, so i try here !
In my app, I want to show 7 Buttons with graphisms I created with the GIMP.
So I use, in the XML code for my Buttons (here for my first button) :
android:background="#drawable/change_my_button1"
-change_my_button1 is an XML file :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false"
android:state_enabled="false"
android:drawable="#drawable/button-1" />
<item android:state_pressed="true" android:drawable="#drawable/button1-2" />
<item android:state_enabled="true"
android:drawable="#drawable/button1" />
If I press the button, its aspect change.
All of that works perfectly with my button1, button2 and button3.
But when I apply this method for my button4, the app crashs and i have a message "Unfortunatly, the application my_app has stoped"
I thought my images "button4" and "button4-2" are wrong but no ! When I delete the code line
android:background="#drawable/change_my_button1"
from the XML code of my first Button, then the image for my fourth Button works perfectly...
Maybe the res/drawable/ folder may contain only a restrict number of images ?
I've tried to put those two images in several res/drawable/ folders, but it's not working...
I hope you'll understand my problem...
Please help me ! That is a pain in the ass for me...
Thanks ! :)
Your resources are to big and you get OutOfMemoryError. You have to scale your resources for screen resolution which you support. I mean xxhdpi xhdpi hdpi etc. Probably all your resources are in drawable folder. It is wrong. They should be in drawable-xxhdpi, drawable-xhdpi, etc folders with proper size with proportions:
hdpi = mdpi * 1.5
xhdpi = mdpi * 2
xxhdpi = mdpi *3
I have a problem with drawables on HTC Sensation and HTC One S.
I have graphics in drawable-nodpi folder:
icon_l.png
icon_m.png
In drawable-hdpi folder I have file icon.xml with code:
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/icon_l" />
In drawable-land-hdpi folder I have file icon.xml with code:
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/icon_m" />
In drawable folder I have selector file button.xml with code:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/icon_pressed" />
<item android:drawable="#drawable/icon" />
</selector>
In layout I have:
<ImageButton android:src="#drawable/button"/>
Everything works ok, on almost all phones and tablets: graphics on landscape are smaller and when I back to portrait graphics are again bigger;
but not on HTC sensation and HTC one S: graphics on this phones are loaded randomly when I rotate phone.
I suppose that may be any cache?
I tried setContentView to other layout and again reloaded correct layout, but it doesn't work.
I was able to duplicate this behavior on a Sensation running stock ICS Android. Only workaround I found so far was to put an extra copy of button.xml in each HDPI folder.