How to position vector image in RecyclerView item template - android

Is there a way to adjust the alignment of the menu dots in the RecyclerView item so that it's positioned exactly underneath the overflow dots in the Toolbar (i.e. in its original place where it should be)? I tried adjusting the item weights but that didn't work.
<LinearLayout
android:id="#+id/ll_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100">
<TextView android:id="#+id/rvitem_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:textColor="?android:attr/textColorPrimary"
android:fadingEdge="horizontal"
android:layout_weight="90"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="More options"
android:clickable="true"
android:focusable="true"
android:layout_gravity="end"
android:src="#drawable/ic_more_vertical"
android:background="#null"
android:tint="?attr/colorOverflow"
android:layout_weight="10"/>
</LinearLayout>
<TextView android:id="#+id/rvitem_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:textColor="?android:attr/textColorSecondary"
android:layout_below="#id/ll_title"
android:fadingEdge="horizontal" />
Current result
Expected result

#MacaronLover, The approach you are taking to make the view align by assigning the weight seems to be in the right direction. I have taken your xml file and made some adjustments here:
<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"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="8dp"
android:paddingBottom="8dp">
<ImageView
android:id="#+id/firstImage"
android:layout_width="90dp"
android:layout_height="90dp"
tools:background="#000" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="#+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
tools:text="Title A" />
<TextView
android:id="#+id/subTitleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="Subtitle A" />
</LinearLayout>
<ImageView
android:id="#+id/secondImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_vertical_dots" />
</LinearLayout>
The idea here is to aligh our view with the toolbar's padding. By default, the toolbar sets 16dp padding on start and end.
So, to start with in our view, we set paddingStart and paddingEnd to be 16dp. Now, to adjust vertical padding, we set that to 8dp as it adjusts with the top and below items. Set, the orientation of parent to horizontal.
Then, we add first ImageView and sets its layoutWidth/Height to the values we want.
Then add the LinearLayout that holds the two TextViews and set it's orientation to vertical and layout_width to 0dp and add the two child TextViews.
Then finally add the overflow ImageView and provide the attributes. Since we set the first image and last image dimensions as static values, when the view is drawn, the width is allocated to these first and the remaining of the width goes to the textview container LinearLayout.
If we note at the pre-view attached, there might seem to be a bit more padding at the end. It is due to the dot image src we are assigning to the second image. It doesn't fill the ImageView and hence looks like extra padding. We can adjust this by adjusting the paddingEnd value of our parent LinearLayout.
Please comment if there are any confusions.

See this Image
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:layout_marginStart="10dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title A"
android:textSize="20sp"
android:textColor="#000"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Subtitle A"
android:textSize="17sp"
android:textColor="#000" />
</LinearLayout>
<ImageView
android:layout_width="40dp"
android:padding="13dp"
android:layout_height="match_parent"
android:src="#drawable/ic_menu"/>
</LinearLayout>

Related

how come a view gets out of its linear layout parent borders without negative margins?

I have this android layout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:id="#+id/display_name_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="#+id/account_display_name"
..."/>
<ImageView
..."/>
</LinearLayout>
<LinearLayout
android:id="#+id/account_name_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:layout_marginBottom="1dp"
android:orientation="horizontal">
<TextView
android:id="#+id/account_name"
style="#style/AccountDataAccountName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"/>
<ImageView
android:id="#+id/account_name_chevron"
android:layout_width="#dimen/account_menu_chevron_size"
android:layout_height="#dimen/account_menu_chevron_size"
android:layout_marginTop="#dimen/account_menu_chevron_top_margin"
android:layout_marginLeft="#dimen/account_menu_chevron_left_margin"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<FrameLayout
android:id="#+id/close_and_recents"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="#dimen/account_menu_header_horizontal_margin"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/close_button"
android:layout_width="#dimen/account_menu_close_button_size"
android:layout_height="#dimen/account_menu_close_button_size"
android:layout_gravity="top|end"
android:padding="#dimen/account_menu_close_button_padding"
android:alpha="0"
android:visibility="gone"/>
but when i run it with big font size and screen size,
I see the image is getting out of the linear layout. And it's hidden behind the red circle image (a view in a sibling FrameLayout).
How can it be?
I didn't put negative margins.
Because in that LinearLayout first your account_name textview is taking space. So when you run with big font size, this textview takes the (almost) full width of the LinearLayout. Now the layout will render the next View (Image View), it will place it next to textView. Since the imageview has fixed dimension given, it will take its space but will not be visible as it exceeds the parent width.
If still not clear let me know.
Update
For your next question, you can change that LinearLayout to RelativeLayout like this:
<RelativeLayout
android:id="#+id/account_name_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginBottom="1dp">
<ImageView
android:id="#+id/account_name_chevron"
android:layout_width="#dimen/account_menu_chevron_size"
android:layout_height="#dimen/account_menu_chevron_size"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_marginTop="#dimen/account_menu_chevron_top_margin"
android:layout_marginLeft="#dimen/account_menu_chevron_left_margin"/>
<TextView
android:id="#+id/account_name"
style="#style/AccountDataAccountName"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:lines="1"
android:ellipsize="end"
android:layout_toLeftOf="#+id/account_name_chevron"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"/>
</RelativeLayout>
First we draw ImageView at the extreme right of the layout, then we draw textView from extreme left to starting of ImageView. For the Relative layout has properties like android:layout_toLeftOf and more.
Update2
Try this code as per your requirement. So basically what we are doing is; We fist draw textView and give it a rightPadding equals to iconSize + iconLeftMargin. So now the textView will always keep space for icon on its right. Now we rightAlign the icon with textView, so as the textView increase its space the icon will move with it. Once it reach the layout end the icon will still be fully visible.
account_menu_chevron_size_plus_margin this the dimen equal to iconSize + iconLeftMargin
<RelativeLayout
android:id="#+id/account_name_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginBottom="1dp">
<TextView
android:id="#+id/account_name"
style="#style/AccountDataAccountName"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:lines="1"
android:ellipsize="end"
android:paddingRight="#dimen/account_menu_chevron_size_plus_margin"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"/>
<ImageView
android:id="#+id/account_name_chevron"
android:layout_width="#dimen/account_menu_chevron_size"
android:layout_height="#dimen/account_menu_chevron_size"
android:layout_centerVertical="true"
android:layout_alignRight="#+id/account_name"
android:layout_marginTop="#dimen/account_menu_chevron_top_margin"
android:layout_marginLeft="#dimen/account_menu_chevron_left_margin"/>
</RelativeLayout>

