I'm trying to make a layout in which a ViewPager fills vertically the available space.
Basically what I have here are a bunch of views stacked vertically.
Checkbox
ViewPager
LinearLayout (which will contain the indicator)
Button
I want the checkbox on top, and the button on the bottom, the LinearLayout above the button, and whatever space is left over in the middle to be used by the ViewPager, however I can't seem to be able to make it work.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="#color/white"
android:gravity="top|center_horizontal"
android:padding="#dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:background="#drawable/login_button"
android:id="#+id/checkbox_friend_notify"
android:visibility="invisible"
android:checked="false"
android:textColor="#color/black"
android:text="#string/friend_notify"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ViewPager
android:id="#+id/pager"
android:gravity="top"
android:layout_below="#+id/checkbox_friend_notify"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="#+id/pager_indicator"
android:layout_centerHorizontal="true"
android:orientation="horizontal"
android:layout_below="#+id/pager"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/start_btn"
android:visibility="invisible"
android:text="#string/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:background="#drawable/login_button"
android:layout_below="#+id/pager_indicator"
android:layout_alignParentBottom="true" />
</RelativeLayout>
Any pointers?
If you simply need a set of views stacked vertically, consider changing your RelativeLayout for a vertical LinearLayout. Then you can keep all your child views the same (getting rid of all the layout above/below attributes) except give the ViewPager android:layout_height="0dp" and android:layout_weight="1"
Explained:
layout_weight tells LinearLayout how to distribute leftover white space, and by giving the ViewPager a weight (and not giving any of the other children any weight values) you're telling LinearLayout that ViewPager wants all of the remaining white space to itself. This only works if you don't define a height (hence why layout_height=0dp).
You can read more about it on the LinearLayout guide.
Related
After creating a LinearLayout with ImageViews as its children, I noticed that only the first row of items are shown. I thought the LinearLayout would automatically wrap its children onto a new line as necessary? The width seems fine but not the height.
Expected result
Expected blueprint (ImageView count is not to scale)
For some reason, when I create a LinearLayout inside another view, the width is shown correctly, but it never seems to adjust its height to fit & show all the children inside it.
Current result
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cv_facilities">
<LinearLayout
android:id="#+id/ll_facilities"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<LinearLayout
android:id="#+id/ll_titlerow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/iv_expandcollapsearrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp" />
<ImageView
android:id="#+id/iv_topicsymbol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp" />
<LinearLayout
android:id="#+id/ll_symbols"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/iv_symbol_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_language" />
<ImageView
android:id="#+id/iv_symbol_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_pets" />
<ImageView
android:id="#+id/iv_symbol_c"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_verified_user" />
<ImageView
android:id="#+id/iv_symbol_d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_transport" />
<ImageView
android:id="#+id/iv_symbol_e"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_seat" />
<ImageView
android:id="#+id/iv_symbol_f"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_fingerprint" />
<ImageView
android:id="#+id/iv_symbol_g"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_areoplane_depart" />
<ImageView
android:id="#+id/iv_symbol_h"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_areoplane_arrive" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
This behavior of LinearLayout is "as intended": it will display its children in a horizontal or vertical line.
Since all of the child Views in your blueprint seem to be of a similar size, consider switching to GridLayout, it is available as androidx-library (e.g. androidx.gridlayout:gridlayout:1.0.0).
For child Views with varying dimensions, FlexboxLayout is a good alternative. It was introduced in a blog post in February 2017. There is a version for androidx available: 'com.google.android:flexbox:1.1.0'
A horizontal LinearLayout will not automatically wrap to a second line to fit it's children. Per the Android documentation it only supports a single direction:
LinearLayout is a view group that aligns all children in a single
direction, vertically or horizontally
What you could do is use flexbox-layout to achieve the wrapping behavior.
Don't make horizontal linearLayout with 6 imageView's
Make new vertical linearlayout and put on it two horizontal linear layout for each one 3 imageView .
I have a TextView and ImageView in a ListView row, positioned next to each other. However, the ImageView doesn't show up at all, and doesn't register clicks either. This is the XML code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:text="text"
android:layout_width="320dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_centerVertical="true"
android:padding="10dp" />
<ImageView
android:id="#+id/imageView"
android:clickable="true"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/textView"
android:src="#drawable/ic_action"/>
</RelativeLayout>
The problem seems to lie in the layout_toRightOf line, if I remove it, the ImageView is shown, but in the wrong place. But I don't understand why it's causing a problem. What am I missing?
The issue is that the TextView is pushing the ImageView off the screen.
You can fix this using a LinearLayout and android:layout_weight
eg:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:text="text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="10dp"
android:layout_centerVertical="true"
android:padding="10dp" />
<ImageView
android:id="#+id/imageView"
android:clickable="true"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/textView"
android:src="#drawable/ic_action"/>
</LinearLayout>
More info on the layout_weight attribute:
This attribute assigns an "importance" value to a view in terms of how much space it should occupy on the screen. A larger weight value allows it to expand to fill any remaining space in the parent view. Child views can specify a weight value, and then any remaining space in the view group is assigned to children in the proportion of their declared weight. Default weight is zero.
For example, if there are three text fields and two of them declare a weight of 1, while the other is given no weight, the third text field without weight will not grow and will only occupy the area required by its content. The other two will expand equally to fill the space remaining after all three fields are measured. If the third field is then given a weight of 2 (instead of 0), then it is now declared more important than both the others, so it gets half the total remaining space, while the first two share the rest equally.
You need to use LinearLayout with weight.. if you set fixed width and the size of the phone is small, it will either stretch out of the screen.
//do linearlayout with orientation horizontal
<LinearLayout
...
orientation = "horizontal"
...
>
<TextView
....
android:layout_width="0dp"
android:layout_weight="1"
...
/>
<Button
....
android:layout_width="wrap_content"
...
/>
</LinearLayout>
Play with android:layout_weight, you will understand
I have relative layout ("relative") with clickable layout ("clickable") on top, expandable list view ("lview") under "clickable", and "footer" text view with version of my app on bottom of "relative":
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relative"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/menu_background" >
<com.reconti.app.widgets.Logo
android:id="#+id/reconti_menu_tv_logo"
android:layout_width="fill_parent"
android:layout_height="?android:attr/actionBarSize"
android:layout_alignParentTop="true"
android:gravity="center_vertical"
android:paddingLeft="#dimen/standart_side_margin"
android:textSize="30sp" />
<RelativeLayout
android:id="#+id/clickable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/menu_tv_logo"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:clickable="true"
android:paddingLeft="#dimen/standart_side_margin" >
<com.reconti.app.widgets.RoundedImageView
android:id="#+id/menu_profile_avatar"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:scaleType="fitCenter"
android:src="#drawable/com_facebook_profile_picture_blank_portrait" />
<TextView
android:id="#+id/menu_user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#id/menu_profile_avatar"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#color/white" />
</RelativeLayout>
<ExpandableListView
android:id="#+id/lview"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:childDivider="#color/menu_divider_color"
android:divider="#color/menu_divider_color"
android:dividerHeight="1dp"
android:footerDividersEnabled="false"
android:groupIndicator="#null"
android:headerDividersEnabled="false"
android:listSelector="#drawable/expandable_row_background" />
<TextView
android:id="#+id/footer"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_alignParentBottom="true"
android:layout_marginTop="10dp"
android:gravity="center"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/white" />
</RelativeLayout>
Everything looks good as long as user hit some option in expandable list. Then "lview" overlaps "footer". I would like to achive effect, that "lview" remains on top of "footer" and "footer" remains on bottom of "relative" and only bottom of "lview" is visible to user (so top goes under "clickable"). I hope I explained it clearly:)
Usually I like to work with linearlayout when needs to keep views above views. I don't like how relative layout works sometimes. Well, you can try my idea, I know this works with list, but didnt try with expandable list (but guess will work).
LinearLayout vertical #relative
Logo #reconti_menu_tv_logo
RelativeLayout #clickable
ListView weight 1 #lview
TextView #footer
In this, only your ListView will scroll. I don't know if is this what you want. Your logo, clickable and footer will be fixed.
The weight 1 is to keep your listivew using all not used space, so your footer will be always on "footer". Don't forget about height 0dp when using weight.
Now, if you want all scrolling, you have to use addHeader(View) and addFooter(View) on your list before set the adapter. (this is the better way)
In a layout resource XML, I have 3 RelativeLayout(s) which are inside a main RelativeLayout. The view will be shown vertically. These 3 RelativeLayout() are set next to each other, and I want them to fill the whole screen, doesnt matter what will be the screen size. My, layout view:
<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="#drawable/backg"
>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="#dimen/top_mr_image"
android:src="#drawable/temp" />
<RelativeLayout
android:id="#+id/r1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="#+id/imageView1"
android:layout_marginLeft="10dp"
android:background="#drawable/r1bg"
android:layout_weight="1"
>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="#dimen/txt_mr_right"
android:layout_marginRight="#dimen/txt_mr_right"
android:layout_marginTop="39dp"
android:text="S"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#id/textView1"
android:layout_marginLeft="#dimen/txt_mr_right"
android:layout_marginRight="#dimen/txt_mr_right"
android:text="T"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/r2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignTop="#+id/r1"
android:layout_toRightOf="#+id/r1"
android:layout_weight="1" >
</RelativeLayout>
<RelativeLayout
android:id="#+id/r3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignTop="#+id/r2"
android:layout_toRightOf="#+id/r2"
android:layout_weight="1" >
</RelativeLayout>
I set weight=1 and layout_width=0dp for each relativeLayout and this technique works with buttons, I thought the same will be with relativeLayout, seems my thoughts were wrong. Any idea?
UPD1: I have added an image of what I would like to have
RelativeLayout does not pay attention to android:layout_weight. (That's a property of LinearLayout.LayoutParams, but not of RelativeLayout.LayoutParams.)
You should be able to get the layout you want with a much simpler view hierarchy. It's not clear what you are trying to do, since the last two RelativeLayouts are empty. If you need a purely vertical organization, I'd suggest using LinearLayout instead of RelativeLayout.
EDIT Based on your edit, it looks like you want a horizontal layout of three compound views, each one clickable. I think something like the following will work:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- First column -->
<LinearLayout
android:id="#+id/firstColumn"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="..." />
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="text 1"
. . . />
</LinearLayout>
<!-- Second column -->
<LinearLayout . . . >
. . .
</LinearLayout>
</LinearLayout>
If the contents of the buttons aren't correct, you can replace the second-level LinearLayout views with RelativeLayout if that helps organize the layout better.
RelativeLayouts do not support weight. You need to use a LinearLayout as a parent container if you want to use weights.
Solution is very simple. I have been looking for weight distribution in relative layout.
It's a small trick for all these kind situations.
Use LinearLayout with android:orientation="horizontal"
You can use Horizontally oriented LinearLayout Manager in the Recycler View, and place each RelativeLayout in each item, of its Adapter.
The Link: How to build a Horizontal ListView with RecyclerView?
If your RelativeLayouts are set to a fixed width and height, that is to the size of the Screen, that you can get from DisplayMatrics, that will be OK.
The Link: Get Screen width and height
If the contents of your RelativeLayouts are different, then you can use getItemViewType() method.
Please see: How to create RecyclerView with multiple view type?
Happy Coding :-)
I am trying to layout 1 textview (upText) left aligned and 1 textview (downText) and an image view (image) both on the same line and right aligned.
how can I do that? I tried that, but both 'textview' and image view at left aligned.
<TextView
android:id="#+id/uptext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"/>
<TextView
android:id="#+id/downtext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:gravity="right|bottom"/>
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right|bottom"/>
</LinearLayout>
Don't use a LinearLayout. Use a RelativeLayout, with
your first TextView set with android:layout_alignParentLeft="true"
your second TextView set with android:layout_alignParentBottom="true" and android:layout_alignParentRight="true"
something similar for your ImageView, which presently looks like it is going to overlap the second TextView
I realize this post is a bit old but just in case someone comes across this in their search for clarity;
The parent linear layout is where gravity needs to be specified for the child to align with the desired behavior which is why the above posts are explaining that linear layout is not possible for two separate behaviors to occur since a child cannot decide where to align itself within a linear layout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="200dp"
android:layout_height="50dp"
android:gravity="bottom|right">
<TextView
android:layout_width="40dp"
android:layout_height="20dp"
android:text="test"/></LinearLayout>
It should also be said that the parent linear layout must have a defined size and not be wrap-content or this will not work since wrap content implies that there will be no extra space in the layout for positioning, so at least 'match-parent' for width and height is necessary as well as having a parent with a greater size than wrap-content for the child linear layout itself.
Hope this helps.
Using RelativeLayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom">
<TextView
android:id="#+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="hi"
android:textStyle="bold|italic"
android:gravity="right"/>
<TextView
android:id="#+id/text2"
android:layout_below="#id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="All"
android:gravity="right"/>
</RelativeLayout>