ConstraintLayout: Minimal distance to edge with wrap content - android

I have e.g. a Textview in a Constraint Layout, which I want to be as small as the text is (wrap content):
Here is my XML:
<?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">
<TextView
android:text="This is an example Message."
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/textview1"
android:background="#android:color/holo_green_light"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="16dp"/>
</android.support.constraint.ConstraintLayout>
But I want to define a minimal distance to the right edge of the screen. So if the text gets larger it currently looks like this:
But I want it to look like this:
How do I do that?
Edit:
I still have no clue.
One deleted answer suggested to try setting
android:layout_marginRight
and
android:layout_marginEnd
I tried using padding to, but with no success.

I know this is late, but it might help others looking at this.
Try adding these lines to the TextView
android:maxWidth="200dp"
android:adjustViewBounds="true"

Related

Can't center button in constraint layout

This question may have been asked a million times and seem trivial but i still do not understand the logic behind it after reading about 100 of answers.
I have this ultra simple layout XML
<?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">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
From my understanding if i set opposing constraints the render engine interprets them automatically as percentage... i mean right ?
If no specific margin or anything is set then it evens out the distances. This would clearly mean that the button should tae a centered position inside the view. But it doesnt....
I dont understand it. i want to center with WITHOUT SETTING A MARGIN since a margin, from my understanding, is something independent of the constraint. It works within a constraint. but nevertheless i set a margin of 50 on each side. once a margin is set on opposing sides the engine should automatically render it as percentage.... right ?
So this XML:
<?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">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginLeft="50dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="50dp"
android:layout_marginRight="50dp"
android:layout_marginBottom="50dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
should say something like "the constraint is 50% to left right top and bottom" which essentially again is exactly the middle. Of course this is again not working. The engine interprets it as absolute value and the button is in another awkward position:
So how to do this ??
What I DON'T WANT TO DO:
Adjust it with some kind of Guideline or Bias.
I want the plain thing.
Just 4 constraints (4 lines inside the xml) and a button that is in the middle of the screen on any device.
Maybe someone can share some insight ?
You should delete these two attributes:
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintVertical_bias="0.0"
As you can see the official reference, default bias is fifty-fifty (50% = 0.5).
For example the following will make the left side with a 30% bias
instead of the default 50%, such that the left side will be shorter,
with the widget leaning more toward the left side (Fig. 5):

Some missing layout attributes in the textView

I'm looking for some attributes such as layoutCenteringParent in my textView and cannot find them. I want to find that specific attribute in order to center the text (I'm following an online tutorial). I tried to follow the advice here:
Missing attributes in the layout design - Android Studio
and deleted my Android studio cache but it didn't help.
I'm a beginner so there is a good chance I'm just missing something here. I'm attaching a screenshot:
With ConstraintLayout you should constrain Textview from all four sides to center it.
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ABC"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Your best option is to use ConstraintLayout, like this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/greeting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Here is an excellent tutorial about ConstraintLayout: https://www.youtube.com/watch?v=4N4bCdyGcUc
To center text's container set all constraints as parent and remove any biases.
To center text inside container use android:gravity = "center"

What can I do to shrink the space between my CardViews within a RecyclerView?

So I'm learning app development for Android, and I'm a bit stuck. I'm trying to make a RecyclerView with CardViews, but there is just too much space between CardViews. This is what it looks like.
I'm going for more of the look that the Google app has with the feed.
This is more like what I'm shooting for.
Anyways, I've searched and searched on this website for a solution to my problem and nothing seems to be working for me. I'm hoping that someone can give me something that will actually work.
Here's the xml for my cardview:
<?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="wrap_content"
android:orientation="vertical"
android:paddingBottom="10dp">
<android.support.v7.widget.CardView
android:id="#+id/cv"
android:layout_width="match_parent"
android:layout_height="120dp"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="#+id/note_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="false"
android:layout_below="#+id/event_time"
android:textSize="24sp" />
<TextView
android:id="#+id/note_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/note_title" />
</RelativeLayout>
</android.support.v7.widget.CardView>
The top and bottom spaces is caused by your padding
android:paddingBottom="10dp", remove this or reduce it
Decrease the PadingBotom of the root constraintLayout
you could put 3 or 4 dp instead of 10dp.
android:paddingBottom="10dp"
Also I do not know if the copy of your code was not good ... the constraintLayout must close at the end:
after this:
</android.support.v7.widget.CardView>
you must have this:
</android.support.constraint.ConstraintLayout>
From the documentation for CardView:
Before Lollipop, CardView adds padding to its content and draws shadows to that area. ... If you want CardView to add inner padding on platforms Lollipop and after as well, you can call setUseCompatPadding(boolean) and pass true.
In your layout, you have this attribute on your CardView tag:
app:cardUseCompatPadding="true"
This does the same thing as the method in the quote above.
As a result, even if you had zero margin on all sides of your cards, users would still see space in between them because of the inner padding behavior. If you want really tight spacing, you'll have to remove this attribute (though of course you'll still get the larger spacing pre-Lollipop).