layout_gravity isn't working as expected - just partially

I have the following layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="#string/title_day"
android:textStyle="bold"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="Tuesday"
android:textSize="16sp" />
</LinearLayout>
<TextView
android:id="#+id/tv_fail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+22"
android:textSize="16sp"
android:layout_gravity="end|center_vertical" />
</LinearLayout>
</LinearLayout>
And this looks like this:
And I want the last TextView with id tv_fail to be pinned to right end of screen. I suppose that
android:layout_gravity="end|center_vertical"
should handle it, but this instruction centers TextView vertically, but doesn't move it to end. How to fix it?
I suppose that
android:layout_gravity="end|center_vertical"
should handle it, but this instruction centers TextView vertically, but doesn't move it to end.
This is due to how LinearLayout works; your understanding of layout_gravity is generally correct.
LinearLayout takes its children and lays them out in a line, and the children will all be packed towards the "start" of the LinearLayout. In other words, a horizontal LinearLayout will ignore the horizontal component of the layout_gravity attribute of a child.
There are a few ways to work around this. The one that I think works best for your scenario is to make the TextView stretch to fill all the remaining space in the LinearLayout (using layout_weight), and then have the TextView position its text at the end of its content area (using gravity).
<TextView
android:id="#+id/tv_fail"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+22"
android:textSize="16sp"
android:layout_gravity="center_vertical"
android:gravity="end"/>
If you just want to set text inside of your last TextView to end then you should use :
android:gravity="end"
for TextView gravity use:
android:layout_gravity="center"
Difference between android:gravity & android:layout_gravity is that first one arrange content inside of any view with given gravity while second one arranges view according to given gravity.
Updated code:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="title_day"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:text="Tuesday"
android:textSize="16sp" />
</LinearLayout>
<TextView
android:id="#+id/tv_fail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="+22"
android:textSize="16sp" />
</LinearLayout>

Why is height of ListItem (a LinearLayout) so tall when layout_height is changed to wrap_content?

I have a pretty simple layout (Linear) for my ListView item, just 3 widgets laid out horizontally: 2 TextView items then a Button. But even though the layout_height of all 3 is wrap_content it seems that that value used for the button forces the ListItem to expand a lot more than needed. But simply changing the value of the layout_height to 25dp eliminates this.
Why is the Button's wrap_content having this effect, and how to stop it?
Notice the background colors in my screenshots below, showing widget dimensions. The only difference between the two pics is that in my XML (at bottom) the layout_height of the Button has been changed from wrap_content to 25dp.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="#+id/tvTotal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_gravity="left"
android:text="0."
android:textSize="18sp"
android:maxLines="1"
android:layout_weight=".15"
android:background="#color/LightGreen"
/>
<TextView
android:id="#+id/tvName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="left"
android:text=""
android:textSize="18sp"
android:maxLines="1"
android:layout_weight=".55"
android:background="#color/LightBlue"
/>
<Button
android:id="#+id/btnMyButton"
android:layout_width="0dp"
android:layout_height="25dp"
android:gravity="right"
android:layout_gravity="right"
android:textColor="#color/CornflowerBlue"
android:text="Questions"
android:textSize="16dp"
android:maxLines="1"
android:layout_weight=".3"
android:background="#color/black"
>
</Button>
</LinearLayout>
Using wrap_content for Button's layout_height:
Hardcoding 25dp for Button's layout_height:
The extra space are buttons default padding.
If you want to remove it use:
android:minHeight="0dp"
android:minWidth="0dp"
in your code
<Button
android:id="#+id/btnMyButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_weight=".3"
android:background="#color/black"
android:gravity="right"
android:maxLines="1"
android:minHeight="0dp"
android:minWidth="0dp"
android:text="Questions"
android:textColor="#color/CornflowerBlue"
android:textSize="16dp"></Button>

