How to use same technique of css "negative margin" in a layout? - android

I would like to create this kind of layout you see in the picture and I'm thinking like negative margin in CSS and no result. Please help me achieve it.
<?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"
android:layout_height="match_parent"
tools:context=".HomeActivity">
<TextView
android:id="#+id/txt_home_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/box"
android:elegantTextHeight="true"
android:padding="30dp"
android:text="Welcome!"
android:textColor="#ffffff"
android:textSize="28sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp">
<ImageView
android:id="#+id/home_logo"
android:layout_width="90dp"
android:layout_height="80dp"
android:scaleType="fitCenter"
android:src="#drawable/mylogo" />
</FrameLayout>
</android.support.constraint.ConstraintLayout>
Here is the box:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#2d3669"></solid>
<corners android:radius="50dp"></corners>
<gradient android:angle="90"
android:startColor="#392800"
android:endColor="#faae03"/>
</shape>
</item>
</selector>
I know in ConstraintLayout how to have items near each other, but I can't figure it out how to put a log on a TextView so that half of it remains outside! I can't find a keyword that leads to such examples on Google.

Here you go:
<?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"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:layout_editor_absoluteY="81dp">
<TextView
android:id="#+id/txt_home_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/box"
android:elegantTextHeight="true"
android:padding="30dp"
android:text="Welcome!"
android:textColor="#ffffff"
android:textSize="28sp"
tools:layout_editor_absoluteX="129dp"
tools:layout_editor_absoluteY="0dp" />
<android.support.v4.widget.Space
android:id="#+id/space"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="#+id/txt_home_title"
app:layout_constraintLeft_toLeftOf="#id/txt_home_title"
app:layout_constraintRight_toRightOf="#id/txt_home_title" />
<ImageView
android:id="#+id/home_logo"
android:layout_width="98dp"
android:layout_height="84dp"
android:scaleType="fitCenter"
android:src="#mipmap/ic_launcher"
app:layout_constraintHorizontal_bias="0.687"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/space" />
</android.support.constraint.ConstraintLayout>
Output:
Explanation:
We can not use negative margin in ConstraintLayout as it is not officially supported so we need to use a workaround. Add an empty view i.e. Space between ImageView and TextView and set android:layout_marginBottom="32dp" to Space view and you are done.
I followed this answer of CommonsWare.

There are at least 2 different ways to achieve this.
1. Anchor
If you want the logo's center to be exactly on the bottom edge of the TextView, use a CoordinatorLayout as the direct parent view of the logo and the TextView, and use the app:layout_anchor and app:layout_anchorGravity XML properties on the logo. For your example, the value of app:layout_anchor would be the ID of the TextView, and the value of app:layout_anchorGravity would be "bottom|end".
Note that you should be able to achieve any positioning that you want by encapsulating the logo within a parent layout, anchoring the parent to the TextView, and then setting margins on the logo to move it around within its transparent parent.
2. Negative margins (yep)
Android actually supports negative margins, although probably not with a ConstraintLayout. It definitely works with a RelativeLayout though! Considering that you want your ImageView to overlap the TextView, it would look like this:
<RelativeLayout
...
<TextView
android:id="#+id/myTextView"
... />
<ImageView
android:layout_below="#+id/myTextView"
android:layout_marginTop="-30dp"
... />
</RelativeLayout>
Keep in mind the Z ordering when doing this as well. In my example above the ImageView would be drawn on top of the TextView because it's declared after the TextView within its parent. If the ImageView would have been declared first, the TextView would be drawn on top of it.

Related

Rounded corners in a card view won't work at the bottom of image with a text view

