I am trying to insert an imageView into a Relative/Linear layout in such a way that the imageView is larger than the parent. So far I have tried a negative margin and padding on the imageView and set clipChildren to false on the parent, but nothing seems to help. Has anyone done something like this before?
<FrameLayout 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">
<LinearLayout
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_gravity="center"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/text_black"
android:paddingBottom="-100dp"
android:paddingLeft="-100dp"
android:paddingRight="-100dp"
android:paddingTop="-100dp"
android:src="#drawable/logo"/>
</LinearLayout>
</FrameLayout>
Basically I am trying to achieve something like this...
state1 - Has a series of viewgroups. When I click on one of them, I get state 2 where the image inside the viewgroup is visible fully and overlaps any of the surrounding viewgroups without affecting their position.
so why don't u just give parent to Width and Height= wrapcontent
The size of the container is limited by teh Parent, so it is not possible to put a container inside that is larger (you couldn't put a 5 liter box inside a 3 liter box).
ImageView has an "scale" attribute that will clip or adjust your view (and keep it sized appropriately).
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
Related
I would just like to know if every time I need to set the View's size (width or/and height) as a function of its parent size (e.g. width = 0.5 * parent_size), I have to create a custom View and override onMeasure() or is there a way to do it using XML?
Thank you in advance!
Edit:
What I'd like to achieve is something like : place a view left aligned, with a width equals to 1/10th of the parent width and a height equals to 1/5th of the parent height. So on for other Views.
Here is an answer with two nested LinearLayouts and a TextView in the upper left corner, the TextView is 10% of width and 10% of height.
Just to prove it works with only one view.
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:weightSum="10"
android:background="#FF0000"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="0dp"
android:orientation="vertical"
android:weightSum="10"
android:background="#00FF00"
android:layout_weight="1"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
android:layout_weight="1"
android:text="Hello"
android:textColor="#FFFFFF"
/>
</LinearLayout>
</LinearLayout>
you can use LinearLayout as a container and android:layout weight attribute for example. You can read more here: developer.android.com/guide/topics/ui/layout/linear.html#Weight
So, if you want to add only one element, you can add your view with weight=1 and one element with weight=9. But if you want to add 10 view in one row (1/10 of height for each) - you can use GridView for that or TableLayout.
I have to create a custom View and override onMeasure() or is there a
way to do it using XML?
There are no such way to achieve you goal using XML Layout file.
You have to manage this view dynamically .Your second approach is right approach .
You need to create dynamic view and make onMeasure() method according to your functions.
I have an imageview that I want to fill it's parent RelativeLayout to act as a background image.
The image is the correct size until the other views in the relative layout expand, and thus expand the size of the entire layout (just height in my case) (ie: a large string from the internet has been loaded into a textView). Then the image view doesn't grow to continue matching the parent. Is that expected behavior and if so, how do we get around it?
Here's my layout code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/parentLayout">
<my.BlurredImageView
android:scaleType="centerCrop"
android:id="#+id/profile_bg"
ImageUrl= "Avatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
<LOTS AND LOTS OF OTHER VIEWS>
OK I am sure you know this already, but for thoroughness I thought I should mention that the easiest way to set the background of the relative layout is directly in the background field:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="drawable file or file from internet you load programatically"
android:id="#+id/parentLayout">
Now to your question. If for whatever reason you really need an imageView as a background, then use the width and height as 0dp because you are aligning to parent on all 4 sides. See if this makes a difference:
<my.BlurredImageView
android:scaleType="centerCrop"
android:id="#+id/profile_bg"
ImageUrl= "Avatar"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
/>
To check the actual size of the image view, and whether it fills your relative layout, the most practical way would be to make the background of the RelativeLayout bright green, and the background of the imageView bright Orange. Then you always know exactly where they are :-)
How to show a vertical line on the background, such as the one highlighted in blue on the image below?
In this example, I have a ListView with ImageView elements (and TextView, but it is not related to the line), and I want a vertical line on the background of these items to feel like they are "connected" to each one.
And also, note that the vertical line does not fill all the background.
The vertical line is on the left, and it is not equal for the all cases. Sometimes it fills all the row height (in most of ListView rows) and sometimes it just fills the half of row height (in the last item of the ListView and outside of the ListView, on the top, where we can see the big ImageView with the star icon).
Updated
I tried the suggestion proposed by Hellboy, and it almost work perfectly. I modified the proposed code for my case:
<RelativeLayout
android:layout_width="40dp"
android:layout_height="match_parent"
android:gravity="center"
android:layout_marginLeft="15dp">
<View
android:layout_width="4dp"
android:layout_height="match_parent"
android:background="#3399CC"
android:gravity="center"
android:layout_centerHorizontal="true"/>
<ImageView
android:id="#+id/user_image"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:gravity="center"
android:background="#android:color/holo_blue_light" >
</ImageView>
</RelativeLayout>
the RelativeLayout with the width="40dp" (the same as the original ImageView I was working with), height="match_parent (the same as he said), gravity="center" (to let them in the center of the row height) and layout_marginLeft="15dp" (to let a space to the left margin). In the ImageView, I added marginTop="10dp" and marginBottom="10dp", and with it, the blue vertical line appears. But I have other elements in the same row, so I have a parent layout (a linear layout). My parent layout is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center"
android:id="#+id/linearlayoutservicerow">
So, this parent layout above, has the described RelativeLayout and other LinearLayout with the other row elements. But the code results in flattened images. Why does this happen?! It seems like the RelativeLayout consider its height as the ImageView height (40dp) and does consider its marginTop and marginBottom, and with this the image is flattened.
Waiting more answers to this problem. I'll try another alternatives.
You can replace your ImageView with something like this:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="4dp"
android:layout_height="match_parent"
android:background="#color/navy_blue"
android:layout_centerHorizontal="true"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/image"/>
</RelativeLayout>
and of course in your first and last element you need to manipulate the height of the View and align it to Top or Bottom
I got it.
I've persisted in trying to fix the problem of the Updated section of my question (based on the solution initially proposed by #Hellboy) and I got results! So, how I achieved an answer to my own question, I decided to put as an answer.
The first step was to configure the XML file such as the code below.
Part of the final XML corresponding to the row layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center"
android:id="#+id/linearlayoutservicerow">
<RelativeLayout
android:layout_width="40dp"
android:layout_height="match_parent"
android:gravity="center"
android:layout_marginLeft="15dp">
<View
android:layout_width="4dp"
android:id="#+id/verticallineview"
android:layout_height="match_parent"
android:background="#3399CC"
android:gravity="center"
android:layout_centerHorizontal="true"/>
<RelativeLayout
android:layout_width="40dp"
android:layout_height="match_parent"
android:gravity="center"
android:paddingBottom="10dp"
android:paddingTop="10dp">
<ImageView
android:id="#+id/user_image"
android:layout_width="40dp"
android:layout_height="40dp"
android:gravity="center"
android:background="#android:color/holo_blue_light" >
</ImageView>
</RelativeLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/layoutotherrowelements">
</LinearLayout>
</LinearLayout>
Explaining the XML:
Here we have the parent layout (linearlayoutservicerow) and inside it: a RelativeLayout (proposed by #HellBoym, with the structured discussed in the final of my question) and the LinearLayout to other elements of the row (layoutotherrowelements). Summarizing... What I modified?
The initial code resulted in flattened images because the RelativeLayout (parent) did not consider the ImageView marginTop and marginBottom, so the image was flattened vertically. (And if we let without margin, the RelativeLayout would mantain the same size and the vertical line would not appear on the top and on the bottom of image.) We must have a space between the ImageView and the RelativeLayout initially proposed, in order to show the line, but if it does not recognize the margin, how to create this space?
I just "encapsulated" the ImageView in another RelativeLayout (inside that parent RelativeLayout), and changed the margin parameters of the ImageView to padding parameters of this capsule RelativeLayout.
The problem of the last row
It results in the layout with a line background, but we still have the problem of the last row. In fact, this row is different, and in this case, it must have its height modified to not have the same parent's height. I decided to put at least, the ImageView's height and it worked! Remember to convert the value in dp to pixel, because the function getLayoutParams has all parameters expressed in pixels.
So, in the Adapter, we put the following code:
if(position==(getCount()-1)){
View my_line = (View)
row.findViewById(R.id.verticallineview);
//40dp, this is the ImageView height
int dpsize = 40;
//convert the height in dp unit to pixel (because the parameter is in px)
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpsize, context.getResources().getDisplayMetrics());
my_line.getLayoutParams().height = px;
}
And that is it!!!
It is worth mentioning that #dinesh sharma proposed other interesting alternative using 9-patch, that I will try later.
I did not want to use image as background (that is why I started asking about drawable), because my final goal was to improve this solution to make all dynamic (including the vertical line color), and I believe with image I could not achieve it. But in my original question I did not mention that, so if I have success with this other approach, I will accept it as correct answer.
Thanks for all your help! In my current solution I used the #Hellboy's clue of using a RelativeLayout and a View, and the #dinesh sharma's clue to verify if it is the last row of the ListView. I hope this answer and the others helps more people with similar problems.
You can use transparent 9-patch image as a background for you list view.
For creating nine-patch image please follow this:
http://developer.android.com/tools/help/draw9patch.html
Now verified answer
your image in item layout:
<RelativeLayout
android:id="#+id/rl"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="#drawable/m"
android:paddingBottom="10dp"
android:paddingTop="10dp" >
<ImageView
android:id="#+id/grid_item_image"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
three bg nine patch images for drawable
Handling in Adapter:
if(position==0)
holder.rl.setBackgroundResource(R.drawable.b);
if(position==(getCount()-1))
holder.rl.setBackgroundResource(R.drawable.t);
Finaly got output:
First off, this is not a duplicate question, to best of my ability I've tried all (there are many) similar questions. Solutions to such problems appear to be very subjective, specific to a given scenario.
My layout currently appears as follows. Black boxes are images (logo and body, respectively), colours represent each layout:
My XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
android:padding="0px"
android:layout_margin="0px"
android:orientation="vertical">
<LinearLayout
android:layout_weight="16"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF"
android:gravity="top|center"
android:orientation="horizontal">
<ImageView
android:id="#+id/logo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/logo"
android:layout_gravity="top|center" />
</LinearLayout>
<LinearLayout
android:layout_weight="4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00F"
android:gravity="bottom|left"
android:orientation="vertical">
<ImageView
android:id="#+id/body"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/body"
android:layout_gravity="bottom|left" />
</LinearLayout>
</LinearLayout>
Here you can see I have a parent linear layout, split into two children linear layouts. This is because I need the images to be positioned differently within that part of the page.
In a nutshell, I need logo to be vertically aligned to the top, and body horizontally aligned to bottom-left.
Now, a few things that I've tried:
Using RelativeLayout rather than Linear
Switching gravity with layout_gravity for both LinearLayout and ImageView, along with combinations of excluding each
Fairly confident match_parent for width and height is what I want, but I have tried different combinations with wrap_content
What I've come to understand:
gravity:top requires the parent view use orientation:horizontal
gravity:left requires the parent view use orientation:vertical
gravity applies to the children of the view
linear_gravity applies how the child aligns with it's parent
Using the same value for gravity on the parent and linear_gravity on the child might have the same effect (when using one instead of the other)?
Hopefully this is enough information. I'm having a very difficult time wrapping my head around how these layouts work.
Thank you SO much for the help!
I think your problem is you are setting dimensions of the image views to match_parent. I would use a RelativeLayout as it seems to be the most efficient in your case (pseudo-XML-code):
RelativeLayout (width=match_parent, height=match_parent)
ImageView (width=wrap_content, height=wrap_content,
alignParentTop=true, centerHorizontal=true)
ImageView (width=wrap_content, height=wrap_content,
alignParentBottom=true, alignParentLeft=true)
You don't need any gravity setting here. You might want to play with the scaleType attribute depending on your image sizes.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/frameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background_gradient" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center" >
<ImageButton
android:id="#+id/buttonLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/log"
android:onClick="log" />
</RelativeLayout>
</FrameLayout>
I was expecting my button to appear in the center of the screen. However, it appears on the TOP center of the screen (that is, the button is center horizontally, but not vertically).
It seems to me that the RelativeLayout is behaving like it was defined with "wrap_content" instead of "fill_parent".
The funny thing is that, if I give an actual value to my RelativeLayout height property (android:layout_height), like:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="100dp"
android:gravity="center" >
Then the button behaves correctly (i.e. the button is also centred vertically). But I don`t want to use actual values. I want to use fill_parent! Why doesn't it work with "fill_parent" ??
Does anybody know what's going on?
Thank you in advance!
RelativeLayout requires you to specify the position of the elements in the Layout. I don't see any layout_below or layout_toLeftOf tags. Gravity works on LinearLayouts. In general, LinearLayouts are easier to work with, and they scale much better to different screen sizes. I suggest you replace the RelativeLayout by a LinearLayout, and also the FrameLayout by a LinearLayout. You use a FrameLayout typically if you want to use multiple overlapping layouts, which you don't do.
I recommend you read up on using layouts in the Android sdk reference documentation, like here: http://bit.ly/djmnn7
You specified fill_parent for both the layout_width and layout_height of your RelativeLayout, therefore it fills up it's parent view.
By default, a relative layout arranges it's children to the top-left corner, regardless you use fill_parent for the size.
You should achieve the desired aspect by taking advantage of the RelativeLayout's own attribute set, which helps you arrange the child views relatively to each other or to their parent:
<ImageButton
android:id="#+id/buttonLog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#drawable/log"
android:onClick="log" />
Using the android:layout_centerInParent you can achieve this. This attribute if set true, centers this child horizontally and vertically within its parent.