Frame Layout fixed elements on wrap_content height

I have the next design:
Actual design app
CODE:
<LinearLayout
android:id="#+id/edit_name"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#99000000"
android:weightSum="1">
<FrameLayout
android:background="#color/tabIndicator"
android:layout_width="310dp"
android:layout_gravity="center"
android:clickable="true"
android:layout_height="wrap_content"
android:minHeight="136dp"
android:layout_weight="0.75">
<TextView
android:id="#+id/close_circle"
android:elevation="2dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="X"
android:background="#drawable/oval_corner"
android:backgroundTint="#color/colorPrimary"
android:layout_gravity="top|bottom|right"
android:layout_alignParentEnd="true"
android:paddingLeft="8dp"
android:paddingTop="3dp"
android:paddingRight="8dp"
android:paddingBottom="3dp"
android:textColor="#color/tabIndicator"
android:textStyle="bold"
android:layout_margin="2dp"
android:translationZ="2dp">
</TextView>
<TextView
android:id="#+id/textDescLarga"
android:layout_width="match_parent"
android:layout_height="208dp"
android:text="#string/text_placeholder_benefit"
android:textStyle="normal"
android:textSize="12dp"
android:textColor="#color/textDefault"
android:layout_gravity="bottom|center"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:maxLines = "12"
android:scrollbars="vertical">
</TextView>
<ImageView
android:id="#+id/imageMain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="#drawable/placeholder_benefit"
android:layout_gravity="top|left">
</ImageView>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="#+id/textTitulo"
android:layout_gravity="center"
android:layout_marginBottom="0dp"
android:text="Nombre hotel"
android:textAlignment="center"
android:textStyle="bold"
android:textSize="19dp"
android:textColor="#color/cardview_dark_background"/>
</FrameLayout>
PROBLEM:
When I need auto height, on the text, whether increases or decreases, I tried Fragment Layout layout_height: wrap_content but text overlap image.
What am I doing wrong? Is there another way to do this?
Thanks
FrameLayout renders it's children in a stack - one on top of the other unless you use layout_gravity to position them. FrameLayout is typically used with the entire available screen space - the layout_height and layout_width are set to match parent.
Your issue is because you have the layout_height set to wrap content, it will overlay widgets one on top of the other. Set the layout_height to match parent. Or better yet for your case, use a RelativeLayout.

Android - How to have a variable width layout with an image at either end and text in the middle

I'm trying to create a layout for a callout bubble that includes an image on the left, another image on the right and then a layout in the middle which includes a couple of TextViews.
If the length of either TextView is short enough, I want the whole callout to only be wide enough to show the text; if it's too long I want it trimmed with a '...'.
Here's a sample of the XML I'm dealing with (I've stripped out all the margins and padding etc. for clarity):
<RelativeLayout android:id="#+id/callout"
android:layout_width="wrap_content"
android:layout_height="54dp">
<ImageView android:id="#+id/callout_img_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RelativeLayout android:id="#+id/callout_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/callout_img_left">
<TextView android:id="#+id/callout_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true" />
<TextView android:id="#+id/callout_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:layout_below="#id/callout_name" />
</RelativeLayout>
<ImageView android:id="#+id/callout_img_right"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/callout_info"/>
</RelativeLayout>
Originally I had the image on the right using android:layout_alignParentRight="true" but this made the whole callout fill it's available width. The XML shown above works for short text, but if the text is too long it pushes out (shrinks?) the image on the right.
Perhaps a nested LinearLayout with a zero width will do the trick:
<LinearLayout android:id="#+id/callout"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="54dp">
<ImageView android:id="#+id/callout_img_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView android:id="#+id/callout_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true" />
<TextView android:id="#+id/callout_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true" />
</LinearLayout>
<ImageView android:id="#+id/callout_img_right"
android:layout_width="48dp"
android:layout_height="wrap_content" />
</LinearLayout>
If you don't mind the two text views always having the same width, you can dispense with the nested LinearLayout and just give each TextView a width of 0dp and weight of 1.

Categories

Resources