Placing text view over an image view using FrameLayout - android

Below is how I have designed my xml. Now what I am trying to fit a textview inside the white box shown below. But am being restricted by FrameLayout (at least I think so) that I need to hard code values to make the text view fit in the middle or some where inside the white box. I cannot use Relative or other layouts for this purpose as I have understood by my trials as this whole is a single image.
Here is my layout,
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:visibility="visible" android:layout_marginTop="60dip"
android:layout_gravity="center" android:id="#+id/xxx">
<ImageView android:id="#+id/calloutquizImage"
android:background="#drawable/callout" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:scaleType="fitCenter" />
<ImageView android:id="#+id/triviaImage"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignTop="#+id/calloutquizImage" android:layout_gravity="left"
android:src="#drawable/trivia" android:background="#drawable/trivia"
android:layout_marginTop="50dip" android:layout_marginLeft="85dip"></ImageView>
<TextView android:text="TextView" android:id="#+id/triviAnswerText"
android:layout_marginTop="125dip" android:layout_marginLeft="85dip"
android:layout_gravity="left" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:textColor="#000000"
android:typeface="sans"></TextView>
<ImageButton android:id="#+id/triviaanswercloseButton"
android:src="#drawable/closebtn" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:background="#drawable/closebtn"
android:layout_marginRight="8dip" android:layout_marginTop="43dip"
android:layout_gravity="right" android:onClick="triviaanswerClose"></ImageButton>
<ImageView android:id="#+id/buttontoclose"
android:layout_gravity="left"
android:visibility="visible" android:onClick="triviaanswerClose"
android:layout_marginTop="50dip" android:layout_marginLeft="75dip"
android:layout_width="230dip" android:layout_height="170dip"></ImageView>
</FrameLayout>
Because of this the text view looks in different positions in various handsets.
Any guesses what can be done for this instead?
Below is my image :

I think you are not doing the right thing. If you want a text to appear inside a white box (or even resize it, if there is to many text to fit to it) - you can still avoid any layouts ad do it with only one TextView.
Please have a look what is NinePatch image in Android:
http://developer.android.com/reference/android/graphics/NinePatch.html
http://developer.android.com/tools/help/draw9patch.html - drawing tools
So basically you will need only 1 textView and your image, properly converted to 9-patch with 2nd link. (Basically - just add a few black pixels on image border).
No just set this 9-patch as a background of textView. It will place text right where you need, and will shrink white box if you'll define so in 9-patch.
UPD:
Please find the resulting screenshot:
As you can see, textView not handles
WhiteBox" itself, filling it with text and resizing the box if necessary.
Here is how to make it work:
<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">
<TextView
android:id="#+id/first"
android:background="#drawable/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Manymanymany text
Manymanymany text
Manymanymany text
Manymanymany text
Manymanymany text
Manymanymany text" />
<TextView
android:layout_below="#+id/first"
android:background="#drawable/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Not so many text" />
</RelativeLayout>
And here is your image, converted to 9patch. Just place it to "drawable/" folder. Note: it MUST have "back.9.png" name.
For details of how 9patch works you can check links above. The main idea: by making black dots on left and top border - you specify which part of the image will be stretched when image must be upscaled. By making dots on right/bottom side you tell the View where to place the content. In our case content is a text of the TextView.
Hope it helps, good luck

I think you can use a RelativeLayout within the FrameLayout for the ImageView and the TextView, and by using the parameters, you can navigate the TextView to the white box. Refer to the LayoutParams documentation for details.
for eg. you can add the ImageView block first and then the TextView, so that the TextView will lay over the ImageView, and by using align bottom, and specifying top margin with a negative value, you can make the TextView go over the image. Or rather, if you are using eclipse, you can directly move the text view in the graphic layout.
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools"
android:id="#+id/xxx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="0dp"
android:visibility="visible" >
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margintop="0dp" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/user2" />
<TextView
android:id="#+id/Textviewtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world"
android:layout_below="#+id/imageView1"
android:layout_marginTop="-10dp"
app:context=".TestActivity" />
</RelativeLayout>
</FrameLayout>
Similar to above, you can specify margin left and right to properly position your TextView as you want. Check with graphic layout for feedback to know the correct position.
Please reply if this helped.
Use your images and values for the height and width. I just tried for testing.

