Use margin on an include layout - android

This is a follow up question to this question:
Margin does not impact in "include"
I am trying to add a margin to an include layout. I have added layout_width and layout_height to the include element, but the margin is still ignored. Furthermore, when I try to auto complete the word "margin" in the layout xml file, this attribute is not even recognized.
So how can I add a margin to an include tag?
The layout:
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/main_status"
/>
<!--
As the main content view, the view below consumes the entire
space available using match_parent in both dimensions.
-->
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
<!--
android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
If you're not building against API 17 or higher, use
android:layout_gravity="left" instead.
-->
<!--
The drawer is given a fixed width in dp and extends the full height of
the container.
-->
<fragment
android:id="#+id/navigation_drawer"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="left"
tools:layout="#layout/fragment_navigation_drawer" />

As you can see, the LinearLayout's height is set to match_parent. I still want it like that, but that's what caused the included layout and container layout be on top of each other when trying to add margin inside the layout that I wanted to include.
So what I did that got me the effect I wanted was setting the paddingTop attribute of the linear layout container. It created some space between the included layout and the linear layout.

Related

Using NavigationView with SlidingPaneLayout

Per Google's Material Design guideline for Navigation drawer, to achieve Standard drawer for tablet or desktop devices, I would use NavigationView with SlidingPaneLayout for tablet devices instead of DrawerLayout for phone devices, which is to achieve Modal drawer.
I put a NavigationView as the first child view of SlidingPaneLayout. A problem occurred.
As you know SlidingPaneLayout's child views overlap if their combined width exceeds the available width in the SlidingPaneLayout. In this case, the child views expand to fill the available width in the SlidingPaneLayout. The user can slide the topmost view out of the way by dragging it back from the edge of the screen.
But my NavigationView's pane wouldn't slide. It just appears or disappears at maximum width without sliding animation.
How can I solve this?
<androidx.slidingpanelayout.widget.SlidingPaneLayout
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">
<!-- The first child view becomes the left pane. When the combined
desired width (expressed using android:layout_width) would
not fit on-screen at once, the right pane is permitted to
overlap the left. -->
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigationView"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_view_header"
app:menu="#menu/navigation_view" />
<!-- The second child becomes the right (content) pane. In this
example, android:layout_weight is used to expand this detail pane
to consume leftover available space when the
the entire window is wide enough to fit both the left and right pane.-->
<fragment
android:id="#+id/navigationHost"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="320dp"
android:layout_weight="1"
android:layout_height="match_parent"
app:navGraph="#navigation/main" />
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
Add app:elevation="0dp" to the NavigationView.
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:elevation="0dp"
app:headerLayout="#layout/navigation_view_header"
app:menu="#menu/navigation_view" />
If you inspect the layout, you can notice the NavigationView has elevation of 16dp by default. This causes the problem. It is probably that SlidingPaneLayout handles the two child views under the condition that they have the same elevations (0dp).
So a solution is to override NavigationView's default elevation (16dp) with 0dp.
Another solution is to wrap NavigationView with a FrameLayout or some ViewGroup.
<FrameLayout
android:layout_width="280dp"
android:layout_height="match_parent">
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_view_header"
app:menu="#menu/navigation_view" />
</FrameLayout>
Then, you should specify layout_width with FrameLayout and NavigationView's layout_width to match_parent.
In spite of NavigationView's default elevation of 16dp, for its parent ViewGroup's elevation is 0dp, SlidingPaneLayout can properly handle.

Applying max height to BottomSheetDialogFragment and apply height change transitions

I have a BottomSheetDialogFragment that holds multiple Fragments of different sizes as a content in the FrameLayout.
The max height of the BottomSheetDialogFragment container needs to set at 60% of the total height of the current window viewport.
In addition, I also need to apply transitions when the content displayed within the BottomSheetDialogFragment changes its height such that the height changes smoothens out while rendering.
In other words, the height of the container should stay fixed no matter whatever the content displayed be in BottomSheetDialogFragment. And once the height of the content exceeds the height of the specified height, the content becomes scrollable. Said that, there can be content whose height is less than the max height and hence the transition should be applied to layout height changes.
Here's a layout hierarchy that matches what I have:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:animateLayoutChanges="true"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_short_height" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#id/button_container"
app:layout_constraintTop_toTopOf="parent" />
<!-- This layout always sticks to the bottom of the BottomSheet when opened -->
<RelativeLayout
android:id="#+id/button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
PS: The view hierarchy still can be simplified but I am trying to use BottomSheetDialogFragment which can be used without specifying BottomSheetBehavior and so it's intended to avoid using CoordinatorLayout.
As per https://material.io/develop/android/components/bottom-sheet-behavior/
Using BottomSheetDialogFragment provides a similar UI and interactions as BottomSheetBehavior, however BottomSheetDialogFragment does not require CoordinatorLayout and creates a modal bottom sheet (essentially a dialog).

How to add flexible sizing to layout components of android

Is there any way to add flexible sizing attributes to in XML of android layout.
I want to add elements such that the height/width of one element equals to height of parent minus another element.
Like in CSS, we can use calc() function
Ex: calc(100% - 100px)
Is there a way to do something similar in android, like:
I set
android:layout_height="?attr/actionBarSize"
So, is there anything like:
<RecyclerView
android:layout_height = "(match_parent - ?attr/actionBarSize)"/>
Is there any way to achieve this in XML itself and not with java in the activity?
No there is not. But you can do it by using margins.
For example if you need to "cut" the height of a RelativeLayout from bottom you can use:
android:layout_marginBottom="?android:attr/actionBarSize"
or if you want to do it from the top:
android:layout_marginTop="?android:attr/actionBarSize"
Yes you can do that in Relative layout as below
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/button" />
</RelativeLayout>
As in above code first i placed button at bottom.Now for remaining place i want to display listview. So i place listview above button and make it match_parent.So it will all remaining space.

match_parent within wrap_content layout

I'm trying to find documentation or guidelines as to behaviour of a UI component with the layout_width/layout_height set to match_parent within a ViewHolder of layout_width/layout_height of wrap_content.
So for instance, what is the EXPECTED result of the following layout?
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
/>
</RelativeLayout>
By the description here, the layout of your example would depend on what you put inside the LinearLayout. That content would expand to fill all available vertical space within the parent RelativeLayout. By default, the LinearLayout would be positioned at the top left of the parent RelativeLayout

Include layout inside another one: strange behavior of wrap_content

I have a layout (principal) that include another layout. In principal Layout I include the other one like
<include
android:id="#+id/other_layout_id"
android:layout_height="match_parent"
layout="#layout/other_latyout_name" />
and this is code of my other layout that represent a custom row with some elements (some text and a button):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relative_row_opponent"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- other widget, all with wrap_content -->
If inside principal layout, in include tag i specify
android:layout_height="wrap_content"
other layout take all vertical space inside principal layout and I doesn't expect this behavior. why happen this?
Acoording to the http://developer.android.com/training/improving-layouts/reusing-layouts.html#Include
You can also override all the layout parameters (any android:layout_* attributes) of the included layout's root view by specifying them in the <include/> tag.
Also
However, if you want to override layout attributes using the <include> tag, you must override both android:layout_height and android:layout_width in order for other layout attributes to take effect.
So what you should do is
<include
android:id="#+id/other_layout_id"
android:layout_height="match_parent"
android:layout_width="match_parent"
layout="#layout/other_layout_name" />
Here I have included android:layout_width property along with android:layout_height as suggested by the website.
I haven't tested it. But hope it helps.

Categories

Resources