I'm working on an Android application where I want to create a windowBackground with a centered element and a layout also with a centered element. I want these elements to be in the exact same position, with the layout overlapping the background. The problem I'm having is that the layout and the background seem to be calculating center differently (see image). Why is this happening, and what can I do to line the elements up?
This is what I see right now. The red box is created by the background and the green box is created by the foreground. Screenshot was created with a Nexus 5X API 26 emulator.
Foreground layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:background="#color/foreground_box"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_centerInParent="true" />
</RelativeLayout>
Background Drawable (applied via android:windowBackground in my theme)
<?xml version="1.0" encoding="UTF-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/background" />
<item android:gravity="center">
<shape
android:gravity="center"
android:shape="rectangle">
<solid android:color="#color/background_box" />
<size android:width="10dp"
android:height="10dp" />
</shape>
</item>
</layer-list>
For clarity, my colors file is
<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<color name="background">#ffffff</color>
<color name="background_box">#AAFF0000</color>
<color name="foreground_box">#AA00FF00</color>
</resources>
Full source for this sample project is available at https://github.com/HofmaDresu/AndroidCenteredTest
The reason windowBackground includes both the heights 1) statusBar and 2) actionBar
Modify below line in your background.xml
<item android:gravity="center" android:top="80dp"> // 56 actionBarSize + 24 statusBarHeight
You may need to manage this programatically as statusBarHeight and actionBarSize varies based on device API/resolution.
Here is the result. For testing, have resized background size bit bigger so that overlapping between views and background become visible.
It is probably because of the extra space taken up by the ActionBar in the foreground.
To fix this, you can add a margin to your View in the foreground layout as:
android:layout_marginBottom="?android:attr/actionBarSize"
After test it in AS, I can say you that the right code for you background_drawable is this:
<?xml version="1.0" encoding="UTF-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/background" />
<item android:gravity="center" android:bottom="48dp">
<shape
android:gravity="center"
android:shape="rectangle">
<solid android:color="#color/background_box" />
<size
android:width="10dp"
android:height="10dp" />
</shape>
</item>
using android:top, the red square go more down than center. Need to use android:bottom instead to center background. By my tests results that 48dp is the right value.
Related
I want to create vertically repeating background for whole app that is adjusted to width of phone.
My bitmap is:
resources/drawable/repeating_bitmap.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/app_bg_003_phone"
android:gravity="fill_horizontal"
android:tileModeY="repeat" />
My style is:
resources/values/style.xml
<style name="AppTheme" parent="BaseTheme">
<item name="android:windowBackground">#drawable/repeating_bitmap</item>
</style>
And my problem is here:
As you can see, instead of whole image only the edge is stretched, Weird.
How can i achieve horizontally stretched and vertically repeated background?
I have used proper flags on bitmap... (android:gravity="fill_horizontal" android:tileModeY="repeat")
If this could help this im attaching original image that im repeating (mdpi)
I want to use repeating bitmap to save up on memory. Also this is only jpeg pattern that is available for me at the moment.
Update
Now i know why only edge is streched: From documentation:
https://developer.android.com/reference/android/graphics/drawable/BitmapDrawable
"Gravity is ignored when the tile mode is enabled. Default value is "disabled"."
That means when i got tileModeY="repeat", then tileModeX by default as i enabled tile mode overall, must be tileModeX="clamp" which is:
"clamp Replicates the edge color."
Any ideas how i can use tileMode and gravity at the same time? I tried to insert this bitmap into another view where gravity would be "fill_horizontal". Sadly without success.
I found a pretty fancy way of achieving this:
Remove the tileMode attribute from the "bitmap"
Create a "layer-list" root tag in the XML
Add an "item" tag around the "bitmap" with top and height attributes (set the height to that of the image)
Copy&paste this "item" as many times as you think you need it to fill the display
Enter the proper top value for each of the "item" tags
Here is an example where the image for the background is 116 pixel high. Therefore each of the following tags has a top value increased by this height.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="0dp" android:height="116dp">
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill_horizontal" android:src="#drawable/background" />
</item>
<item android:top="116dp" android:height="116dp">
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill_horizontal" android:src="#drawable/background" />
</item>
<item android:top="232dp" android:height="116dp">
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill_horizontal" android:src="#drawable/background" />
</item>
<item android:top="348dp" android:height="116dp">
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill_horizontal" android:src="#drawable/background" />
</item>
<item android:top="464dp" android:height="116dp">
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill_horizontal" android:src="#drawable/background" />
</item>
<item android:top="580dp" android:height="116dp">
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill_horizontal" android:src="#drawable/background" />
</item>
</layer-list>
I would like to add padding or space to the logo on both the sides and the code is added here.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="fill">
<item android:drawable="#color/ns_theme"></item>
<item>
<bitmap android:gravity="center" android:src="#drawable/logo" />
</item>
</layer-list>
I had the same problem, I tried to add padding to the item but it didn't change anything.
<item
android:left="16dp"
android:right="16dp">
<bitmap android:gravity="center"
android:src="#drawable/splash"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"/>
</item>
The problem was gravity="center", with it the padding were not applied.
Try using android: gravity = "clip_horizontal"
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/splash_color" />
<item
android:left="16dp"
android:right="16dp">
<bitmap android:gravity="clip_horizontal"
android:src="#drawable/splash"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"/>
</item>
</layer-list>
Use
android:bottom=""
android:left=""
android:right=""
android:top=""
Try this
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="fill">
<item android:drawable="#color/ns_theme"></item>
<item
android:bottom="20dp"
android:left="20dp"
android:right="20dp"
android:top="20dp">
<bitmap
android:gravity="center"
android:src="#drawable/logo" />
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/ns_theme" />
<item
android:drawable="#drawable/ic_logo"
android:left="#dimen/_16sdp"
android:right="#dimen/_16sdp" />
</layer-list>
The problem is probably that your logo is too big (The image file you are using has a pixel width that exceeds the pixel density of the device you are running it on).
Whether or not that is the case, it would probably be better to approach the problem considering the possibility that it could be run on ANY Android device with ANY screen size.
Considering that, there are several options better than simply adding padding in xml... For example, you could:
1) Wrap the image inside another view object that you can control the size and postion of as Bhavik Makwana suggested.
2) Just simply re-edit/resample your image to match the width of your target device and include the white space you desire in the image itself.
3) Design full splash screens that match the entire screen exactly (which combine foreground and background into one image), for example one with 1080 x 1920 resolution, and others for other screen sizes. That way you can control exactly how you want it to look, and the resolution will be 1-1 with no anti-aliasing or resampling.
4) Use this "9-patch" image approach to define an absolute width and height for your logo, but allow stretching of the white space around it to accommodate different screen sizes.
or, finally, the best way:
5) Use a constraint layout with guidelines in order to define the width of your logo in terms of percentage of parent width rather than absolute value.
Some other advice: Unless you are using technique #2 above, make sure you are using a logo.png file like this:
... NOT like this:
KaBOOYOW!
-Boober.
try this code:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/colorPrimary" />
<item>
<bitmap android:src="#drawable/logo"
android:gravity="center" />
</item>
</layer-list>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:gravity="center"
android:layout_height="match_parent"
android:layout_width="match_parent">
<item
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp"
android:gravity="center"
android:background="#mipmap/logo" />
</layer-list>
Here is a picture of what I want to accomplish, where there is no progress color (transparent), with a solid grey background bar:
I tried
android:progressTint="#00000000"
But that sets the whole bar (progress bar AND the back bar) to transparent.
I also tried:
android:progressDrawable="#drawable/customseekbar"
where customseekbar.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/seekbar_background" />
<item android:id="#android:id/progress">
<clip android:drawable="#drawable/seekbar_background" />
</item>
and seekbar_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#FF555555" />
</shape>
but then I get this fat and ugly:
What am I doing wrong here? Thanks
How to Style a Seekbar in Android
Here you go, you need to do the following
Step 1:
In drawable, put "progress_bg.png" (find attached)
Step 2:
In drawable, create "myprogessbar_style.xml", and insert the following
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background"
android:drawable="#drawable/progress_bg" />
<item
android:id="#android:id/secondaryProgress"
>
<scale
android:drawable="#drawable/progress_bg"
android:scaleWidth="100%"/>
</item>
<item
android:id="#android:id/progress"
android:drawable="#drawable/progress_bg"/>
</layer-list>
Step 3:
Your seekbar
<SeekBar
android:id="#+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_margin="10dp"
android:indeterminate="false"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:progressDrawable="#drawable/myprogessbar_style"/>
Result
Attachment
P.S. Yes, it's not a transparency but the expected result
This seems to work:
<SeekBar
...
android:progressTint="#android:color/transparent"
... />
seekbar_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">
<stroke android:height="1px" android:color="#FF555555" />
</shape>
1px line shape
android:maxHeight="3dp" add this to your layout xml where you have mentioned the seekbar. You can change the dp if you wish to decrease the height
That's much easier to solve. In your seekbar_background.xml:
Instead of:
android:color="FF555555"
Try:
android:color="#android:color/transparent"
If you want to do it programatically:
seekBar.progressTintList = ColorStateList.valueOf(Color.TRANSPARENT)
android:background="#android:color/transparent"
This set my SeekBar in Android Studio background to transparent. Pretty straight forward.
I am trying to set a global background image for my android application. The image is a PNG file with transparency. I set it in the following way:
<style name="MyAppTheme" parent="#style/Theme.AppCompat">
<item name="android:windowBackground">#drawable/background_main</item>
</style>
And drawable/background_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/background_main_bitmap"
android:gravity="bottom|center_horizontal" />
My PNG file should sit at the bottom of the screen always, being scaled to match the screen size always. With the above code, however, I am facing two problems.
The transparent background of the PNG file is black while I want it to be white.
The PNG file is larger than the screen width and hence, I can only see a portion of it. It is not scaled to match the width of the screen.
How can I accomplish these two things, possibly without havin to write Java code? (Although it would be better than nothing...)
Problem #1 can be solved with a layer-list in drawable/background_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
</shape>
</item>
<item>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/background_main_bitmap"
android:gravity="bottom|center_horizontal|fill_horizontal" />
</item>
</layer-list>
Problem #2 remains though...
just change the property of android:gravity like following:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/flush"
android:gravity="fill_horizontal|fill_vertical"/>
Actually, using layer-list may give you expected scaling:
All drawable items are scaled to fit the size of the containing View, by default. Thus, placing your images in a layer list at different positions might increase the size of the View and some images scale as appropriate. To avoid scaling items in the list, use a <bitmap> element inside the <item> element to specify the drawable and define the gravity to something that does not scale, such as "center"
Thus, the following drawable will suit your request:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/white" />
<item android:drawable="#drawable/background_main_bitmap" />
</layer-list>
Friends How To Display Border To Imageview ?
I Want To Result Like Mobile gallery all image display with border.
plz give me ans thanks for advance....
You can create a resource (layer drawable xml) for your ImageView's "border" (actually background), and declare in your theme that the ImageView's background resource is the drawable xml.
If you need this "border" to be changed based on the ImageView's state (focused, selected, etc.), then you should create more layer drawables, and put them together into a selector xml (state drawable).
Then in your theme you should set the ImageView's background to be this selector.xml.
Update
Below is a sample of how to specify a simple border to your images, that will result in
You have to
create a new layer drawable file (image_border.xml),
modify/create your styles.xml file
modify/create your colors.xml file
modify your layout xml file (or your code) to apply the style to the ImageView.
res/drawable/image_border.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient android:angle="90"
android:startColor="#color/image_border_start"
android:centerColor="#color/image_border_center"
android:endColor="#color/image_border_end" />
</shape>
</item>
<item android:top="2dp" android:left="2dp"
android:right="2dp" android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#color/default_back_color" />
</shape>
</item>
</layer-list>
res/values/styles.xml
Add the following lines:
<style name="myImageView">
<!-- 3dp so the background border to be visible -->
<item name="android:padding">3dp</item>
<item name="android:background">#drawable/image_border</item>
<item name="android:scaleType">fitCenter</item>
</style>
res/values/colors.xml
Add the following lines:
<color name="image_border_start">#40990000</color>
<color name="image_border_end">#FF660000</color>
<color name="image_border_center">#FFFF3333</color>
And finally specify the style of your ImageView in your layout xml:
<ImageView android:id="#+id/my_image"
android:layout_width="100dp" android:layout_height="100dp"
android:src="#drawable/efteling"
style="#style/myImageView" />
You can use this XML file as a drawable instead of multiple files, but this
file is placed in drawable folder. In ImageView use this XML file as a
background drawable, like: android:background="#drawable/following code file
name".
I hope this is helpful for you.
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<stroke android:width="1dp" android:color="#000000" />
<padding android:left="1dp" android:top="1dp" android:right="1dp"
android:bottom="1dp" />
</shape>
I tried all the above solutions but they didn't work for me!
So I figured out a simple solution to this! :-)
I remember that I read about FrameLayout of Android in the following article saying that it helps us to stack up our UI elements on top of each other in the same order we add them up.
Solution:
<FrameLayout
android:layout_width="112dp"
android:layout_height="112dp"
android:layout_marginLeft="16dp" <!-- May vary according to your needs -->
android:layout_marginRight="16dp" <!-- May vary according to your needs -->
android:layout_centerVertical="true">
<!-- following imageView acts as the boarder which sitting in the background of our main container ImageView -->
<ImageView
android:layout_width="112dp"
android:layout_height="112dp"
android:background="#000"/>
<!-- following imageView holds the image as the container to our image -->
<!-- layout_margin defines the width of our boarder, here it's 1dp -->
<ImageView
android:layout_width="110dp"
android:layout_height="110dp"
android:layout_margin="1dp"
android:id="#+id/itemImageThumbnailImgVw"
android:src="#drawable/banana"
android:background="#FFF"/>
</FrameLayout>
Preview:
And that's it. You will get the following like imageView!
Pros and Cons:
I think this is pretty easy solution to be used in anywhere else and it's all the things you do sits in one single place so easier to modify it. However I don't like to having to add two ImageViews.