Related

Relativelayout position view between two views

so I'm currently working on an app on Android, and I got stuck on a specific problem regarding the RelativeLayout, which I can't find a way to solve.
I have in the layout three views as follows: TextView, Textview and ImageView (laid horizontally), here is a screenshot of the ios counterpart:
the Textview at the middle should stick to the first one, until he gets to the Imageview, when he does, he keeps his minimum size (wrap content), while the first Textview truncate.
On IOS I setted priorities to the constraint to accomplish this, but I can't figure out how to solve this on Android.
Here what I tried:
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#drawable/daily_movie_title_box">
<TextView
android:id="#+id/daily_header_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
android:text="New Text aawi oa ioawfwi"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#color/white"
android:lines="1"
android:singleLine="true"
android:layout_alignParentStart="true"
/>
<TextView
android:id="#+id/duration_text"
android:text="138 mins"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:textSize="13sp"
android:textColor="#color/white"
android:lines="1"
android:layout_alignBaseline="#id/daily_header_textview"
android:layout_toStartOf="#+id/certification_icon"
android:layout_toEndOf="#id/daily_header_textview"
/>
<ImageView
android:id="#id/certification_icon"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:src="#drawable/uk12a"
android:layout_alignBottom="#id/daily_header_textview"
app:layout_aspectRatio="100%"/>
</android.support.percent.PercentRelativeLayout>
Which resulted in this (which is what I want):
But when I increase the first Textview text it's not behaving as I desire...
Is it possible to achieve the behaviour I want in Android (keep the middle Textview wrap content, and truncate the first one if needed)?
I will post an update if I find a solution eventually, just wanted to see if anyone can find an easy way to achieve this behaviour, as I suspect there is.
Thanks.
From my understanding, you want the first TextView to be as large as possible, without adding space after the text if the text is too small. The second TextView should only wrap_content, but it should fill the rest of the parent layout when the row doesn't. The ImageView is set to wrap_content.
I tested it with this layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0"
android:stretchColumns="1">
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="Shrinking text dddddddddddddddddddddd"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Midle column"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher"/>
</TableRow>
</TableLayout>
</LinearLayout>
The only problem is that if the second column has a incredibly large text, it will push the other views out of the parent. But in your case, I don't think that will be a problem. Otherwise, I think it does the job.
These are some suggested solutions:
You can use LinearLayout with horizontal orientation and weight for each component (TextViews and ImageView).
You can set the minimum and maximum text length for the second TextView.
But i prefer to apply the first solution. You can assign a weight for each component ( amount of space on the screen ) using:
android:layout_height

Keep ImageView on the right size of the text and yet prevent long text to push it out of view?

