Problem with relative layouts: anchored elements at the top right - java

I'm trying to create an android application but I'm a beginner, especially with the XML. I don't know why, if I put Relative layout and move the widgets they remain anchored at the top left. does anyone know why?
ps I would like to work on the window design not on the code. Anyway I leave you the code in case there is something wrong
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Tentativo">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Number"
android:textSize="50dp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.255"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.299" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play"
tools:layout_editor_absoluteX="247dp"
tools:layout_editor_absoluteY="211dp" />
</RelativeLayout>

You are facing this problem because you are using the wrong attributes. The attributes you are using are meant for Constraint Layout and not Relative layout.
For Example: in case of TextView instead of using app:layout_constraintRight_toRightOf="parent" try using android:layout_alignParentRight="true"
Also, I would like to recommend you to use Constraint Layout instead of Relative as is much better and easier to use. example: To center a view in a RelativeLayout you would write centerInParent=true. Constraint Layout instead allows centering in-between views and the parent.

relative layout works great with nested sibling Containers, just add a container, and add the Widgets inside the container, my favorite one to use when Relative Layout is the parent is the Linear Layout, it makes the UI much cleaner and uses weights which is great for supporting different screen ratios. Here is a sample Example for your case (also you can remove all the constraints in the widget since their parent is no longer the relative 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_centerHorizontal="true"
android:gravity="center"
android:weightSum="2"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Number"
android:layout_weight="1"
android:textSize="50dp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.255"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.299" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Play"
tools:layout_editor_absoluteX="247dp"
tools:layout_editor_absoluteY="211dp" />
</LinearLayout>
</RelativeLayout>

Related

How do i create a container in constraintlayout so i can set a background?

How can i group views in a constraint layout without nesting viewgroups?
<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"
android:orientation="vertical"
android:background="#color/color1">
<ImageView
android:id="#+id/mAlbumArtLarge"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
android:src="#drawable/image1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<android.support.constraint.ConstraintLayout
android:id="#+id/mBottomSheet"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#20000000"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/mAlbumIvBottom"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="5dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
This is what i'm doing now to create a container mBottomSheet where i can group views and set a background, but i'm using another viewgroup constraintlayout for this which is not recommended because the point of constraintlayout is too have a flat view hierarchy.
So how can i achieve the same thing, but without using another viewgroup as a container?
EDIT
example:
You can use Gudeliens to achieve something similar.
For example, you can take some view (let's call it x) and place on your layout and just put all your wanted views above x.
As for the Gudeliens, with them, you can place your x in any way that you would want to use using app:layout_constraintGuide_percent attribute.
Take this layout for example:
<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"
android:background="#color/colorPrimary"
android:orientation="vertical">
<ImageView
android:id="#+id/mAlbumIvBottom"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#drawable/ic_launcher_background"
android:scaleType="fitXY"
android:elevation="6dp"
android:layout_margin="6dp"
app:layout_constraintBottom_toTopOf="#+id/guideline6"
app:layout_constraintEnd_toStartOf="#+id/guideline7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/button2" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="I am view x"
app:layout_constraintBottom_toTopOf="#+id/guideline6"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Guideline
android:id="#+id/guideline6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent=".15" />
<android.support.constraint.Guideline
android:id="#+id/guideline7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent=".3" />
</android.support.constraint.ConstraintLayout>
This layout will look like this without any nesting views: (I am adding preview image to you could better understand guidelines)
The layout above is an example of how you could achieve this without using nested view groups.
This solution will work for you but I also agree with user1506104.
It's ok to have a very small level of nesting, if you don't overdo it your layout performance could stay the same
You can either go with my solution or have some nesting views (again, don't overdo it)
I prefer to use my solution so I can avoid nesting.
Just remember that my solution may be a bit longer than just having some lever of nesting when creating your layout.
You can try:
androidx.constraintlayout.widget.Group
or
You can group your Views together by assigning Constraints with respect to each others position but you won't be able to apply a background on all of the widgets as they are still the child of the parent ViewGroup. There are many other options to avoid using nested ConstraintLayout.
You can use another ViewGroup like LinearLayout or RelativeLayout inside ConstraintLayout.
You can create a seperate layout for BottomSheet and include it, for clean code

Android : How to clip views by parent, like CSS overflow:hidden

I have views as follows :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/global_legal_gap"
android:clipToPadding="true"
android:clipChildren="true"
android:baselineAligned="false"
android:background="#drawable/post_sound_bg"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="#dimen/post_sound_card_height"
android:layout_height="#dimen/post_sound_card_height">
<com.facebook.drawee.view.SimpleDraweeView
android:id="#+id/album_art"
android:layout_width="#dimen/post_sound_card_height"
android:layout_height="#dimen/post_sound_card_height"
fresco:backgroundImage="#drawable/music_placeholder" />
<RelativeLayout
android:id="#+id/play_icon_control"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:visibility="gone">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_margin="3dp" />
</RelativeLayout>
</RelativeLayout>
<LinearLayout>
As shown in the parent RelativeLayout, I'm using android:clipToPadding="true" and
android:clipChildren="true", yet the children of this parent view are still protruding outside it.
Or I'm I doing this right? How do I achieve something like CSS's overflow:hidden?
Consider changing layouts. What you want can be done with ConstraintLayout.
Just set the the dimensions of the layout and don't set the constraint on the part you want to overflow/hide.
The following code shows a View that adjusts it dimensions to its constraint and another that overflows.
Create a new android project and paste this as activity_main.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"
tools:context=".MainActivity"
android:layout_margin="55dp">
<ImageView
android:id="#+id/imageView3"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#android:drawable/sym_def_app_icon"/>
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_begin="84dp"/>
<ImageView
android:id="#+id/imageView4"
android:layout_width="0dp"
android:layout_height="300dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/guideline"
app:srcCompat="#mipmap/ic_launcher"/>
</android.support.constraint.ConstraintLayout>
Your parent view has
android:layout_width="match_parent"
android:layout_height="wrap_content"
which means that the view takes all available width and up to all available height if child views are large enough. With this setup you can't seethe overflow:hidden behaviour because the parent will resize itself to contain children up to the whole screen size.
Actually, default view behaviour in android is similar to overflow:hidden.
What you need to do to see it is set fixed dimentions on the parent.
Just try to use something like:
<LinearLayout
android:layout_width="20dp"
android:layout_height="20dp"
and you'll get the idea.
On a different note, you don't need to have a LinearLayout just to host a RelayiveLayout - use the RelativeLayout directly. Also, using android:orientation="horizontal" makes it behave similarly to flexbox direction row, not sure if that's something you want here.
In native Android, overflow: hidden is android:clipToOutline="true".

My app layout is different from activity_main layout design

I'm trying to make a imperial to metric conversion app, which is going fine, until I ran into problems with the Android Emulator. The layout is totally screwed up in the Emulator, and I have no idea why. http://imgur.com/a/IBOcs
EDIT:
The whole activity_main.xml code:
<?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="com.example.daniel.converter.MainActivity"
tools:layout_editor_absoluteY="73dp"
tools:layout_editor_absoluteX="0dp">
<TextView
android:id="#+id/textViewMPH"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MPH"
tools:layout_editor_absoluteX="55dp"
tools:layout_editor_absoluteY="90dp" />
<EditText
android:id="#+id/editTextMPH"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
tools:layout_editor_absoluteX="85dp"
tools:layout_editor_absoluteY="77dp" />
<TextView
android:id="#+id/textViewTO"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="To"
tools:layout_editor_absoluteX="55dp"
tools:layout_editor_absoluteY="132dp" />
<TextView
android:id="#+id/textViewKMH"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="KMH"
tools:layout_editor_absoluteX="55dp"
tools:layout_editor_absoluteY="168dp" />
<EditText
android:id="#+id/editTextKMH"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
tools:layout_editor_absoluteX="85dp"
tools:layout_editor_absoluteY="156dp" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Convert!"
tools:layout_editor_absoluteX="146dp"
tools:layout_editor_absoluteY="229dp" />
</android.support.constraint.ConstraintLayout>
Issue is happening because you are using constraint layout but you have not provided any constraints for your items. Thus, every item is shown at (0,0) position.
Contraint Layout description:
The layout editor allows you to place widgets anywhere on the canvas, and it records the current position with designtime attributes (such as layout_editor_absoluteX.) These attributes are not applied at runtime, so if you push your layout on a device, the widgets may appear in a different location than shown in the editor. To fix this, make sure a widget has both horizontal and vertical constraints by dragging from the edge connections.
So either assign x and y values or use LinearLayout/RelativeLayout.

Doesn't wrap_content adjust to the size of fonts?

My understanding was that the wrap_content take as much space as needed by its contents. But doesn’t this apply to TextViews as well?
In the following layout why when I change the font of TextView with id real_status to 24 the text is partially hidden? I was expecting that due to the wrap content the enclosing TextView it would wrap around the 24 sp and display the text fine. It is fine with 18sp.
Layout:
<?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:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
<TextView
android:id="#+id/real_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/full_display_name"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/full_display_name"
android:gravity="center_vertical"
android:textSize="24sp"
android:textStyle="bold"
tools:text="Active"
/>
<TextView
android:id="#+id/full_display_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#id/real_status"
android:gravity="center_vertical"
android:text="The real user status:"
android:textSize="16sp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/full_display_name"
android:gravity="right"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:visibility="gone"
tools:text="Just a text view"
tools:visibility="visible" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
With 18sp:
With 24sp:
UPDATE:
Following the answers I removed the layout top/bottom and the font adjusted but now I see that the TextView overlaps with the next widget. Adding red background is more visible.
I thought that by “growning” the TextView the rest would move down and not overlap
whenever You suffering from this type of problem You can LiniarLayout is best if You understand it very well. because of wrap_content and match_parent is simple to handle in LiniarLayout.
lets understand it.(For Your case)..
1.take two LiniarLayout(parent have verticle orientation..)
i give Id LL1(horizontal) and id LL2 for your case
2.in first layout two textview #+id/full_display_name and #+id/real_status
in real_status have match_parent in width so it easy to divide parent(fill_parent) and set its android:gravity="right"
3.LiniarLayout as it is without relate
See belove XML code...
<?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="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/LL1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/full_display_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The real user status:"
android:textSize="16sp" />
<TextView
android:id="#+id/real_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:text="Active"
android:textSize="26sp" />
</LinearLayout>
<LinearLayout
android:id="#+id/LL2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/real_status"
android:gravity="right" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="Just a text view" />
</LinearLayout>
</LinearLayout>
It will help you Your GUI give bestView in All devices with any size of text
Hope it help You
Remove these two line will fix your problem
android:layout_alignBottom="#+id/full_display_name"
android:layout_alignTop="#+id/full_display_name"
Yes the wrap_content will take as much space needed by the view. It will also applied to the TextView also. The problem here is you written android:layout_alignBottom="#+id/full_display_name" to real_status text view. This attribute is overriding the wrap_content So remove allignBottom attribute from the text view.
UPDATE
For your bottom linear layout update the line
android:layout_below="#+id/full_display_name"
with
android:layout_below="#+id/real_status"

Position Of Views in Android vs iOS?

I am new to Android development. I have been working in iOS since long. As in iOS when we want to put VIEW on xib on some exact position, we simply put it there, drag it up to that point.
For example say Two buttons at lower area in iOS, which look like below
As, I simply want them in middle, I will put them their. as below
Now same thing in Android environment, I go for following code,
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/db1_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/myAwesomeTextView"
android:layout_width="wrap_content"
android:layout_height="1dip"
android:layout_centerInParent="true"
android:text="Veer Suthar" />
<TextView
android:id="#+id/myAwesomeTextView1"
android:layout_width="wrap_content"
android:layout_height="100dip"
android:layout_below="#id/myAwesomeTextView"
android:layout_centerInParent="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/myAwesomeTextView1"
android:gravity="center_vertical"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center"
android:onClick="buttonPressed"
android:text="Button One" />
<Button
android:id="#+id/button2"
style="?android:attr/buttonStyleSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center"
android:onClick="buttonPressed"
android:text="Button Two" />
</LinearLayout>
</RelativeLayout>
It shows Activity Screen, like below
Now If I want to drag buttons, using GRAPHICAL LAYOUT, I can't move them as I want, and for spacing to put them into lower area, I need to put extra TextView .
Is there any better way to organise Android Activity GUI properly, like iOS?
I'll give you a brief example, since Android graphical layout is not as smooth as XCode.
To accomplish what you need, centering the two buttons in the screen, you can use a XML code like this:
<?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" >
<LinearLayout
android:id="#+id/layout_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true">
<Button
android:id="#+id/button_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button One"/>
<Button
android:id="#+id/button_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button Two"/>
</LinearLayout>
</RelativeLayout>
The trick is to use android:layout_centerInParent="true" for the only component that you want to be centered in the screen all other components can use that one for reference to be placed in the screen.
For example
<TextView
android:id="#+id/myAwesomeTextView1"
android:layout_width="wrap_content"
android:layout_height="100dip"
android:layout_above="#+id/layout_center"
android:text="Veer Suthar"/>
This is one way for doing this, you can always find a better and more comprehensible way to do things.
Hope this helped.
Add this to your LinearLayout:
android:layout_alignParentBottom = "true"
Childs in a RelativeLayout can be "glued" to a particular position relative to the parent layout or to other elements in the same layout using the xml tags listed here: http://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams.html

Categories

Resources