I'm building a splash screen with a dimmed background. Im using RelativeLayout as the base for all the widgets. In order to create and dim effect I created a dim.xml, which is essentially a black shape (to set the opacity later).
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#000000" />
The layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:background="#drawable/background"
android:id="#+id/ActivityLayout">
<ImageView
android:layout_width="240dp"
android:layout_height="#dimen/abc_action_bar_default_height_material"
android:layout_marginTop="98dp"
android:layout_marginRight="170dp"
android:src="#drawable/logo"
android:id="#+id/logo" />
</RelativeLayout>
Is there a way to place the black shape between the RelativeLayout and the widgets, and then set some alpha value to the black shape in order to achieve the dimming effect?
Is there a way to place the black shape between the RelativeLayout and
the widgets, and then set some alpha value to the black shape in order
to achieve the dimming effect?
You can achieve this by adding another View in your RelativeLayout and set its width and height to "match_parent", then change the View's background color to what you want.
Your layout may go like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
>
<View android:width="match_parent"
android:height="match_parent"
android:background="#color/the_color_you_want"/>
<here are the widgets...>
</RelativeLayout>
Update:
But it doesnt fill the entire view port, the there's about 10dp margin
on each side, that doesnt stretches across the screen. Any way to fill
the entire screen?
It's because you have set a 10dp padding for both the left and right side of your RelativeLayout. There are two ways to make the color View fill the entire screen:
Set android:clipToPadding="false" to your RelativeLayout and then set the following attribute to the color View:
android:layout_marginLeft="-10dp"
android:layout_marginRight="-10dp"
This is very easy to do but it may cause problem to your widgets, so you can have a try.
Remove paddingLeft and paddingRight attribute from your RelativeLayout, thus your color View will fill the screen, then rearrange your widgets to make sure their left or right margin is correct.
You may need to do more work with this method, but I'm sure this is a right way.
Related
I'm building a UI with the following constraints:
I must describe the layout in XML.
I can only use common widgets like FrameLayout, RelativeLayout, ImageView, and even ProgressBar.
I don't know the size of my container.
Here's what I want to happen:
An ImageView with a circle inside it should maintain its aspect ratio and fill as much of the vertical + horizontal space as possible, centering inside of that. That ImageView will have an icon in the center of it with some padding around it from the circle background.
A ProgressBar which rotates a ring should match the size of the ImageView, sharing its exterior border with the ImageView exactly. It should also be centered in the same container.
Here's what I've got so far, but it only works sometimes. Seems like it only works when the adjustViewBounds flag is actually changing the size of the view. I've also been able to tweak this to make it work in other cases, but I haven't been able to figure out how to make this work regardless of the conditions.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dp"
android:background="#drawable/circle_blue"
android:contentDescription="#string/icon_content_description"
android:scaleType="centerInside"
android:adjustViewBounds="true"
android:layout_centerInParent="true"
/>
<ProgressBar
android:id="#+id/greenProgress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_marginTop="-6dp"
android:layout_marginBottom="-6dp"
android:layout_marginStart="-6dp"
android:layout_marginEnd="-6dp"
android:indeterminateDrawable="#drawable/progress_green"
android:indeterminateDuration="1600"
android:indeterminate="true"
android:indeterminateOnly="true"
android:visibility="gone"
/>
<ProgressBar
android:id="#+id/yellowProgress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_marginTop="-6dp"
android:layout_marginBottom="-6dp"
android:layout_marginStart="-6dp"
android:layout_marginEnd="-6dp"
android:indeterminateDrawable="#drawable/progress_yellow"
android:indeterminateDuration="800"
android:indeterminate="true"
android:indeterminateOnly="true"
android:visibility="gone"
/>
</RelativeLayout>
...
</LinearLayout>
Thanks for any help!
What might work is only using match_parent on one of the height/width layout params of the ProgressBar, and using wrap_content for the other. (i.e. android:layout_width="match_parent" + android:layout_height="wrap_content". This might allow the ProgressBar to lay itself out in the same manner that scaleType="centerInside" draws its image (but I have not tested it).
So the underlying issue was the ring shape, not the ProgressBar. I'll explain why, but first, the solution!
The solution
I used a png of the ring png with the gradient where it went from white to transparent. I made sure the outer edge of that png aligned with the outer edge of the ring. Then, I could use <rotate> on the bitmap directly. See below:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="800"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" >
<bitmap
android:src="#drawable/spinner_white"
android:tint="#color/spinnerYellow"
/>
</rotate>
This allowed me to describe the ProgressBar I wanted to render in terms of how its outer edge aligned with the outer edge of its container.
Why wasn't this happening when I was using the ring shape?
To explain that, I'll have to reference the Drawable resources documentation on Shapes. Take a look at two attributes there referencing a radius: android:innerRadius and android:innerRadiusRatio. The description for both of those begins with: "The radius for the inner part of the ring (the hole in the middle)..." And there you have it. There's no way to describe the ring shape by its outer radius, only by its inner radius.
One interesting tidbit, and why ProgressBars using ring shapes never fill the bounds of their containers, is the default value for android:innerRadiusRatio is 9. That means the inner radius, by default, is the ring's width divided by 9. It'll usually be pretty small relative to its container!
I'm relatively new to android and I want to know how to put a visible divider/borders around images.
You could try to add an android:background attribute to your ImageView with the value of your desired border color. Then add an android:padding attribute to the ImageView with the value of your desired border width. It's not the most elegant solution, but it's understandable and for a new developer will do a fine job. For example:
<ImageView
android:id="#+id/list_item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/android_image"
android:background="color/list_item_icon_border_color"
android:padding="1dp"
/>
Maybe the right way for performing this is by using custom XML drawables. You could check in Google for creating borders for ImageView using custom XML drawable. However being a little more complicated way than the upper mentioned method it could be an excellent way to start with XML defined custom drawables. Sooner or later you'll have to understand it, no other way. For circular border check this post - nice and clear explanation with custom XML drawable:
Create circular border around ImageView
In the item's layout you could put a View with heigth of 1dp or width 1dp and fill it with some color. This is a item for a list with a text and a bottom divider.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/colorPrimary"/>
</FrameLayout>
I have a relative layout with a margin and a floating action button that is nested inside this layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="#dimen/activityMargin"
android:orientation="vertical"
android:clipToPadding="false">
<android.support.design.widget.FloatingActionButton
android:id="#+id/id_FABSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
app:srcCompat="#drawable/ic_save_white"/>
</RelativeLayout>
As you can see in the attached picture, the drop shadow of the floating action button is cut off. How does this happen and how can it be fixed?
In your relative layout tag, use padding instead of margin and add the attribute android:clipToPadding="false" to avoid the shadows being cut.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="#dimen/activityMargin"
android:clipToPadding="false">
Problem is that shadows are cut by bounds of view or view group. To tackle this issue you have to use:
android:clipChildren
Defines whether a child is limited to draw inside of its bounds or not.
android:clipToPadding
Defines whether the ViewGroup will clip its children and resize (but not clip) any EdgeEffect to its padding, if padding is not zero.
Problem is that you have to set this to many views in xml if you want to render shadow. I resolved this issue on level of themes.xml. In my top level theme I just set:
<item name="android:clipChildren">false</item>
<item name="android:clipToPadding">false</item>
Then, if there is space on screen, shadow is rendered. I hope it won't break something else.
EDIT: It breaks some views. For example CameraPreview will set black background to whole screen. Be careful with scrolling views, etc.
In my Android project, I am not quite sure how to make my background image fill the entirety of the RelativeLayout root element in XML, which is the size of the screen. I want to be sure that this works for all aspect ratios, so the image will clip vertically or horizontally as necessary. Does someone know how to do this easily? I've only seen questions regarding ImageViews and Buttons, but not really generic Views.
My XML file currently:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/enclosing_rl"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background"
android:fitsSystemWindows="false">
<!-- Other elements -->
</RelativeLayout>
Other than turning your image into a nine patch I don't think this is possible. What you could do instead is-
Add an ImageView as the first view in your RelativeLayout.
Set layout_centerInParent to true.
Have the layout_width and layout_height set to match_parent.
Then set scaleType to centerCrop.
That will make sure the image fills the screen without any distortion, but depending on screen size/orientation either some of the top/bottom or left/right of the image may be cut off.
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:scaleType="centerCrop"
android:src="#drawable/background" />
Any other views in the RelativeLayout will appear on top of the ImageView, as long as it is the first view in the RelativeLayout (when you are in the xml).
Create a bitmap drawable XML resource in your res/drawable folder:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/background"
android:tileMode="repeat" />
Use that drawable as background instead of #drawable/background
according to this answer If you want your ImageView fill your RelativeLayout,use align parameters for ImageView.
you can put all of your views to a LinearLayout and set align parameter to your background ImageView:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/my_background"
android:scaleType="centerCrop"
android:layout_alignTop="#+id/my_views"
android:layout_alignBottom="#+id/my_views"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/my_views"
android:orientation="vertical" >
<!-- stuff -->
</LinearLayout>
</RelativeLayout>
Its smart and 100% working answer is to set the property scaleType of image view !
android:scaleType="fitCenter"
I have a large png that I would like to use as a background on different layouts, but offset it so that I can have different parts showing (much like you can in CSS), preferable in the xml.
My main layout for the activity contains the following xml:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#layout/bg1">
Layout bg1 consists of the following xml:
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/big_image"
android:layout_marginTop="50sp"
android:paddingTop="50sp"
android:gravity="top|left" />
The gravity property works as expected but margins and paddings are ignored, presumably because I'm working on a bitmap object rather than a layout. What I want to do is set these to a minus amount so that only part of the picture is shown. I've tried using a shape but that only wraps the content whereas I need to fill the entire background.
Any suggestions would be gratefully received. Thanks.
I have used an ImageView with a negative top margin value. The ImageView is declared first within the layout so that it is lowest in the stack of controls and will be rendered behind the others.
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/bigLogo"
android:src="#drawable/big_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="-100px" />
</RelativeLayout>
You can use an InsetDrawable (it works from XML) to add extra padding to another drawable.