The situation is the same no matter if I use LinearLayout or RelativeLayout. I think this is a old Android XMl bug, but I have no idea why it still exists.
Namely, in a layout where an ImageView is on the right side of a TextView can disappear from the screen when text becomes too long. It simply pushes it off the screen. I must NOT make TextView single line.
Here is the XML.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="some long text blahblahblahblahblah"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="17sp"
android:layout_marginRight="10dp"
android:layout_centerVertical="true"
/>
<ImageView
android:layout_toRightOf="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/key"
android:layout_centerVertical="true"
/>
</RelativeLayout>
I cannot use layout_weight attribute as image will then stick to the right side of the screen. It HAS to be on the right side of the text.
Anyone has any ideas how to solve this bug?
Check images when the text is short and long. On the 2nd image the text is long and the image is being pushed away from the screen.
You can achieve your task, if you use the layout_weight properly. Please refer the code below:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="The quick brown fox jumps over the lazy dog. As you can see it easily handles the long length of the text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="17sp"
android:layout_marginRight="10dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher"
/>
</LinearLayout>
The output for long text:
The output for short text:
EDIT:
This works because of the layout whose width is set as wrap_content. If it were match_parent then in all cases, all the extra space would have been given to TextView because of it's layout_weight but since the parent is wrap_content, there is no extra space for the TextView to fill when the text is small. But when the text is large, the weight property is applied to the TextView but since there is no layout_weight for the ImageView hence, it takes only the amount of space it has to.
Set
android:layout_marginRight="30dp"
for the TextView
and
android:layout_marginLeft="-20dp"
for the ImageView
You can change the values depending on your needs.
But, if the image can have different sizes, you will have to set margins programmatically.
there is 2 solutions for these
either set the image as a drawableRight to the textview
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="The quick brown fox jumps over the lazy dog. As you can see it easily handles the long length of the text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="17sp"
android:layout_marginRight="10dp"
android:drawableRight="#drawable/ic_launcher"
/>
or
alignt the image to right and make textview toleft of the image

Why are my "centered" objects slightly off-center in my RelativeLayout?

I wanted to make two equally-sized radio buttons with a custom background, text, and an image to the right of the text. Because of how different these are from a standard "Button", I made them using a clickable "RelativeLayout".
The text and the image are of different heights, but I want each one to be centered vertically in the button. I also want the combination of the text+image to be centered horizontally in the button. This second part is what I'm having trouble with; it's off-center, close to the left side. In the image below, the left side is what I want, but the right side is what's happening. The image on one of the buttons (the one with the longer text) is resized to be smaller, too... Though there is still plenty of space on the right side of the button.
Here is my code:
<LinearLayout
android:baselineAligned="false"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:id="#+id/my_button"
android:background="#drawable/radio_button"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<TextView
android:id="#+id/button_textview"
android:text="#string/button_label"
android:textAppearance="?android:attr/textAppearanceButton"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
<ImageView
android:contentDescription="#string/image_description"
android:id="#+id/button_imageview"
android:layout_centerVertical="true"
android:src="#drawable/my_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/button_textview">
</ImageView>
</RelativeLayout>
<RelativeLayout
... same thing for the second button ...
</RelativeLayout>
</LinearLayout>
What am I doing wrong?
Use this as your button:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="MyButton"/>
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="#drawable/my_image"/>
</LinearLayout>
Now, you can place it in other parent views. To apply layout attributes to above button, place those attributes in the outer <LinearLayout> tag of above button.
Alternative:
You can set custom images to be drawn on sides(Left,Right,Top,Bottom) of a TextView using attributes like:
android:drawableLeft="#drawable/my_image"
Turns out the solution was adding
android:paddingRight="0dip"
strangely enough, even though I didn't put any padding there in the first place.

Android View Layout Scaling bitmaps

I'm working an a layout which I will have a bitmap centered, and I'd like the left & right margin bitmaps to scale (horizontally) to fill the screen, such that my center item can be a decorated titlebar, and the left & right are filler bitmaps that match the center bitmaps background, and thus stretching horizontally.
But what I'm seeing is there is a space between the bitmaps. The left & right scale, but there is a space between them.
Eg what I'm getting is:
http://www.58seconds.com/getting.png
What I want is:
http://www.58seconds.com/want.png
Any ideas?
Here is a snippet of the Layout code I use:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:layout_width="1dp"
android:layout_weight="1"
android:layout_height="45sp"
android:src="#drawable/mdjleftfiller"
android:layout_gravity="top"
android:gravity="top"
android:scaleType="fitXY"
/>
<ImageView
android:id="#+id/command_selection_topImage"
android:layout_width="wrap_content"
android:layout_height="45sp"
android:src="#drawable/top_image"
android:layout_gravity="top"
android:gravity="top"
android:layout_weight="0"
/>
<ImageView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="45sp"
android:src="#drawable/mdjrightfiller"
android:layout_gravity="top"
android:gravity="top"
android:scaleType="fitXY"
/>
</LinearLayout>
Have you thought about creating a 9-patch with your single title bar image? If you have your "stretched" parts on either side of the actual title it will stretch to fit whatever you want without resorting to layout trickery.
Try creating two images, one as a background and scaleType to FIT_CENTER, then set the other one to lay on top and just move to the center.
Here's a nice clean way of doing this, that is pretty much exactly what Lucas was talking about, but in xml:
<FrameLayout android:id="#+id/navbar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#drawable/titlebar_repeat">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="#drawable/titlebar_logo" android:layout_gravity="center" />
</FrameLayout>
In this case titlebar_repeat is just a single pixel wide, and titlebar_logo is just the text with a transparent background. In your case, since you don't seem to want highly stylized text, you could probably just make the ImageView a TextView instead if you like.

