Why .9.png in Eclipse/device not looks like in draw9patch.exe? - android

I create combobox_normal_m.9.png in draw9patch.exe. It looks very good in draw9patch.exe, but in Eclipse/device it's not so clear. Why edges are blurred?
from layout:
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/selector_cbutton_m" />
from selector:
<item
android:drawable="#drawable/combobox_normal_m"
android:state_selected="false"
android:state_pressed="false"/>

You've inverted the top and bottom 9 patch data. The top 1 pixel defines the area that can be stretched. The bottom 1 pixel defines the area that can be covered with content. Unless, I guess, you intended there to be a buffer between the right edge of the text and the vertical separator. I could be misunderstanding what you are trying to do.
You will also notice that you still have to create versions of the 9 patch for different densities if there are non-scalable features that you want to look right at the different pixel densities. In eclipse you are also seeing a enlarged (typically) version of the screen resolution so it may not be representative of the device.

Related

Android add a padding with size that looks equal on all devices

I have a view that is the same size as my screen / fragment. However, I want to add a padding on the left and right edges such that on all devices, this padding looks like its the same size. when I use:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="20dp"
android:paddingEnd="20dp">
....
The padding is not equal on all devices. On a tablet, it is much smaller than on a small phone. Is there a way maybe programmatically to set the padding as equal on all devices?
and is dp supposed to be density-independent? Then how come, on different density devices the padding set to dp is not always the same size visually?
Notice that what you want is not scalable and not recommended. The reason is that the sizes of devices vary a lot in Android, as well as their pixel densities.
Furthermore, I include a more general article that might help you.
However:
A. Try with other units like mm or in, which are "based on the physical size of the screen" (see documentation).
B. Maybe set it programmatically. That is, calculate how many px/etc. you need on each device so that it looks the same (mm) on all of them.
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1, getResources().getDisplayMetrics());
Finally, I am not sure if this is the case, but as other users sugest, maybe this could help. Once again, however, I am not entirely sure if this is what you need. On the same line, you can also define sizes depending on the details of the device with qualificators (refer here).
You need manage different dimens file for different resolutions , please check this link , You just need to put your padings parameter in dimens and then use from dimens.
How to define dimens.xml for every different screen size in android?
Like the answer said in here
on API 21 padding doesn't work via XML, you can define programmatically like the link i share above
but you can try create style="#style/RootLayoutWithPadding" use this in your view
and inside styles.xml add this
<style name="RootLayoutWithPadding">
<item name="android:paddingLeft">#dimen/activity_horizontal_margin</item>
<item name="android:paddingTop">#dimen/activity_vertical_margin</item>
<item name="android:paddingRight">#dimen/activity_horizontal_margin</item>
<item name="android:paddingBottom">#dimen/activity_vertical_margin</item>
</style>
for every padding you can fill the sizes you want inside values.xml
i hope it help you :)

Android splash screen without logo distortion

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!

9 Patch png not working correctly for background