I am trying to get a card view so that I get a rounded corners image with a text under it but the thing is, when I add the text, since they are both inside of the rounded corners card view, the image is not rounded at the bottom (which is what I need). How would I accomplish that?
This is the layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardCornerRadius="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/iv_news"
android:layout_width="300dp"
android:layout_height="200dp"
android:src="#drawable/background_shape"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/news_title"
android:textColor="#color/black"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textAlignment="center"
android:layout_marginTop="5dp"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
The image (I need the bottom corners of the image also rounded):
Try to put this code in your "#drawable/background_shape". Just tried it and it all working fine.
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:bottomLeftRadius="20dp" android:bottomRightRadius="20dp"/>
</shape>
The problem is the TextView is overlaying the card radius. To fix that add padding to the text view or to the card and that should solve it.
The answer marked as correct, is not clean: Adds an unnecessary drawable, the card view already has a corner radius property, making the child implement round corners as well defeat the purpose of such attribute.
Also, try to use material card view: <com.google.android.material.card.MaterialCardView/>. You might not needed it now but it has more customizations.
If you only need a circular image in that case you need to add only ImageView inside CardView, and which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardCornerRadius="16dp">
<ImageView
android:id="#+id/iv_news"
android:layout_width="300dp"
android:layout_height="200dp"
android:src="#drawable/background_shape"
android:scaleType="centerCrop" />
</androidx.cardview.widget.CardView>
<TextView
android:id="#+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/news_title"
android:textColor="#color/black"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textAlignment="center"
android:layout_marginTop="5dp"/>
</LinearLayout>

How can I make a background overlaying the recyclerView?

I have a horizontal recyclerView of images. I want to set a background color that covers the recyclerView.
I want to:
I made with my xml code:
I've added a view to the RecyclerView area. Background color gave it there. When I write it like this in the code, the background color is under the recyclerView:
gradient background:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="0"
android:centerColor="#f1f1f1"
android:endColor="#FFF8F8F6"
android:startColor="#color/white" />
</shape>
xml layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentTop="true"
android:background="#color/colorAccent" />
<FrameLayout
android:id="#+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottomView"
android:layout_margin="5dp"
android:layout_below="#+id/toolbar"
android:layout_gravity="bottom" />
<View
android:id="#+id/bottomView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignStart="#+id/images"
android:layout_alignLeft="#+id/images"
android:layout_alignTop="#+id/images"
android:layout_alignEnd="#+id/images"
android:layout_alignRight="#+id/images"
android:layout_alignBottom="#+id/images"
android:layout_alignParentBottom="true"
android:background="#drawable/gradient_white" />
<ImageView
android:id="#+id/sendButton"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:adjustViewBounds="true"
android:contentDescription="#null"
android:elevation="5dp"
android:gravity="center"
android:padding="14dp"
android:scaleType="center"
app:srcCompat="#drawable/ic_baseline_send_24" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/images"
android:layout_width="match_parent"
android:layout_height="110dp"
android:layout_gravity="bottom"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_alignParentBottom="true"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="10dp" />
</RelativeLayout>
first of all rearrange order of your Views - first should be RecyclerView, then covering background, then send icon. Views placed in XML are drawn in order of declaration, treat them like layers in your case (and for the future: be aware of translationZ and elevation XML attributes)
and for placing covering "background" View (in fact this is foreground, "above" RecyclerView) use this:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/images" ....
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#80FFFFFF"
android:layout_alignBottom="#id/images"
android:layout_alignTop="#id/images"
android:layout_alignLeft="#id/images"
android:layout_alignRight="#id/images"/>
<ImageView
android:id="#+id/sendButton" ...
"covering" View may have 0dp size for better measuring performance, still all android:layout_align... declarations make it stretch to the size of RecyclerView (and as later-declared this View will be drawn after RecyclerView, so on top of it)
just adjust your android:background, use some gradient drawable with transparency
edit: gradient drawable file (put in drawable folder)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#00ffffff"
android:centerColor="#00ffffff"
android:centerY="80%"
android:endColor="#fff"
android:angle="0"
android:dither="true"/>
</shape>
set it up as
android:background="#drawable/your_file_name_of_above_shape"

Is there a way to center an element while enforcing it stays on screen in Android?