How do I vertically align an item within a list using relative layout?

I am using a list view in Android 1.5 to show a list of images and text next to the image. I am trying to vertically center the text but the text is at the top of the row instead of centered. Below is my layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip">
<ImageView android:id="#+id/item_image" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:paddingRight="10dip"
android:src="#drawable/default_image" android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"/>
<TextView android:id="#+id/item_title"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="#id/item_image"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"
/>
</RelativeLayout>
It seems strange that I need to set alignParentTop="true" when I'm trying to vertically center the text, but if I don't the text does not even show up. What am I doing wrong?
EDIT following the comments:
It turns out making this work with RelativeLayout isn't easy. At the bottom of the answer I've included a RelativeLayout that gives the effect wanted, but only until it's included in a ListView. After that, the same problems as described in the question occurred. This was fixed by instead using LinearLayout(s).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:orientation="horizontal">
<ImageView android:id="#+id/pickImageImage"
android:layout_width="100dp"
android:layout_height="80dp"
android:background="#drawable/icon"
android:scaleType="fitXY"
android:layout_marginRight="10dp"/>
<TextView android:id="#+id/pickImageText"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:gravity="left|center_vertical"
android:text="I'm the text"/>
</LinearLayout>
If you want to have two text boxes, you can nest a second orientation="vertical" and LinearLayout after the ImageView and then put the text boxes in there.
This works, but I have to admit I don't know why the RelativeLayouts didn't. For example, this blog post by Romain Guy specifically says that the RelativeLayout should. When I tried it, I never got it to quite work; admittedly I didn't do it exactly as he did, but my only changes were with some attributes of the TextViews, which shouldn't have made that much of a difference.
Here's the original answer:
I think you're confusing Android with all those somewhat contradictory instructions in RelativeLayout. I reformatted your thing to this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/row"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip">
<ImageView android:id="#+id/item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dip"
android:src="#drawable/icon"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
<TextView android:id="#+id/item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/item_image"
android:layout_centerVertical="true"
android:text="Blah!"/>
</RelativeLayout>
And that works fine. I removed many of your redundant android:layout_alignParentxxx because they weren't necessary. This view now comes up with the picture in the top left corner and the text vertically centered next to it. If you want the picture vertically centered as well, then you can't have the RelativeLayout be on android:layout_height="wrap_content" because it's trying to make itself no taller than the height of the picture. You'd have to specify a height, e.g. 80dp, and then set the ImageView to a fixed height like 60dp with android:scaleType="fitXY" to make it scale down to fit properly.
Was stuck on a similar issue for a while, but found this from CommonsWare:
"When you inflate the layout, use inflate(R.layout.whatever, parent, false), where parent is the ListView."
Works but only when you set the height of the row to a specific value (ie you can't use wrap_content).
Baseline directive would do it, but ImageView simply does not support baseline alignment as of today. You can work around this by creating a subclass of ImageView, override the getBaseline() method and return the height of the image.

Categories

Resources