I'm trying to create a background image for my app that will look sharp on all resolutions/orientations.
I'm new to android development, but I understand the easiest way to achieve this is to use 9 patch images. I thought I understood how they worked, but I can't get it to work.
I've created a background image # 768 x 1280 which is the resolution of my Nexus 4. When I don't 9 patch it and view it on my device, it looks fine (obviously, because the resolution/orientation matches the device's):
So it looks nice and sharp.
But then I add the patches onto the image using the drawer9patch.bat file and rename the file to '.9.png' and this is the result:
Knackered!
The strange thing is: in the preview pane in the right hand side of the draw9patch tool it all looks fine....
I've also tried making the image at a smaller resolution, but the logo & text don't look sharp; they look pixelated...
I feel there must be some vital piece of the puzzle I'm missing? The area I've defined as content is being stretched?
Here is my layout code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/my_background_image_patched"
android:padding="0px">
<!-- Login controls here --->
</RelativeLayout>
Here is my 9 patch image (which is located to the 'drawable' folder):
OK, I tinkered with your 9 patch.
I must say it was poorly designed (72 dpi, while it should really be 320 dpi).
So, I redesigned it (you can see I moved the black pixels) and saved it to 320 dpi (in the drawable-xhdpi folder).
It seems it scaled well at ldpi and mdpi screens (so, I guess it will also scale well at hdpi):
The patch I used is this:
Try to generate Nine-Patch using this Nine-patch Generator allows you to quickly generate simple nine-patches at different screen densities, based on the specified source artwork

Android positioning problems

So my problem is simple- I want to use XML layouts to precisely control the positioning of widgets on multiple devices. To do this, I thoroughly read the google docs on supporting multiple devices. According to this part, the WVGA854 and HVGA are both considered "Normal screen" size. So theoretically, positioning a widget on WVGA854 should look the same as with HVGA. However, the resultant screenshot shows otherwise.
The widget appears relatively higher placed on the WVGA854 skin. The XML code is shown below, and was placed under the layout-normal/ folder:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageButton
android:id="#+id/button1"
android:src="#drawable/icon_unlock"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="300dp"
android:text="Button" />
</RelativeLayout>
The drawables I constructed are in the proper ratios (3:4:6:8 as recommended). So why does this positioning mismatch happen? I beginning to think that using XML to position things is quite fruitless. My app requires very accurate positioning of widgets so even this slight mismatch is a problem. Any help how I can remedy this?
EDIT:
What I want is for the widget to be placed in a manner such that the ratio of margin from top to the margin from bottom is exactly the same across devices. From the screenshot, you can see that this ratio is not the same for WQVGA854 and HVGA.
"Normal Screen" size does not mean that screens have the exact same number of dip. You need to think of it as a bucket which contains a number of different screen sizes which are all similar in physical size.
so using fixed size margins and paddings is not (easily) going to achieve the effect you need. So please clarify your question and give an example of what you exactly want to achieve.

Android custom RatingBar image artifacts

I implemented a custom RatingBar in an application on my ListView items.
Custom style ratingbar_red.xml:
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background" android:drawable="#drawable/star_off" />
<item android:id="#android:id/secondaryProgress" android:drawable="#drawable/star_on" />
<item android:id="#android:id/progress" android:drawable="#drawable/star_on" />
</layer-list>
Here's part of ListItem layout:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="15dp" >
<RatingBar
android:id="#+id/li_company_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginBottom="1dp"
android:isIndicator="true"
android:numStars="5"
android:progressDrawable="#drawable/ratingbar_red"
android:stepSize="1" />
<Button
android:id="#+id/li_company_callbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:layout_marginLeft="40dp"
android:contentDescription="#string/ContentDescription"
android:drawableLeft="#drawable/phone_icon"
android:drawablePadding="5dp"
android:onClick="callbtn_Click"
android:text="#string/CallButton"
android:focusable="false"
android:focusableInTouchMode="false" >
</Button>
</LinearLayout>
It works, but when the rating is set, I get some strange image artifacts; 2 vertical lines below the pink stars appear on my view:
Here is star_on.png
star_off.png looks okay, and if rating == 0, the lines don't appear.
I'm android beginner, and can't understand what the problem is.
Try giving height to RatingBar in xml layout like this:
android:layout_height="30dp"
30dp or whatever suits you..
Check out why is this happening ??
I had this issue to, looked like the bottom edge of custom star image being stretched. You don't have to set the layout_height of rating bar tag. You can set the min/max height on the rating bar (to same as image height).
Example from my styles xml.
<style name="GoldRatingBar" parent="#android:style/Widget.RatingBar">
<item name="android:minHeight">#dimen/rating_bar_height</item>
<item name="android:maxHeight">#dimen/rating_bar_height</item>
</style>
Dimens.xml
<dimen name="rating_bar_height">11dp</dimen>
The value should match that of the drawable used. 11 pixel high image, so the rating_bar_height was set to 11dp.
Another simple solution woud be to leave a row of empty pixels in the star image using an image editor like photoshop. Then the repeated or stretched row of pixels in the ratingbar would be empty. This aproach solved my issue.
I solved this problem in another way. I take my custom star png's, and in image editor add transparent line to the bottom of the image. The problem with vertical lines disappeared on all screens!
Its a Icon design issue. The Problem here is the padding around the icon. If you are creating a custom star icon make sure you leave some padding space between the star and the page boundary on which it lies.
If you are not sure how to do it try Android Asset Studio. You can see something like "Padding around Optical Icon" do not keep it to 0 dip.
Every body is suggesting something but no body is trying to explain why this happen. I am gonna try to explain it now. Of course this will happen only when you are trying to customise the rating bar images.
Imagine that we have custom image with size 72x72 pixels and this is our resource for XXXHDPI -(it is 4x).
Same image need to have copy inside XXHDPI, XHDPI, HDPI, MDPI and LDPI as well. I will miss last one resource directory for now.
Inside different directories this image need to be as follow:
for XXHDPI size copy image need to be 54x54 (this is 3x)
for XHDPI size copy image need to be 36x36 (this is 2x)
for HDPI size copy image need to be 27x27 (this is 1.5x)
for MDPI size copy image need to be 18x18 (this is 1x)
So now in this scenario if your Rating bar has height bigger then 18 dp for example 30 dp, you will see this bad image artefacts below every star image, BECAUSE obviously RatingBar is trying to fill the rest of it's height with something (your Image is 18 dp but the height of the bar is 30dp), so rest 12dp will be filled with this artefacts.
That's why if you set the rating bar height to be fixed size everything COULD be OK but also COULDN'T be OK. All this depends about your custom image size.
I think there has one solution which will work in all possible scenarios and this is :
Create image asset for all devices screens that your app will support XXXHDPI, XXHDPI or what ever you want.
Make sure that if your (MDPI which is 1x) image has for example height 20 pixels, your RatingBar height will not be bigger then 20 dp and everything will be OK.
NOTE: In this whole conversation we talk about dp (density pixels) not in px because if we provide all those image resources in every single res folder we will have chance to work with dp not with px. I hope the last sentence is clear and make sense.
EDIT: The other possible way is to leave some small padding (empty space) , maybe 1px or 2px at the bottom of your custom image. In that case RatingBar view will NOT display those artefacts pixels, because they will be taken from the padding part of your custom image, which actually is just empty (transparent) pixels. I personally think, that this is not the best way, because the image padding will create some space (padding) between RatingBar and the rest Views inside the layout. In that case you will not have absolutely full control of Views space, because some small part has been hard coded inside the custom image (those 2 px padding).
Just 2 pixel padding in image star in photoshop.
padding in xml not work, just padding star image in photoshop.
it's work very good.
I fixed my same problem by reducing "layout_height" since my image's height was less than the height that I had in layout_height.
Same issue. In my case
Put custom star images in /Drawable folder
and set "android:layout_height="30dip"
work fine!!
I was observing the issue due to vector drawable.
Once I added respective png images it started working.
Added this as answer as it may helpful to someone facing the same issue.

Categories

Resources