How can I get all available width? - java

I have a linear layout with horizontal orientation.
The left side of the layout is a linear layout with a vertical orientation.
The right side of the layout is a small view of fixed width 80dp * 80dp.
Problem:
If I set the left layout with width "match_parent" the right layout is not visible.
If I set the right layout with "width=0dp" and "weight=1" to get as much space as available it just wraps around the content. I mean that it does not go all the way to the next element on the right.
How can I make sure that the left element expands all the way to the parent width minus the 80 dp occupied by the right element?

Give this a try (background colors are for visualizing what is going on only):
<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="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:background="#00ff00">
</LinearLayout>
<View
android:layout_width="80dp"
android:layout_height="80dp"
android:background="#ff0000"/>
</LinearLayout>

The general approach for this is to leave the right element's width hardcoded to your 80dp and set the following on the left:
android:layout_width="0dp"
android:layout_weight="1"
This allows the right element to measure itself and reserve its 80dp and then the parent grants all the additional space to the left element since it's weight is 1.
Edit:
To explain a little further why match_parent pushes your right hand element offscreen -- LinearLayout will perform two layout passes when it has a child with a layout_weight. The first pass will allocate the minimum amount of space based on the specified widths/heights. It is during this pass that your match_parent element will behave as you're seeing and fill it's parent container, thus pushing the right element offscreen. Then, during the second layout pass, the parent LinearLayout will allocate any left-over space according to the layout_weight attributes. There is none left to allocate, so nothing changes.
If, however, you use a layout_width="0dp" on the left element, it will get no space during the first pass, and your right element will get the 80dp that it requested. During the second pass, the LinearLayout parent will allocate the remaining width according to the weights -- so in this case the left element will receive all of the unused space.

I believe the "match_parent" option will push out anything else that is with it in that layout. Try "fill_parent" on the left layout which leaves room for other things.

Related

Adjust items height to fit its RecyclerView according to screen size

I have a RecyclerView with height:match_parent which displays 16 items vertically with fixed height in adapter. Everything works fine except when it comes to the different screen sizes. In larger screens there is a space remained at the bottom after 16 items are displayed, where on small screen phones it perfectly fits to the bottom. I am looking for a way where list items heights are adjusted to the RecyclerView height till the end without scrollable.
Check the Screenshots below for more clarification
Problem:
Expectation:
My approach was to make the Item weight set to 1, hence when rendering into the RecyclerView 16 times, they will share the same height within the RecyclerView. Unfortunately that didn't work for me.
My RecyclerView:
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_morning"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never" />
My Adapter:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#color/white"
android:clickable="false"
android:orientation="vertical">
<TextView />
</LinearLayout>
The exact solution for your problem is the flexible layout manager for ReyclerView.
More about flexible layouts.
An example illustrating the use of flexible layouts.

How layout_weight works?

I researched on another stackoverflow question//answer and found a working definition of layout_weight to be that "This attribute assigns an "importance" value to a view, and allows it to expand to fill any remaining space in the parent view"
(source:What does android:layout_weight mean?)
I am trying to apply that concept to my code.
Currently my code (without the layout weights) is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Home"
android:gravity="center"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="About"
android:gravity="center"
/>
</LinearLayout>
And the current layout is http://imgur.com/eq6q0I8
(the home should take up all the space bc of match_parent)
However if i add android:layout_weight="1" to both text views,
i get this layout http://imgur.com/fscM0Zr
(Both are visible and share same amount of space)
My question is how is this happening from that working definition of layout_weight? layout_weight in this example will assign extra space equally to both the text views. But there is no extra space because the first one has width match_parent which will make it take the width of the entire parent(no extra space)
How is this happening ?
To fix the ideas, let's say that LinearLayout's width is 100px.
TextView Home is MATCH_PARENT so 100px
TextView About is MATCH_PARENT so 100px
So, total width used by children is 100px+100px = 200px
Now, let's compute the remaining width : this is the difference between the available width and the width used by all children :
RemainingWidth = AvailableWidth (100px) - TotalWidthUsedByChildren (200px) = -100px
Note that it is negative
There is 2 child views, so distribute the remaining width to each of them according their weight. In this case each child receive 50% of the remaining... it means that each child receive -50px.
So finally :
TextView Home width is 100px + -50px = 50px
TextView About width is 100px + -50px = 50px
Perfectly logic, but not very intuitive. So the recommendation when using layout_weight is to always set the width of chid views to 0.

Space buttons out evenly (horizontal)

I'm trying to space some buttons out across the display and have them be an equal distance apart.
Here's my view xml at the moment http://pastebin.com/DvURNWn3
For each button, change this:
android:layout_width="0dp"
and set parent element's width fill_parent or particular width as below :
android:layout_width="40dp"
It's good practice to set root element to RelativeLayout instead of LinearLayoutsince nested layout_weight may throw Nested weights are bad for performance warning.

how to create two fixed size views and one view spanned between them in android?

I want to create a screen
with two fixed size areas: one aligned to left, one to the right
and in between them another area which spans all the rest of the area?
If I make the middle view with property fill_parent it will catch all the area to the 3rd child.
what will be the effective property when layout_weight=0.X and layout_width=20dp.?
======
I have a linearLayout with orientation= horizontal.
It has a child with layout_weight=0.X and also layout_width=20dp.
What will be the effective property?
If you have a horizontal LinearLayout with the first child with a fixed width (e.g. layout_width="20dp"), the second child with a non-zero weight (e.g. layout_weight="1") and the third with a fixed width (e.g. layout_width="20dp"), then you should get the first aligned to the left, the third aligned to the right and the third filling the area between them.
It's also possible to do this with a RelativeLayout, but I'll leave that as the above solution should work just fine.
It will be something like this:
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<View android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<View android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<View android:id="#+id/view3"
android:layout_width="20dp"
android:layout_height="wrap_content"
android:layout_weight="0"/>
</LinearLayout>
You should use android:layout_weight.

Android LinearLayout get views/rows that are on the screen

Let's say I have a LinearLayout set to vertical and i've added 100 views to it each view is 50dp high. A user is going to scroll and fling up and down on that LinearLayout.
I need to know the index numbers of the views that are on the screen. i.e if they fling down to the middle and stop, and see 5 items on their screen, i'd need to infer 50-55.
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:id="#id/listing_main">
</LinearLayout>
I've tried a bunch of ways to infer the current visible views - like taking the scrollY position and the height of my items...doesn't seem to work out.
view.getScrollY() seems totally arbitrary compared to the other scroll mesurements
If you put them inside a list then you can use getFirstVisiblePosition() and getLastVisiblePosition() and use these to get all of them from first to last.
http://developer.android.com/reference/android/widget/AdapterView.html

Categories

Resources