Centering a background image in Android - android

I have a background image about 100 x 100 that I want to center in an Android app. Is there a way to do this?
I'm thinking it would greatly help with orientation changes for simple apps.

You can use BitmapDrawable for the case. Create centered.xml in res/drawable folder:
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/your_image"
android:gravity="center"/>
Then you can use centered drawable as background.

Or if you want to use your mipmap image, you should use item instead of bitmap:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/app_bg_color" />
<item android:drawable="#mipmap/ic_launcher_round"
android:gravity="center"/>
</layer-list>

Question is old and answer has one big weakness - we have no possibility to change image size, it means it fully depends from drawable we have.
While using newest Android design libraries the root of activity view will be CoordinatorLayout or DrawerLayout and those layouts has no default view showing hierarchy, it means that first child view will be overshadowed by any next one, and second by third and ... to last one. So to have centered background We need to add as first child LinearLayout with centered image inside it. Some code snippet:
<android.support.v4.widget.DrawerLayout>
<!-- first child -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="60dp"
android:src="#drawable/some_background"
/>
</LinearLayout>
... next view will be above
We can fully customize size of image which will be centered by LinearLayout gravity option. Important is also to have match_parent on width and height of LinearLayout, thanks that center will be center of parent view also.
The same thing can be done in RelativeLayout or any other layout which enable child views overlapping.

With a ConstraintLayout you can set the background tag directly. To be honest it took me a few hours to work this one out but it's a lot simpler than you might think ;)

Related

How to create a complete round LinearLayout or RelativeLayout

I am trying to create a complete circular Layout so that if i put any content inside that layout. That content should be inside the circle. How is that possible ? I tried the following way. But the shape is not circular all the time. Sometime it becomes oval depending on the space. How to keep the layout circular all the time and content should come inside it ?
<LinearLayout
android:id="#+id/zodiac_Layout"
android:layout_width="100dp"
android:layout_height="100dp"
android:orientation="vertical"
android:background="#drawable/circular_background">
<ImageView
android:id="#+id/zodiac_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="2dp"
android:adjustViewBounds="true"
android:src="#drawable/sunrise" />
<TextView
android:id="#+id/zodiac_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:text="#string/na"
android:textColor="#fff"
android:textSize="#dimen/nakshatra_text_size" />
</LinearLayout>
This is the circular_background.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#50514F"/>
<size android:width="5dp"
android:height="5dp"/>
</shape>
What if I make the ImageView match_parent. It comes out of the circle shape of the Layout. I want the content to be cropped along the circular shape of the layout.
Due to what we have chatted in the comments. Now I know what you real want is the Circular crop to your ImageView and also a TextView. So after a dedicated work I have decided to form the solution that will result to an output that is shown in the image below:.Dont worry about the textView you can position it anywhere. Even on top of the image! And change its size! First you will have to know there is no default implementation on this meaning there is no default View class that provides Circular cropped Views in android. So here are the two alternatives for solving this trick using XML ONLY!
FIRST ALTERNATIVE ( BEST OPTION )
We are going to use a FrameLayout which is a layout that add Views on top of each other. That means if you put the first then the second will be on top of the first etc.
Requirements
To fit an image well in a circular view then it should be SQUARE(this is just logical) so you we will need to set width and height equal values.
We will need a circular shape with stroke (The idea is to put it on top of a well calculated view sizes!)
Inside your drawable folder make a file called circular_image_crop.xml. And paste the code (dont worry will describe it later!) do not forget to read the comments in it:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#00ffffff"/>
<!--The above colour is completely transparent!-->
<stroke android:width="20dp" android:color="#ec407a" />
<size android:width="140dp" android:height="140dp"/>
</shape>
After making that drawable file we will have to make our FrameLayout (This frame layout is not a root view of any view just copy it inside any view you want to show this layout) Go on and paste the code below (we will explain it later!) again read the comments in it:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ec407a">
<!-- This is our framelayout! Notice our background color is the same as the one in the stroke of our drawable. Also this is your image view notice the it has width and height similar (square) do use match parent or wrap content just define a square and views will be position by adjust view bounds true-->
<ImageView
android:id="#+id/image_view_user_profile_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:adjustViewBounds="true"
android:contentDescription="#string/your_image_description"
android:src="#drawable/your_image" />
<!-- Ooh here we have another image! This is an image just for displaying our drawable and crop our image (how?? dont worry!) -->
<ImageView
android:layout_width="140dp"
android:layout_height="140dp"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/also_your_image_description_if_any"
android:src="#drawable/circular_image_crop" />
<!--This text view we almost forget here it is!-->
<TextView
android:id="#+id/your_text_view_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginBottom="8dp"
android:layout_marginTop="125dp"
android:gravity="center"
android:text="John Nanai Noni"
android:textColor="#ffffff"
android:textSize="16sp"
android:textStyle="bold" />
</FrameLayout>
How it works and customizations!???
The good thing is that we used our Frame Layout and position our real View at the centre horizontal(square image). The we made our drawable which is a circular and also have a circular hole(space) at the centre which matches the height and with our picture. Lastly we add our textview and put on top of all those but at the bottom (it should not obscure out image right?). So the way that we can understand this is viewing the following image as an outline to whats needed.(dont think its complicated):So from there we can see how it went on the image at the middle the Circular crop and etcThe next stage:From there we can apply the same background colour to our whole layout (FrameLayout) to hide the Circular things and leave our own visible space. And yes we have finished our layout! What about customization.
Customization
For colours you can put your own colour anywhere in the FrameLayout background well as well as the stroke of the drawable. But never change the <solid> colour it should always be completely transparent always.For customization of the radius of the circular crop lets dig into its mathematics formula to figure out the coverage of the image!Mathematics
Let your width or height(the image is square remember) of your image be x dps. Then the values in your drawable are
stroke= 0.2071 * x
size(height and width)=stroke + x
You can 2 or 3 dps for elimination of truncation errors!
Actually the mathematics behind is based on the formula below. The formula works if your interested how comment below:
SECOND ALTERNATIVE
Another alternative which I think is good for someone who DOES NOT care about the space between the circular view is by making the ImageView inside the CardView and making the corner radius half the size of the CardView for example this code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="280dp"
android:layout_height="280dp"
android:layout_gravity="center_horizontal"
android:layout_margin="30dp"
app:cardCornerRadius="140dp"
app:cardElevation="12dp">
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:src="#drawable/login_back_ground" />
</android.support.v7.widget.CardView>
This is an output I get In android Studio. Also I cant guarantee how is this is going to look like in various devices especially old ones!
CONCLUSIONBoth methods are good and useful. Understanding both can even lead to more customizations like making using the first alternative with the second to bring about customizations like adding elevations of circular image. But the first method fits number of daily uses and it also bring equal experiences to all android devices. I hope this will even help future users who might have the same problem.

