Android recently introduced Flow virtual layout but all of the examples I've seen show child Views that have the same width so it ends up laying out in a grid, instead of a jagged flow.
I've seen variable width handles for flexbox-layout and Dhaval Solanki's FlowLayout.
One other person asked a similar question (Which android layout to use for distributing variable width buttons to fill a screen?), but they were asking generally how to do it, whereas I'm asking specifically how to do it with Flow.
Can Flow handle variable-width Views? How?
Here is a simple example of how it can be achieved (ConstraintLayout:2.0.0-beta2):
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="0dp"
android:layout_height="wrap_content"
app:constraint_referenced_ids="text1,text2,text3,text4,text5"
app:flow_wrapMode="chain"
app:flow_horizontalStyle="packed"
app:flow_horizontalBias="0"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:background="#FF0000"/>
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="That is a very long textview that is very, very long"
android:background="#00FF00"/>
<TextView
android:id="#+id/text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text3 which is somewhat long"
android:background="#0099FF"/>
<TextView
android:id="#+id/text4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text4"
android:background="#999999"/>
<TextView
android:id="#+id/text5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text5"
android:background="#9900FF"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Result:
app:flow_wrapMode="chain" allows for the chain to wrap to the next line when there's not enough space
app:flow_horizontalStyle="packed" is necessary to be able to set the bias
app:flow_horizontalBias="0" aligns the Views to the left
app:flow_horizontalGap="Xdp" can be used to set a gap between the Views
Other wrap styles (spread and spread_inside) will not take the bias into account as they have a predefined way of laying out the Views
Related
The situation is: I have a constraint layout with 3 TextViews in a row
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:id="#+id/constraint"
tools:context=".MainActivity">
<TextView
android:id="#+id/small"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text="5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some text, not too long"
android:layout_marginStart="10dp"
app:layout_constraintStart_toEndOf="#id/small"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/big"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text, that can be extremely long, but can be also short"
android:layout_marginStart="10dp"
app:layout_constraintStart_toEndOf="#id/medium"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The last textView can be very long and when it is, I would like to move this textView under textView with id medium, so that the text in the text view is not separated. That means, I do not want to display text within a textView on two lines, I want to have text displayed in one line. If the text is short: on the same level as other textViews(picture 1), if the text is too big to fit the screen, the whole textView should be displayed under the second textView(#+id/medium) - picture 2.
Is it in general possible to do so? If yes, I would appreciate it, if you give me some hints.
With what I tried to do I can only move the rest of the text to a new line and display the textView in two lines, but that is not what I really want to see.
Standard situation, when text is not too big:
What I would like to have if the text is too big:
You can use Flow (no not that one) which is a flexbox-style layout helper for ConstraintLayout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/constraint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
tools:context=".MainActivity"
tools:ignore="MissingConstraints">
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:constraint_referenced_ids="small, medium, big"
app:flow_horizontalBias="0"
app:flow_horizontalGap="10dp"
app:flow_horizontalStyle="packed"
app:flow_wrapMode="chain"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/small"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:text="5" />
<TextView
android:id="#+id/medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some text, not too long" />
<TextView
android:id="#+id/big"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text, that can be extremely long, but can be also short" />
</androidx.constraintlayout.widget.ConstraintLayout>
It basically just lets you define a chain of elements and handles their constraints (note the tools:ignore="MissingConstraints" in the main layout, you don't put them on the views themselves) and then you can set it to wrap when things go off the screen, etc. There are a bunch of tweaks you can do, like setting a max number of elements on a line, forming an aligned grid, etc
There's a pretty good visual guide here:
https://proandroiddev.com/awesomeness-of-constraintlayout-flow-aa0b5edd5df
I would like to position 2 views relative to each other but not simply w.r.t the top, bottom, left or right but in a proportionate way. Let me explain. Here are 4 scenarios of positioning:
Of these, 2) and 4) are easy to do and have in-built support provided by the standard layout containers such as RelativeLayout, ConstraintLayout but my current task requires a positioning depicted in scenarios 1)/3)
A simple solution to this problem involves setting different left/top margins for both the Views w.r.t parent but this means if the need arises to place both the Views together to some other position, all the margins shall have to change.
Instead, what I would like is to have some sort of relative positioning arrangement between these 2 views that keeps them relatively at "right" distance no matter where they are placed as a unit in the parent.
How can I achieve the same? An efficient solution(with flattened hierarchy, no view hacks) would be appreciated.
An efficient solution(with flattened hierarchy, no view hacks) would be appreciated., You can use ConstraintLayout with guidelines.
guidelines have app:layout_constraintGuide_percent attribute making them responsive to the screen size.
you can use it while adding your buttons the app:layout_constraintWidth_percent and app:layout_constraintHeight_percent attributes (not mandatory, you can constraint your views to the guidelines but I believe that it is more simple).
Here is an example for your wanted layout with flattened hierarchy:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Button"
app:layout_constraintHeight_percent=".1"
app:layout_constraintStart_toStartOf="#+id/guideline"
app:layout_constraintTop_toTopOf="#+id/guideline2"
app:layout_constraintWidth_percent=".3" />
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/guideline4"
app:layout_constraintEnd_toStartOf="#+id/guideline"
app:layout_constraintHeight_percent=".1"
app:layout_constraintWidth_percent=".3" />
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".5" />
<android.support.constraint.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".4" />
<android.support.constraint.Guideline
android:id="#+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".45" />
</android.support.constraint.ConstraintLayout>
It will look like this(I am adding screenshot from the preview for better understanding guidelines):
This was just an example but with those tools, you can create your layout however you would like to.
Some extra information
My solution does not contain any fixed size dimensions on my views, this will make the layout responsive(no need to build a layout for every screen size)
You may also find ConstraintLayout: Circular Positioning related to your question, but I don't think that this is the best thing for you in this specific case.
Yes it is possible using constraint layout checkout below XML code for Point 3.(Same point 2 will be implemeted let me know if you have query)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/buttonA"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Add"
android:layout_marginTop="15dp"
/>
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#id/buttonA"
app:layout_constraintEnd_toEndOf="#id/buttonA"
app:layout_constraintTop_toBottomOf="#id/buttonA"
android:text="Add"
/>
</androidx.constraintlayout.widget.ConstraintLayout>`
Please check out below code this is kind of patch but works fine.Here we can put big block to relative to small block.As we have used constraint so will be stick together no matter wherever you put. let me know if i did any thing wrong.
Here we use one dummyView and also app:layout_constraintHorizontal_bias="0.1" for making it relative value changes from 0 to 1 like 1 means 100% stating left to small block smae way 0.5 means 50% from starting small blobk to left.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/buttonA"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:text="Add"
android:layout_marginTop="15dp"
/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/dummyView"
app:layout_constraintTop_toBottomOf="#id/buttonA"
app:layout_constraintStart_toStartOf="#id/buttonA"
app:layout_constraintEnd_toEndOf="#id/buttonA"
app:layout_constraintHorizontal_bias="0.1"/>
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/buttonA"
app:layout_constraintStart_toEndOf="#id/dummyView"
android:text="Add"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
I am new to ConstraintLayout in Android and newbie to Android too. I have a question. Is it advisable to use LinearLayout inside ConstraintLayout? For example:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
app:srcCompat="#drawable/landing_screen"
android:layout_height="match_parent"
tools:context="com.braigolabs.braigo.landing.LandingActivity">
<ImageView
android:id="#+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:srcCompat="#drawable/landing_screen"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="1.0"
app:layout_constraintHorizontal_bias="1.0"
tools:layout_constraintTop_creator="1"
tools:layout_constraintRight_creator="1"
tools:layout_constraintBottom_creator="1"
tools:layout_constraintLeft_creator="1"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="51dp">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="66dp"
android:layout_marginStart="66dp"
android:gravity="center"
android:text="#string/login_welcome_braigolabs" android:textAppearance="#style/TextAppearance.AppCompat.Large"
tools:layout_editor_absoluteX="93dp"
tools:layout_editor_absoluteY="403dp"/>
<Button
android:id="#+id/login_button"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
android:text="#string/login_login_button_title"
android:textAllCaps="false"
tools:layout_editor_absoluteX="116dp"
tools:layout_editor_absoluteY="543dp"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Also curious to know how popular is the ConstraintLayout among the developers?
Is it advisable to use LinearLayout inside ConstraintLayout?
No... usually.
In general, the idea behind ConstraintLayout is that it allows you to position all of your children without having to nest any other ViewGroups inside the ConstraintLayout. As such, I would say that it is not advisable.
However, there are some things that a LinearLayout can do that a ConstraintLayout can't (mostly revolving around weighted spacing of views), and so if you need these particular corner cases in your layout, you won't have any option other than falling back to a LinearLayout.
how popular is the ConstraintLayout among the developers?
ConstraintLayout is relatively new, but it is quite powerful and certainly something that you ought to familiarize yourself with. It won't always be the perfect tool for the job at hand, but it will often allow you to easily create layouts you would otherwise spend hours on.
I can't speak to widespread adoption statistics, but I can say that I've seen tons of questions on this site about the correct usage of ConstraintLayout, so clearly devs around the world are starting to work with it.
As of the 2.0.0-alpha5 release of the constraintlayout library, it's now possible to declare a Flow virtual layout element within your ConstraintLayout which (as the name suggests) determines how referenced items are to flow (e.g. vertically, horizontally) within the ConstraintLayout. So it's no longer necessary to declare a LinearLayout within your ConstraintLayout.
For example, if you wanted items within your ConstraintLayout to flow vertically, you'd do so like this:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="I am the first TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="I am the second TextView" />
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="I am the third TextView" />
<androidx.constraintlayout.helper.widget.Flow
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:constraint_referenced_ids="textView1,textView2,textView3"
app:flow_horizontalAlign="start"
app:flow_verticalGap="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can play around with the app:flow_ attributes in the Flow element to achieve different flow behaviour. For more information about the Flow element, refer to the release notes here. For an example, see here.
I have 3 TextViews inside a linearLayout (horizontal), and when the last textview is too big or there is no space for it, it is matching parent and looking like the image below:
Image Here
What I want is to, IF the textview reaches the linearlayout's width, then, the textview should be moved below "Property" textView. (next line)
Take a look at how it should be:
Image here
That's a snippet of my XML:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearance"
android:text="Property"
android:id="#+id/txtPropertyType" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearance"
android:text="/ 127 m"
android:id="#+id/txtArea"
android:layout_marginLeft="10dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearance"
android:text="/ 3 roomsssssssssdddd"
android:singleLine="false"
android:id="#+id/txtNumRoom"
android:layout_marginLeft="5dp" />
</LinearLayout>
Thanks in advance x)
Modify your xml and add another TextView below the LinearLayout:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearance"
android:text="Property"
android:id="#+id/txtPropertyType" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearance"
android:text="/ 127 m"
android:id="#+id/txtArea"
android:layout_marginLeft="10dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearance"
android:text="/ 3 roomsssssssssdddd"
android:singleLine="false"
android:id="#+id/txtNumRoom"
android:layout_marginLeft="5dp" />
</LinearLayout>
<TextView
android:visibility="gone"
android:layout_below="#+id/linearLayout"
android:id="#+id/long_room"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="dfgdfdfgddfgdfgdd"/>
Now, you have 2 options:
OPTION 1: Check the length of the room number textview. If it's more than, say, 12 (you have to find the number considering all letters to be widest ones - like w), then make the visibility of txtNumRoom GONE and that of long_room visible.
OPTION 2: Find the height of the txtNumRoom before it gets rendered and displayed. If this height is greater than height of txtArea, that means the textview has gone multiple-lines. Again, in that case,make the visibility of txtNumRoom GONE and that of long_room visible.
Refer to this question to know how to find height of a textview programmatically before it gets rendered.
Just add android:singleLine="true" on each text view. Your problem here is that your TextView is spreading on more than one line.
Since August 2020, there is the option to use a ConstraintLayout with the virtual layout Flow.
Your elements should be wrapped in a ConstraintLayout together with a Flow element like in the following sample XML:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearance"
android:text="Property"
android:id="#+id/txtPropertyType"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearance"
android:text="/ 127 m"
android:id="#+id/txtArea"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearance"
android:text="/ 3 roomssssssssssssssssssssss"
android:singleLine="false"
android:id="#+id/txtNumRoom"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.constraintlayout.helper.widget.Flow
android:id="#+id/flow"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:constraint_referenced_ids="txtPropertyType, txtArea, txtNumRoom"
app:flow_horizontalGap="4dp"
app:flow_horizontalStyle="packed"
app:flow_horizontalBias="0.0"
app:flow_wrapMode="chain"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/flow"
app:layout_constraintStart_toStartOf="parent"
android:textAppearance="?android:attr/textAppearance"
android:text="$2000.000"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The elements that are involved in the wrapping (all elements in the line that must wrap if too big) must have ids which are then added in the app:constraint_referenced_ids tag of Flow.
app:flow_horizontalStyle="packed" and app:flow_horizontalBias="0.0" are necessary to left-align your text (flow_horizontalBias won't work unless elements are packed), but can be changed depending on the layout you want to achieve.
app:flow_wrapMode tells the flow-layout how to position elements, and must be set to either chain or aligned, once again chain was necessary to be able to left-align the text.
It is also important to set the height of the Flow element to 0dp so it can determine how much space it needs by itself.
The TextView below should be constrained to the Flow element so that it can be positioned dynamically depending on the position of the elements inside.
Screenshot of the layout with small text
Screenshot of the layout with overflowing text
I need a View to hold a number of TextViews, and the exact number I will not know unfortunately. I need the TextViews to sort of stack either under each other or right next to each other (imagine Tetris, but with just rectangles or squares). The way I have tried thinking about it is using LinearLayout to hold them either horizontally or vertically. I then use their weights to stretch them appropriately if they are next to each other. Otherwise, I use a vertical orientation. Problem is the performance with nested LinearLayouts with more complicated stacks. I thought about using RelativeLayout, but that wouldn't work because I need the TextViews to not overlap. So like if they are next to each other, they need to each take enough space evenly. With layout_weight it works great. I was hoping someone had any idea on how to make this work right/alternative.
Heres an example that is giving me a warning (only a simple example of what I am doing programmatically):
<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="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="1">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Hello World 1"
android:background="#000000"
android:layout_weight="1"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Hello World 3"
android:background="#000000"
android:layout_weight="1"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Hello World 4"
android:background="#000000"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World 2"
android:background="#000000" />
</LinearLayout>
I've tried it with RelativeLayout by the way, but one of the TextView's needs to be a set size, but I need them to take space evenly. I won't know specific sizes. Measuring the screen width and dividing it that way is also both clunky and not precise. I appreciate anybodies input.
Edit: So I've been thinking about it some more and thought of a solution using RelativeLayout. There is a nice example in the Android docs, but the only problem is one of the Views needs to be a set size so the other one could stretch. But if there is a way to allow all of them not to have a set size, that could work too, so then they can stretch. Anyone tried doing that at some point?
It's a bit unclear what your final use case looks like, so I don't know if this will completely solve your problem, but you might take a look at TableLayout (docs link). It's based on LinearLayout so items can still be defined to evenly occupy a given space, but it allows you to define your positions and spans in terms of rows and columns.
So, for instance, your example code would look like:
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:stretchColumns="*" >
<!-- Wrap all items in a given row in a TableRow -->
<TableRow>
<TextView
android:text="Hello World 1"
android:background="#000000"/>
<TextView
android:text="Hello World 3"
android:background="#000000"/>
<TextView
android:text="Hello World 4"
android:background="#000000"/>
</TableRow>
<!-- If a child occupies an entire row, it can be by itself -->
<TextView
android:text="Hello World 2"
android:background="#000000"/>
</TableLayout>
You can also use the android:layout_column and android:layout_span attributes to define exactly which column an item should be in, and how many columns it should occupy. Also note that TableLayout and TableRow have basically ignore any layout params applied and use very specific (documented) parameters, so adding them to your code will only confuse what is actually going on. Of course, this can all be built programmatically as well as in XML.
If this does not provide the flexibility you need, I would then recommend creating your own custom layout that either extends or is based on LinearLayout. The mechanism is uses to measure children with weight is not that complex, and then you can override how each child is placed after measurement. Here is a source link to LinearLayout if you want to see how the platform does these things.
Update: As we know the percent support library is deprecated from API level 26. ConstraintLayout is the new way to achieve the same flat xml structure.
Updated Github Project
Updated Samples:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/fifty_thirty"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ffff8800"
android:gravity="center"
android:text="#string/fifty_fifty_text"
android:textColor="#android:color/white"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.5"
android:textSize="25sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ffff5566"
android:gravity="center"
android:text="#string/fifty_fifty_text"
android:textColor="#android:color/white"
android:textSize="25sp"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintLeft_toRightOf="#id/fifty_thirty"
app:layout_constraintTop_toBottomOf="#id/fifty_thirty"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />
</android.support.constraint.ConstraintLayout>
Deprecated
update: We can use android support library for the same.
compile 'com.android.support:percent:23.0.0'
Consider this demo for dividing the screen into 50-50 percent.
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/fifty_huntv"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff7acfff"
android:text="20% - 50%"
android:textColor="#android:color/white"
app:layout_heightPercent="20%"
app:layout_widthPercent="50%" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_toRightOf="#id/fifty_huntv"
android:background="#ffff5566"
android:text="80%-50%"
app:layout_heightPercent="80%"
app:layout_widthPercent="50%"
/>
</android.support.percent.PercentRelativeLayout>
Output:
Demo HERE!!!
GitHub Project HERE!!!