I am trying to place a view on top of another view and a bit outside of its bounding box.
My code simplified to show the problem:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/view"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_above="#+id/linear"
android:layout_marginTop="200dp"
android:background="#color/red"
/>
<LinearLayout
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:orientation="vertical"
android:padding="0dp"
android:background="#color/white"
>
<View
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#color/orange"
/>
</LinearLayout>
</RelativeLayout>
The result:
The second arrow shows where I expected the small rectangle view.
Why does it show up on the top although I have specified the same top margin as the linear layout bellow it?
If I remove the android:layout_above="#+id/linear" then it goes where the second arrow shows either but bellow the orange view and not above it.
Why does relative layout do that?
It is not RelativeLayout that does that but nature of margins. If you put a view (orange box) and say that there is margin of 200dp above it, then no other view can be placed in that 200dp margin.
To center a orange box and then put another view above it you need to do something like this.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/view"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_above="#+id/center_view"
android:background="#color/red" />
<View
android:id="#+id/center_view"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_centerInParent="true"
android:background="#color/orange" />
</RelativeLayout>
This will put orange view in center and red view directly on top of it. Notice that you don't even need LinearLayout but can have orange view in RelativeLayout directly.
Layout_above causes it to layout with its bottom directly on top of the view its named above. If you want to make it layout directly above, you'd have 0 marginTop.
Without the layout above, it goes below because the z order is determined by the order of views in the file- the lower in the file, the higher the z order.
If you want it to appear on the upper left corner of the orange view, do layout_alignTop="#id/linear" and make sure the smaller view is later in the file than the bigger view. Do not put a margin on it.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp"
android:orientation="vertical"
android:padding="0dp"
android:background="#color/white"
>
<View
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#color/orange"
/>
</LinearLayout>
<View
android:id="#+id/view"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_alignTop="#+id/linear"
android:background="#color/red"
/>
</RelativeLayout>
When you include the attribute android:layout_marginTop="200dp" in the LinearLayout android:id="#+id/linear", the margin is considered to be a part of the LinearLayout container.
Hence, effectively, the container wrapping the LinearLayout includes the margin android:layout_marginTop="200dp". And since your root layout is a Relative Layout, the LinearLayout is aligned to the top of the root layout by default (since the LinearLayout doesn't contain any relative attributes like android:layout_below, android:layout_above etc). So when you include the android:layout_above="#+id/linear" attribute in your View tag given by android:id="#+id/view", it is trying to place the View above LinearLayout which starts from the top of the screen.
A better way to code your layout would be:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/view"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginTop="200dp"
android:background="#color/red"
/>
<LinearLayout
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_below="#+id/view"
android:orientation="vertical"
android:padding="0dp"
android:background="#color/white"
>
<View
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#color/orange"
/>
</LinearLayout>
</RelativeLayout>
Related
I want to separate the 4 icon with equal space like pic1.
And the XML code for pic1 is:
However, at the first time, I set the Blank View height as wrap_content, then the result showed like this:
.
The code for pic2 is:
.
The only difference is highlight by red rectangle.
In the case of this layout, you will get more from a ConstraintLayout.
Specifically, setting your icons within a ConstraintLayout would look like this to get the balanced look you're going for:
<?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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/check"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/image_2"
app:layout_constraintHorizontal_chainStyle="spread_inside"/>
<ImageView
android:id="#+id/image_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/check"
app:layout_constraintStart_toEndOf="#id/image_1"
app:layout_constraintEnd_toStartOf="#id/image_3"
app:layout_constraintHorizontal_chainStyle="spread_inside" />
<ImageView
android:id="#+id/image_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/check"
app:layout_constraintStart_toEndOf="#id/image_2"
app:layout_constraintEnd_toStartOf="#id/image_4"
app:layout_constraintHorizontal_chainStyle="spread_inside" />
<ImageView
android:id="#+id/image_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/check"
app:layout_constraintStart_toEndOf="#id/image_3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="spread_inside"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The takeaways from this snippet that get your look are:
horizontal Orientation for the ConstraintLayout
Constraints for each ImageView that attach them to the one before and after
First view is constraint to the parent, specially, as is the last view
app:layout_constraintHorizontal_chainStyle="spread_inside", says to spread them out evenly within the available space.
If you don't want them touching the sides, add padding to the left/right of the parent ConstraintLayout.
Use this code in place of that linearlayout containing all the icons:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content">
<!--keep your first icon code here-->
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content">
<!--keep your second icon code here-->
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content">
<!--keep your third icon code here-->
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content">
<!--keep your fourth icon code here-->
</LinearLayout>
</LinearLayout>
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".
I have implemented persistent bottom sheet with FAB anchored to the top of it.
When I try to do the same with modal bottom sheet (extends BottomSheetDialogFragment) it says
java.lang.IllegalStateException: Could not find CoordinatorLayout descendant view to anchor view android.support.design.widget.FloatingActionButton
Is it possible to do the same layout with modal bottom sheet or maybe make a shadow and unclickable area above persistent one?
I was trying to do the same "FAB on top" thing in ModalBottomSheet, but there's no direct method/way to do that.
For such cases, we therefore use FrameLayout. Inside the definition, it says that -
Child views are drawn in a stack, with the most recently added child on top.
So we can create a layout for the ModalBottomSheet (extends BottomSheetDialogFragment), which would look something like this in your case -
<FrameLayout
android:id="#+id/parent_frame_layout"
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"
tools:context=".ModalBottomSheetFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="25dp"
android:orientation="vertical">
<!-- Whatever layout you want to give here. This is going to be the body
of the ModalBottomSheet. Also you might not wanna use the current Linear
Layout too.-->
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/icon_sheet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:layout_gravity="center|top"
android:src="#drawable/ic_music"
android:elevation="20dp"/>
</FrameLayout>
Notice that -
FAB is made after LinearLayout (body for the BottomSheet), as it would be stacked over the LinearLayout.
We gave a marginTop=25dp for LinearLayout but we gave marginTop=0dp for the FAB. This is how you create the half-out, half-in effect. And also gave elevation on FAB for better float look.
Finally we can inflate it's view inside the onCreateDialog overridden method and perform all necessary actions thereafter.
Hope I was able to answer your question. Do comment for any further doubts/updates.
Adding to #Krishn Agarwal answer we need to make sure the bottom sheet dialog has a transparent theme then only the same look and feel will be achieved. We can even have a Constraint Layout instead of a Linear Layout. We can use BottomSheetDialog/BottomSheetDialogFragment
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="#+id/parent_frame_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/cl_success_dialog"
style="#style/AppModalStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/margin_60"
android:paddingStart="#dimen/dimen_25"
android:paddingEnd="#dimen/dimen_25"
android:paddingBottom="#dimen/dimen_25">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tv_title_text"
style="#style/style_bottomsheet_header_22sp"
android:gravity="center"
android:layout_marginTop="80dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="#string/mf_mandate_creationsuccessful" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tv_description"
style="#style/open_sans_semi_bold_15sp_gray"
android:layout_marginTop="#dimen/dimen_7"
android:layout_marginBottom="#dimen/margin_25"
app:layout_constraintBottom_toTopOf="#+id/go_to_dashboard_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_title_text"
tools:text="Description" />
<androidx.appcompat.widget.AppCompatButton
android:id="#+id/go_to_dashboard_btn"
style="#style/mf_style_blue_button"
android:layout_width="0dp"
android:elevation="#dimen/margin_5"
android:text="#string/mf_go_to_dashboard"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv_description"
tools:targetApi="lollipop" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floating_tick_icon"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_gravity="center|top"
android:layout_marginTop="0dp"
android:importantForAccessibility="no"
android:visibility="visible"
app:backgroundTint="#color/very_light_green"
app:elevation="#dimen/margin_20"
app:fabCustomSize="128dp"
app:maxImageSize="128dp"
app:srcCompat="#drawable/ic_success_tick"
app:tint="#null" />
</FrameLayout>
<?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="match_parent"
android:weightSum="10"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:layout_weight="2">
<TextView
android:id="#+id/centerText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#FFFFFF"
android:textSize="28sp"
android:text="HALLO ALLE"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/centerText"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10"
android:layout_weight="8"
android:orientation="horizontal">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Btn 1"
android:layout_weight="2"/>
</LinearLayout>
Hi everybody, this is my code and I have a question about this I set a weightSum in the first LinearLayout I set the weightSum of 10, which the RelativeLayout has 2/10 and the other one (LinearLayout) has 8/10, as I saw in the preview of my IDE (Android Studio), the RelativeLayout is the bigger one here's my question:
The layout_weight with less value will be the bigger one?
No, the larger value for layout_weight should be the bigger one.
When using layout_weight you should set either the height or width to 0dp; in a vertical layout you're dealing with height and in a horizontal one it's width.
So in your case your root layout is a vertical LinearLayout. Within that, your relative layout with a weight of '2' should have android:layout_height="0dp" and the same for your LinearLayout with a weight of '8'.
From the documentation:
A larger weight value allows it to expand to fill any remaining space in the parent view
The key part here is "remaining space"
This means that if the RelativeLayout height is bigger them half of its parent height, it will be bigger then the LinearLayout no matter to what value you set its android:layout_weight property
I believe you are looking for something like this: (top takes up 20% bottom takes up 80%)
<?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="match_parent"
android:weightSum="5"
android:orientation="vertical">
<!-- Specify height as 0dp-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
android:layout_weight="1">
<TextView
android:id="#+id/centerText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#FFFFFF"
android:textSize="28sp"
android:text="HALLO ALLE"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/centerText"
android:text="Button top"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
<!-- Specify height as 0dp -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"
android:orientation="horizontal">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Btn 1"/>
</LinearLayout>
</LinearLayout>
When dealing with layout weights you supply 0dp to the layout width or height of the weighted item when parents orientation is horizontal or vertical.
When ever using weights it is better to use corresponding one to 0dp and then use the layout_weight....like
In Case of android:orientation="horizontal"
Use the following code
android:layout_width="match_parent"
android:layout_height="0dp"
In Case of android:orientation="vertical"
Use the following code
android:layout_width="0dp"
android:layout_height="match_parent"
I have some FrameLayout to display overlapping images. Under this FrameLayout I want to display a standard button for some click-action.
To make my work easier, I thought, I can put a new Linear, or Relative, Layout under the FrameLayout - surely all in one LinearLayout.
But this method isn't working for me.
What is the best way to show my button under a whole FrameLayout without putting it in the Layout and managing his position programmaticaly?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<FrameLayout
android:id="#+id/framelayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|left" >
<ImageView
android:id="#+id/coverimg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|left"
android:maxHeight="100dp"
android:minHeight="130dp"
android:minWidth="130dp"
android:src="#drawable/cover_img" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="100dp"
android:src="#android:drawable/ic_media_play" />
<ProgressBar
android:id="#+id/progressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Button" />
</LinearLayout>
</LinearLayout>
first to say:
your orientation of the first LinearLayout is wrong. You should use vertical instead of horizontel, cause it would show the button right of your images and not below.
second:
no nead to wrap the button into another LinearLayout, cause it's a sinlge item and attached to your first LinearLayout.
third:
to set the button on another 'place', give your top LinearLayout an ID like 'android:id="#+id/myLinear"' and then use following code:
LinearLayout myLinear = (LinearLayout)this.findViewById(R.id.myLinear);
LayoutParams lp = new LinearLayout.LayoutParams(Gravity.CENTER);
myLinear.setLayoutParams(lp);
maybe this will work to:
LinearLayout myLinear = (LinearLayout)this.findViewById(R.id.myLinear);
myLinear.setLayoutParams(new LinearLayout.LayoutParams(Gravity.CENTER));
Hope i could help you?
First you change Linear layout orientation to vertical, and second no need to use another
layout u can put button directly
Ex: android:orientation="vertical"