Android App Background: using multiple images

I have a background image that's split into three separate images:
backgroundTop.png
backgroundMiddle.png
backgroundBottom.png
How would I go about implementing a background in an Android app in which the top image is displayed at the top of the application, and the bottom image at the bottom, and the middle image is tiled in between? This would of course depend on how much content is loaded on the screen - much like in web pages.
In other words, the total number of times the middle image is tiled will depend on what is on the screen.
I've seen a solution to implement a tiling background out of a single image here: How to make android app's background image repeat
This works fine if you are using a single picture, but not with multiple images.
Links to examples below so you know what I mean:
http://rockfreaks.net/images/reviewPageTop.png
http://rockfreaks.net/images/reviewPageMiddle.png
http://rockfreaks.net/images/reviewPageBottom.png
Think you can try combining layer list drawable (it's possible to set insets for layers) with a tiled bitmap drawable that is placed as a middle layer and positioned with appropriate insets.
Something like this:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/page_top" />
<item
android:insetTop="#dimen/page_top_height"
android:insetBottom="#dimen/page_bottom_height"
>
<bitmap
android:src="#drawable/page_middle_tile"
android:tileMode="repeat"
/>
</item>
<item android:drawable="#drawable/page_bottom" />
</layer-list>
But it all depends on your layout indeed.
Set the background as the middle image and tile it. (like in the example you show)
Create a header view that you insert at the top of each page.
Create a footer view that you insert at the bottom of each page.
And have your content in the middle.
I've made it a flat file here, but you can easily imagine refactoring it into includes, or whatever your application needs.
<?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"
android:background="#00FF00" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dip"
android:layout_alignParentTop="true"
android:background="#FF0000" />
<!-- Your content -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dip"
android:layout_alignParentBottom="true"
android:background="#0000FF" />
</RelativeLayout>
Red = Header
Green = Tiles (which would be inherited from your Theme)
Blue = Footer
Try something like this :
Top and bottom in two layouts with android:gravity="TOP" and "BOTTOM". These two layouts are set up with android:background="#drawable/xxx.png"
For the center, either use your solution or maybe use a ScrollView.

How to wrap content views rather than background drawable?

How can I get a LinearLayout (or any other ViewGroup) to assume the size of it's child views rather than assuming the size of the background image?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/large_image300x300pix">
<TextView android:id="#+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello world!"/>
</LinearLayout>
The linear layout becomes the same size as the background image.
How can I get my linear layout to assume the same size as the textview?
OK, so this thread is a little old, but I have a solution that someone might someday find useful. I think Android has problems scaling large images down, so the LinearLayout size ends up getting bumped by the background drawable bitmap, and the ImageView ends up forcing up the size of the parent container.
Unless you use a relative layout. You can make the ImageView relative to the position of the LinearLayout, even when the ImageView is behind the layout in the parent. My solution looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:src="#drawable/activation_popup"
android:scaleType="fitXY"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignTop="#+id/activation_layout"
android:layout_alignBottom="#id/activation_layout"
android:layout_alignLeft="#id/activation_layout"
android:layout_alignRight="#id/activation_layout"
android:contentDescription="#string/act_code_label" />
<LinearLayout
android:id="#id/activation_layout"
android:clipToPadding="true"
android:padding="25dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- LinearLayout wraps a bunch of smallish views here -->
</LinearLayout>
</RelativeLayout>
I tried this on a top of display sizes and OS versions, seems to work great. Note that the padding in the LinearLayout is a trick to make space for a shadow border in the background image graphic. The LinearLayout doesn't need any relative positioning because top left is assumed.
You can create a FrameLayout and put an ImageView and your LinearLayout there. So you'll be able to configure the layout of your background image.
This happens because the Android view calculates its minimum size based on its background drawable size.
Check my answer here in this another post which covers the same problem which will help you to achieve your layout configuration.
If your image lends itself to being converted to a scalable 9-patch image, then doing that would cause the background to scale around the TextView.
I believe the best solution here is to set android:clipToPadding="true". What this does is excludes the padding for the main layout and wraps your layout to its children.

Android ImageView not stretching vertically in ListView row

I have been struggling with this for several days now and I ran out of ideas.
In my listview, each row can have a vertical bar flushed left with a different color depending on status. That "bar" has no other purpose than visual representation of status and is not clickable.
I implemented the vertical bar using an ImageView with background set to a drawable which has the desired color. The problem is that the vertical bar doesn't stretch, it's only 1 pixel high even though I specified fill_parent.
The row layout is like this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/id1"
android:scaleType="fitXY"
android:layout_width="5dp"
android:layout_height="fill_parent"
android:background="#drawable/d1" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/id1">
...
(leaving content of the second relative layout out on purpose for simplicity)
My drawable d1 looks like this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#color/c1" />
<corners android:topRightRadius="5dip" android:bottomLeftRadius="5dip" />
</shape>
So,
Why isn't the ImageView stretching vertically?
Is there a better way to implement
this than using an ImageView? (I
tried a simple View with a
background color but it doesn't show
up at all)
Any help greatly appreciated. Thanks
First off, you may as well be using a horizontal LinearLayout here instead of a RelativeLayout (since you only have two children anyways, you're not really saving any layout complexity the way you're using it).
Changing to a LinearLayout may fix this, but I suspect you may be running into a specific issue when it comes to matching heights on inflated RelativeLayouts as rows; see the comments on the answer to this SO question and this SO question.

Overlapping Views in Android

Is it possible to have overlapping views in Android? I would like to have an ImageView with a transparent png in the front and another view in the background.
edit:
This is what I have at the moment, the problem is that the image in the imageView is not transparent, the parts that should be transparent are just black.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/gallerylayout"
>
<Gallery android:id="#+id/overview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ImageView android:id="#+id/navigmaske"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="#drawable/navigmask"
/>
</RelativeLayout>
edit:
I got it to work, it was a theme file from another programmer on the team.
Just changed this
<item name="android:background">#FF000000</item>
to this
<item name="android:background">#00000000</item>
Android handles transparency across views and drawables (including PNG images) natively, so the scenario you describe (a partially transparent ImageView in front of a Gallery) is certainly possible.
If you're having problems it may be related to either the layout or your image. I've replicated the layout you describe and successfully achieved the effect you're after. Here's the exact layout I used.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gallerylayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Gallery
android:id="#+id/overview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ImageView
android:id="#+id/navigmaske"
android:background="#0000"
android:src="#drawable/navigmask"
android:scaleType="fitXY"
android:layout_alignTop="#id/overview"
android:layout_alignBottom="#id/overview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</RelativeLayout>
Note that I've changed the parent RelativeLayout to a height and width of fill_parent as is generally what you want for a main Activity. Then I've aligned the top and bottom of the ImageView to the top and bottom of the Gallery to ensure it's centered in front of it.
I've also explicitly set the background of the ImageView to be transparent.
As for the image drawable itself, if you put the PNG file somewhere for me to look at I can use it in my project and see if it's responsible.
Also, take a look at FrameLayout, that's how the Camera's Gallery application implements the Zoom buttons overlay.
If you want to add your custom Overlay screen on Layout, you can create a Custom Linear Layout and get control of drawing and key events. You can my tutorial- Overlay on Android Layout-
http://prasanta-paul.blogspot.com/2010/08/overlay-on-android-layout.html
The simples way arround is to put -40dp margin at the buttom of the top imageview
A visible gallery changes visibility which is how you get the gallery over other view overlaps. the Home sample app has some good examples of this technique.
Now with Jetpack Compose in android, you should use Box for overlapping views.
Example.
Box(modifier = Modifier.fillMaxWidth().fillMaxHeight()){
RecipesList(viewModel.recipes.value)
Snackbar()
}
Here RecipesList and Snackbar are composabes positioned one on top of the other in the composition order
Check out this for Jetpack Compose samples - https://androidlearnersite.wordpress.com/2021/08/03/jetpack-compose-1-0-0-sample-codes/
Yes, that is possible. The challenge, however, is to do their layout properly. The easiest way to do it would be to have an AbsoluteLayout and then put the two images where you want them to be. You don't need to do anything special for the transparent png except having it added later to the layout.

Categories

Resources