How to get rid of a TextView's margin?

This 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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="90sp"
android:text="5000"
android:id="#+id/textView"
android:layout_gravity="center"
/>
</LinearLayout>
produces the following:
I want to get rid of the top and bottom margin. Where are they coming from in the first place? Maybe for certain letters in certain fonts/languages.
There is already a thread for this question, but none of the answers really work in all situations or the solutions are hacks. There has to be a simple way.
First idea from the thread: android:includeFontPadding="true" (does not change anyting)
Second idea from the thread: android:height="90sp" (removes at least bottom margin)
So, I changed my layout regarding the ideas:
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="90sp"
android:text="5000"
android:id="#+id/textView"
android:layout_gravity="center"
android:includeFontPadding="true" <!-- idea 1 -->
android:height="90sp" <!-- idea 2 -->
/>
</LinearLayout>
Still it procudes a top margin:
Third idea from the thread: android:layout_marginTop="-12sp"
If add this property it looks at least as desired. But -12sp seems so arbitrary to me. I just adjusted this value via trial and error and I don't like that.
This does not seem like a clean solution to me. This is such a simple thing, I just cannot believe how Android can make it so hard, that you have to use hacks.
Is there a clean solution out there?
Use the below syntax to set text size programmatically and set the required size in dimes file.
textView.setTextSize(getResources().getDimension(R.dimen.textsize));
To set padding use below code based on your needs
yourTextView.setPadding(0, 10, 0, 0);
Set Linearlayout and TextView padding and margins to 0dp. Should work.
Add those to both views:
android:padding="0dp"
android:layout_margin="0dp"

RelativeLayout background stretches when inner view aligned to parent right

The following XML results in the below image.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/convoLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/right_bubble">
<TextView
android:id="#+id/convoBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" // cause
android:padding="5dp"
android:text="test test test test"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
Is anyone aware of how to get it to look like this:
Note: I need the RelativeLayout as this is a dumbed down version of my XML :).
EDIT:
Let me also clarify. Without android:layout_alignParentRight="true" in the TextView, the layout looks like the image below (there is white padding on the right)
In essence, I need that padding on the left.
EDIT2:
To further clarify, #drawable/right_bubble is a 9-patch image that is meant to stretch to house the inner views dynamically and the RelativeLayout is to have 3 TextViews inside of it, in which the 9-patch image should encapsulate all 3.
EDIT3:
This is what I want the end result to look like
you are setting the background to relative layout... so, whole layout will have same background no matter what views it holds. Try setting "android:background="#drawable/right_bubble" to TextView instead.
EDIT (by OP after getting answer from comments):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/convoLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right" // added
android:background="#drawable/right_bubble" >
<TextView
android:id="#+id/convoBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content" // removed layout_alignParentRight
android:padding="5dp"
android:text="test test test test"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
J.Ajendra's answer got me most of the way there. His answer (that I edited in after understanding his comments) worked, but only if the RelativeLayout's container honors android:layout_gravity. (for example, if we were to Activity#setContentView(R.layout.convo_item)).
In my case, convo_item.xml was to be inflated into a ListView which overrides this behavior for RelativeLayouts (I'm not sure why, but it does) resulting in the chat bubble always being on the left. To solve this, I simply wrapped the RelativeLayout in a LinearLayout that took the parents entire width (android:layout_width="match_parent") and set the gravity of it's content to "right" (android:gravity="right"). The result, it works for all cases including ListViews and Activity#setContentView(...).
Here's the code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/convoOuterLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right" >
<RelativeLayout
android:id="#+id/convoLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/right_bubble" >
<TextView
android:id="#+id/convoBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="test test test test"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
</LinearLayout>

Categories

Resources