I am trying to layout a view that should wrap its content, but it shouldn't be more than ~100dp less than its parent width. How can I do that using a RelativeLayout or some other layout? What I have right now will always make the view 100dp less than its parent so that there is space for another view.
This picture is an example of what I have:
As you can see, the text doesn't fill the whole box, so it could be smaller. But, it should never be larger than 100dp less than its parent, so that there is room for the time the message was sent.
This is my 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="wrap_content"
android:clipChildren="false"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingRight="#dimen/horizontalMargin"
android:paddingTop="10dp">
<TextView
android:id="#+id/message_holder"
android:layout_toLeftOf="#id/blank"
android:layout_alignParentLeft="true"
android:layout_marginLeft="#dimen/horizontalMargin"
android:background="#drawable/message_corners"
style="#style/white_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="alsdkjf; alsdkf" />
<RelativeLayout
android:id="#+id/blank"
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_alignParentRight="true"
android:minWidth="100dp">
</RelativeLayout>
<TextView
android:minWidth="100dp"
android:id="#+id/time"
style="#style/gray_text"
android:layout_toRightOf="#id/message_holder"
android:paddingLeft="10dp"
android:text="Yesterday,\n11:30 PM" />
<RelativeLayout
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignBottom="#id/message_holder"
android:layout_alignParentLeft="true"
android:background="#drawable/triangle" />
</RelativeLayout>
I have tried using the "minWidth" property on a blank view to the right of the message box to provide spacing, but it doesn't resize to be larger (which would make the message box smaller). When I don't have the blank view, and simply place the time TextView to the right of the message box, then that TextView isn't visible when the message box expands.
Update:
This is my "message_corners.xml":
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#color/green" >
</solid>
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" >
</padding>
<corners
android:radius="10dp">
</corners>
</shape>
Update 2:
This is what I am looking for in a layout with short text:
And this is what I am looking for in a layout with long text:
Here you go, a layout that does exactly what you want.
<?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="wrap_content"
android:clipChildren="false"
android:paddingBottom="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp">
<RelativeLayout
android:id="#+id/blank"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#aaaaaa">
<LinearLayout
android:id="#+id/message_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="100dp">
<TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello?"
android:background="#00ff00" />
</LinearLayout>
<TextView
android:id="#+id/time"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/message_container"
android:layout_marginLeft="-100dp"
android:text="12:30 PM"
android:background="#ff0000" />
</RelativeLayout>
</RelativeLayout>
Short message
Long message
I know this is a really old question, but it's a frustrating problem I've encountered several times now and the existing answers weren't quite what I was looking for. Some colleagues and I came up with the following:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#FFFFFF">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#888888"
android:padding="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#00FF00"
tools:text="Short message."/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="0"
android:background="#CCCCCC"
tools:text="Yesterday,\n11:30pm"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#888888"
android:padding="10dp"
android:orientation="horizontal">
<TextView
android:id="#+id/message_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#00FF00"
tools:text="Super ultra mega awesome long message which is going to help us take over the world."/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="0"
android:background="#CCCCCC"
tools:text="Yesterday,\n11:31pm"/>
</LinearLayout>
</LinearLayout>
Which looks like this when rendered:
The magic seems to be the zero value for the weight of the text box on the right (in addition to the non-zero weight value of the text box on the left, which some of the other answers already have).
Honestly, I can't explain exactly why it works, but after having looked for a solution to this for so long I'm not questioning it! :)
As an aside, I like this approach because it doesn't require any explicit or minimum widths, any intermediate wrapper views, or the use of clipping settings, margins, padding, etc. to implement view overlay.
What the author of this question really asks is, how to let the TextView expand to fit the message inside of it without overflowing the time TextView, and without leaving blank spaces.
Since you don't actually know the width of the whole screen, you can't tell your TextView to be 100dp less than it.
What you should do is wrap your TextView in a container which will have the toLeftOf rule, with the TextView only wrapping it's contents. This way, the container will expand all the way up to the right (without overflowing the time TextView) but the TextView will only wrap it's text contents (so, it won't extend any blank spaces)
Code
Instead of
<TextView
android:id="#+id/message_holder"
android:layout_toLeftOf="#id/blank"
android:layout_alignParentLeft="true"
android:layout_marginLeft="#dimen/horizontalMargin"
android:background="#drawable/message_corners"
style="#style/white_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="alsdkjf; alsdkf" />
Use
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/blank"
android:layout_alignParentLeft="true"
android:layout_marginLeft="#dimen/horizontalMargin">
<TextView
android:id="#+id/message_holder"
android:background="#drawable/message_corners"
style="#style/white_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="alsdkjf; alsdkf" />
</LinearLayout>
By the way, your layout isn't very good. You should optimize it.
You can try the following arrangement of views and their widths:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
>
<FrameLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/holo_blue_bright"
tools:text="Some long test is this which is support to wrap at the end of parent view"
/>
</FrameLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
tools:text="Yesterday,\n 11:30 PM"
/>
</LinearLayout>
Sat Sri Akal
This can also be achieved using ConstraintLayout
with 2 children in horizontal chain
1st child
layout width 0
constraint weight 1
constraint max width wrap
2nd child
layout width wrap content
A solution with ConstraintLayout using
app:layout_constrainedWidth
layout_constraintHorizontal_bias
layout_constraintHorizontal_chainStyle
.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/edt_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample content"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="#id/button_right"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Right Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/edt_left"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
If you want to make time text on right and text message on its left, you can do something like that ( using this in relative layout) also you can use maxWidth not minWidth
<TextView
android:id="#+id/view_textView_timeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/view_textView_timeText"
android:maxWidth="100dp"/>
What you could do is put an empty view between the 2 views and keep its width as MATCH_PARENT and assign the textview to leftof this empty view and the empty view to left of the date view. Just make sure to keep the view empty.
As i understand you want to make the layout or the textview to be 100 dp less than the screen size
Which you can do by getting the screen width in pixels which is done by this
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Then you could set the textbiew width to be less 100dp from the screen size hope this help
P.s I think you might want to convert dp to px but i am not sure
You can do like this(not the direct answer for the question ):
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingLeft="45px"
android:text="asdfadsfsafasdfsakljkljkhjhkkhjkjhjkjhjkhjkhljkhlkhjlkjhljkhljkhlkjhljkhljkhlfasd"
android:textColor="#4a4a4a"
android:textSize="40px" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:paddingLeft="45px"
android:paddingRight="48px"
android:text="2017.08.09 13:00"
android:textColor="#9b9b9b"
android:textSize="34px" />
</LinearLayout>
I have a common solution to solve this kind of layout question:
Create a specific ViewGroup!
For the question above, the key point is how to set the correct maxWidth to the content view.
Create a SpecialViewGroup. The contentView is the left view, and the timeView is the right view.
class SpecialViewGroup #JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
private lateinit var contentView: TextView
private lateinit var timeView: TextView
override fun onAttachedToWindow() {
super.onAttachedToWindow()
contentView = findViewById(R.id.content)
timeView = findViewById(R.id.time)
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
// measure the timeView firstly, because the contentView's maxWidth rely on it.
timeView.measure(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
)
// then caculate the remained space for the contentView
val parentWidth = MeasureSpec.getSize(widthMeasureSpec)
val paddingHorizontal = paddingStart + paddingEnd
val view1MaxWidth = parentWidth - timeView.measuredWidth - paddingHorizontal
// set the maxWidth to the contentView
contentView.maxWidth = view1MaxWidth
// The rest thing will be handed over by LinearLayout
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
}
Use the SpecialViewGroup in your layout, like the usual LinearLayout.
<com.example.SpecialViewGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFBB86FC"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:id="#+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FF3700B3"
android:padding="10dp"
android:text="adaasdasdasasdadasdasdaaaaaaaaaaaaaaaa"
android:textColor="#color/white" />
<TextView
android:id="#+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#FF018786"
android:padding="10dp"
android:text="1970-01-01"
android:textColor="#color/white" />
</com.example.archview.SpecialViewGroup>
And the result:
The benefits of this approach are obvious:
No extra nesting Layout.
Common to solve the similar layout questions.
Had the similar issue. Made it works with constraint.
<ConstraintLayout>
<TextView
android:id="#+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
app:layout_constraintEnd_toStartOf="#+id/option_info"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_max="wrap" />
<ImageView
android:id="#+id/option_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_info"
app:layout_constraintBottom_toBottomOf="#+id/title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/title"
app:layout_constraintTop_toTopOf="#+id/title" />
</ConstraintLayout>
hi I am creating ListView with the two TextView in android.
The one contain the fix size and the other will occupied the remaining space of the screen.
The first which is fix size will display on the right side of the screen and other TextView will display data on the left of the screen.
How Can i do this?
isn't that ok?
<TextView
android:layout_height="wrap_content"
android:layout_width="480dp" />
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
Create a LinearLayout with horizontal orientation, and match_parent width.
Put both TextViews in it. For the first on, use android:layout_width and specify the value in dp if you want the buttons physical size to be the same on every screen, or in sp if you want it to scale according to screen resolution.
For the second TextView, use android:layout_width="match_parent".
Try this code...
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/textView1"
android:layout_width="70dp" //Set the dimension
android:layout_height="wrap_content"
android:text="Text1" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Text2" />
</LinearLayout>
Try this :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tv1"
android:layout_height="wrap_content"
android:layout_width="100dp"
android:text="dfafa"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="dfafa"
android:layout_toRightOf="#+id/tv1"/>
</RelativeLayout>
I have a Linear layout then programatically I'm adding some spinners and buttons and so on, but I have xml button Wrap content (width) and then on java I add spinner (or anything else) and it goes below this view even if both views are wrap content:
progBar = new ProgressBar(this);
pBarToca = new ProgressBar(this);
pBarToca.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
linToca = (LinearLayout) findViewById(R.id.tetoca);
linToca.addView(pBarToca);
and it's placed under the button of xml:
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" android:layout_marginTop="6dp"
android:id="#+id/tetoca">
<TextView style="#style/StylePartida"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/te_toca_jugar" />
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#A7E9A9" android:onClick="callJugar"
android:text="#string/jugar" />
</LinearLayout>
edit!!!!!!
I want textview on first line then on next line button + progressbar (for example)
You have android:orientation=vertical so the Views will be laid out starting at the top and going down.
If you want them to all be next to each other, remove that from your xml since the default orientation for a LinearLayout is horizontal. If you do this, you will obviously need to change the android:width to wrap_content for your TextView or else it will take up the entire screen.
After your comment, a RelativeLayout would work best here.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
style="#style/StylePartida"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/te_toca_jugar"
android:id="#+id/tvID" /> // give it an id
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:id="#+id/tetoca"
android:layout_below="#/id=tvID"> // place it below the TV
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#A7E9A9" android:onClick="callJugar"
android:text="#string/jugar" />
</LinearLayout>
</RelativeLayout>
Note the changes in the comments. Now when you add your progressbar to the LL, it should be next to the Button. You may need some changes but this should give you approximately what you want.
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:id="#+id/tetoca">
<TextView style="#style/StylePartida"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/te_toca_jugar"
android:text="#string/te_toca_jugar" />
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#A7E9A9" android:onClick="callJugar"
android:text="#string/jugar" />
</LinearLayout>
In your textView you are matching the parent
android:layout_width="match_parent"
This will cause the textview to take up the entire width of the parent view.
android:layout_width="wrap_content"
and
android:orientation="horizontal"
android:orientation="vertical" will cause the elements to be stacked.
If you are using "horizontal" it's important not to have a child element with width matching parent.
EDIT:
After OPs change to question:
I have used a textview, two buttons and listview to give you an idea of how you can format it. There are many ways to achieve the same thing, this is one suggestion.
The internal linearlayout has a horizontal orientation (by default).
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="te_toca_jugar"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#A7E9A9"
android:text="jugar"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#A7E9A9"
android:text="jugar2"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/lv">
</ListView>
</LinearLayout>
</LinearLayout>
I have a ScrollView that I am trying to populate dynamically. Here is the XML that contains the ScrollView:
<?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="#f6f5f5" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#40ff0000"
android:paddingBottom="70dp"
android:paddingTop="20dp"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<LinearLayout
android:id="#+id/option_list_container"
android:background="#40ffff00"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:background="#292929"
android:paddingBottom="5dp"
android:paddingLeft="15dp"
android:paddingTop="5dp"
android:text="Stap 3/5"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#color/white" />
</LinearLayout>
</ScrollView>
And here is the XML for the element I'm inserting in the ScrollvVew:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<np.custom.FontIcon
android:id="#+id/option_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/calendar_circleround"
android:textSize="40sp"
android:gravity="center"
android:text="#string/planit_selection_empty_circle"
android:textColor="#292929" />
<TextView
android:id="#+id/option_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
This is the code I use to populate the scrollview:
ArrayList<String> g = new ArrayList<String>();
g.add("Fix a Bug");
g.add("Buy a new PC");
g.add("Make Coffee");
g.add("Take a Break");
g.add("Don't do that");
g.add("Throw your hands in the air like you just don't care!");
LinearLayout optionListLayout = (LinearLayout) rootView.findViewById(R.id.option_list_container);
LayoutInflater inflater = LayoutInflater.from(getActivity());
for(String p:g){
View v = inflater.inflate(R.layout.planit_option_item, null);
TextView optText = (TextView) v.findViewById(R.id.option_text);
optText.setText(p);
optionListLayout.addView(v);
}
This all works almost fine, except that the sizes of the ScrollView and the LinearLayout it contains do not come out as I expected. This a screenshot of that it looks like on a device, which shows text being cut out when it goes to a second line:
So how can I make sure the linear layout re-sizes to accommodate children views of different heights?
Your issue isn't the ScrollView not accommodating new children. The problem is that the text, when it spans more than one line, is being clipped due to layout parameters in R.layout.planit_option_item. Try changing the TextView of ID #+id/option_text so that its height is wrap_content.
Change your TextView for the ScrollView element to accommodate two lines:
...
<TextView
android:id="#+id/option_text"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:layout_marginLeft="10dp"
android:maxLines="2"
android:singleLine="false"
android:textAppearance="?android:attr/textAppearanceMedium" />
...
This is not an issue with ScrollView, it's an issue with the specifications of the element you are inserting into the ScrollView. If you expect there may be more than 2 lines of text in some cases set maxLines = X where X is the maximum number of lines you expect.
Please let me know if this does not work and I would be happy to help further.
I have a little issue with my menu. I have 3 Textviews spanning the full width of the device. Each Textview should contain text and an image above.
Problems:
The image always shows against the border of my textview
Beneath the textview open space is added (if I remove the image, the space below is gone too)
I want the icon and the text to be aligned in the center of my textview as '1'.
Current partial code: (the icon is added outside the xml so not visible in this code, and I removed some code that has nothing to do with this part)
<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:background="#color/backgroundBlue"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/llMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<com.olbrecht.thescienceofwinning.SquareTextView
android:id="#+id/menu_ebook"
android:text="#string/menu_ebook"
android:textColor="#color/white"
android:layout_width="0dp"
android:layout_height ="fill_parent"
android:layout_weight="1"
android:gravity="center_vertical|center_horizontal"
android:background="#color/menuBlue" />
<com.olbrecht.thescienceofwinning.SquareTextView
android:id="#+id/menu_library"
android:text="#string/menu_library"
android:textColor="#color/white"
android:layout_width="0dp"
android:layout_height ="fill_parent"
android:layout_weight="1"
android:gravity="center_vertical|center_horizontal"
android:background="#color/menuBlue"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp" />
<com.olbrecht.thescienceofwinning.SquareTextView
android:id="#+id/menu_faq"
android:text="#string/menu_faq"
android:textColor="#color/white"
android:layout_width="0dp"
android:layout_height ="fill_parent"
android:layout_weight="1"
android:gravity="center_vertical|center_horizontal"
android:background="#color/menuBlue" />
</LinearLayout>
</RelativeLayout>
Notice: The size of my textview is different on each device, depending on the width, the height gets matched equal to the width, making a square.
Solved by changing android:gravity="center_horizontal" and adding android:layout_gravity="bottom"
and adding the following code to create the icons and calculating the height to define the topside padding:
TextView tv_ebook = (TextView)findViewById(R.id.menu_ebook);
tv_ebook.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ebook_icon, 0, 0);
BitmapDrawable bd_ebook=(BitmapDrawable) this.getResources().getDrawable(R.drawable.ebook_icon);
int h_ebook = bd_ebook.getBitmap().getHeight();
tv_ebook.setPadding(0, h_ebook, 0, 0);