For the sake of simplicity, let's say I've got two text views A and B. A is a set size with a set margin between it and the parent. B is a variable size.
The goal is to position B centered below A if it fits but not have B go off the screen.
Here's the xml I've currently got for the two elements:
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/element_A"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="elem_A"/>
<TextView
android:id="#+id/element_B"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="#id/element_A"
app:layout_constraintEnd_toEndOf="#id/element_A"
app:layout_constraintTop_toBottomOf="#id/element_A"
android:text="sml"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The image below shows three figures: left is what I'm seeing when element B is small enough (great), middle is what I'm seeing when element B is too big (not good), and right is what I want to see when element B is too big.
As it turns out, switching from ConstraintLayout to LinearLayout actually fixes this problem. I'm still curious if this is possible using ConstraintLayout but for now I'll just use LinearLayout.
<?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="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:layout_gravity="end"
tools:context=".MainActivity">
<TextView
android:id="#+id/element_A"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:gravity="end"
android:layout_weight="1"
android:text="elem_A"/>
<TextView
android:id="#+id/element_B"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:layout_weight="1"
android:text="much much longer element B"/>
</LinearLayout>
First create LinearLayout and set orientation to horizontal And again you need to create child LinearLayout and wrap both text feilds into it and set it's layout_gravity to right also set orientation to vertical. After that you need to distribute weight of LinearLayout into both of text feilds equally and also set gravity and layout_gravity to center for both text feilds . Tip :- don't use hard-coded values,instead use match_parent / wrap_content for all elements.
I have made changes to your code, cop-paste all code to your xml file...
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/element_A"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="32dp"
android:text="elem_A"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="#+id/element_B"
app:layout_constraintStart_toStartOf="#+id/element_B"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/element_B"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="32dp"
android:text="sml"
android:textAlignment="center"
app:layout_constraintEnd_toEndOf="parent"
tools:layout_editor_absoluteY="88dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

Why using padding wouldn't help in increasing touch area of a View

I have a view (red circle).
I tend to increase its touch area, by using padding. I avoid using margin, as it wouldn't help in increasing touch area.
layout.xml
<?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="48dp"
android:orientation="horizontal">
<View
android:paddingStart="36dp"
android:paddingLeft="36dp"
android:paddingEnd="36dp"
android:paddingRight="36dp"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="#drawable/circle"
android:layout_gravity="center_vertical" />
<EditText
android:layout_width="0dp"
android:width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginEnd="36dp"
android:layout_marginRight="36dp" />
</LinearLayout>
circle.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="#ff0000"/>
</shape>
However, as you can see, the touch area of the red circle is not enlarge still?
May I know why is it so? Is there any easy way I can increase the touch area of custom view?
Your padding is not affecting the View size and even if it was, the android:background covers ALL View space.
There's two alternatives:
Use a ImageView instead and android:src in place of android:background. The src will be the content and padding will be applied outside of it, while background will cover ALL view space.
Or add padding at the drawable.xml with the appropriate tags and attributes.
Update from OP
Using ImageView solved my problem
<?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="48dp"
android:orientation="horizontal">
<ImageView
android:layout_width="104dp"
android:layout_height="32dp"
android:paddingStart="36dp"
android:paddingLeft="36dp"
android:paddingEnd="36dp"
android:paddingRight="36dp"
android:src="#drawable/circle"
android:layout_gravity="center_vertical" />
<EditText
android:layout_width="0dp"
android:width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginEnd="36dp"
android:layout_marginRight="36dp" />
</LinearLayout>

How to place a view exactly above the center of its parent view/layout in android

What I want to achieve is that I want to place a View "above" the center of its parent layout. consider the image below:
The blue rectangle it where I want my View to be. as you can see it is exactly above the (vertical)center of the screen.
The challenge is that we don't know the height of the view (so I can't use a bottom margin for it) and I want to do it in layout xml file (so I can't use code to determine the height of the view and set it a margin programmatically)
with these restrictions, is there any way to do this?
You can follow the following layout to place your view at the desired location-
<?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">
<View android:id="#+id/dummy_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerInParent="true"
/>
<View
android:id="#+id/your_view"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_above="#+id/dummy_view"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
I recommend you to use ConstraintLayout, it can be done using guidelines easily (instead of using a View as the anchor point):
XML example:
<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"
>
<android.support.constraint.Guideline
android:id="#+id/mid_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5"
/>
<View
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#F00"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toTopOf="#+id/mid_guideline"
/>
</android.support.constraint.ConstraintLayout>

Categories

Resources