I want a view to be anchored between AppBarLayout and layout. I get this behavior only on Android Studio editor, but on real device is different like so:
I am really confused. My code is:
<android.support.design.widget.CoordinatorLayout 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="view.activity.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="84dp"
android:layout_marginTop="#dimen/activity_vertical_margin">
<!--views on toolbar-->
</RelativeLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/activity_home_content" />
<RelativeLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:background="#drawable/circle_accent"
app:layout_anchor="#+id/whole_layout"
app:layout_anchorGravity="top|start">
<!--img view-->
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
and 'activity_home_content'
<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:id="#+id/whole_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="view.activity.MainActivity"
tools:showIn="#layout/activity_home_toolbar">
<!--some other views-->
</LinearLayout>
Just tried it. As I mentioned in the comments, your whole_layout is a LinearLayout with elevation 0dp. Any element you anchor to this LinearLayout will receive an elevation of 0dp (same as the view you are anchoring to) by default. This means that the RelativeLayout will have an elevation of 0dp.
The AppBarLayout has an elevation of 4dp, so by default the RelativeLayout will always be drawn below it.
The Fix
Give an elevation to the relative layout that is greater than or equal to 4. This will fix your problem, except that the RelativeLayout will now cast a shadow too.
Here is the code for the RelativeLayout
<RelativeLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginStart="#dimen/activity_horizontal_margin"
android:background="#drawable/circle_accent"
app:layout_anchor="#+id/whole_layout"
app:layout_anchorGravity="top|start"
android:elevation="4dp">
<!--img view-->
</RelativeLayout>
Related
Scrollbars not working. I have given the scrollbars as parent view, but still, my screen is not scrolling. I am not able find out the problem.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:fadeScrollbars="false"
android:scrollbars="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Featured Image -->
<ImageView
android:id="#+id/image_tv"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="#drawable/sandwich"
android:adjustViewBounds="true"
android:contentDescription="#string/sandwich_picture_content_description"
android:scaleType="centerCrop" />
<!-- Tabbed Toolbar + Pager -->
<RelativeLayout
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="wrap_content"
android:layout_alignParentTop="true"
android:background="#color/colorPrimaryDark"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:textAlignment="center"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
tools:ignore="NewApi" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="#fff"
android:layout_below="#+id/toolbar"
android:background="#color/colorPrimaryDark"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<androidx.viewpager.widget.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/tab_layout" />
</RelativeLayout>
</LinearLayout>
</FrameLayout>
</ScrollView>
I have given the scrollbars as parent view, but still, my screen is not scrolling. I am not able to find out the problem. I have given the scrollbars as parent view, but still, my screen is not scrolling. I am not able to find out the problem.
Wrap the FrameLayout with a LinearLayout or RelativeLayout such that this Layout becomes the direct child of your Scrollview.
Also, instead of Parent view as ScrollView, Add a RelativeLayout as the parent followed by ScrollView.
RelativeLayout -> ScrollView -> LinearLayout -> FrameLayout.
The problem is simple. I have a TabLayout inside a CoordinatorLayout, and I dynamically set a CustomView for each Tab at runtime. The tabs have some animations and custom content that currently gets clipped at the Tab's edges.
I've set clipToPadding and clipChildren to false throughout all the view hierarchy with no success. Tabs are still getting clipped.
So the question is, how to avoid clipping tab's custom views inside a TabLayout?
Here's some code so you can see what I'm doing:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:clipChildren="false"
android:fitsSystemWindows="false"
tools:context=".MainTabbedActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:elevation="4dp"
android:clipToPadding="false"
android:clipChildren="false"
android:fitsSystemWindows="false"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:clipToPadding="false"
android:clipChildren="false"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:clipChildren="false"
app:tabPaddingBottom="-1dp"
app:tabPaddingEnd="-1dp"
app:tabPaddingStart="-1dp"
app:tabPaddingTop="-1dp"
app:tabIndicatorColor="#android:color/white"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
... />
And then, a custom Tab looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="32dp"
android:scaleType="fitCenter"
android:layout_marginBottom="-4dp"
android:adjustViewBounds="true"
android:id="#+id/tab_pic" />
<TextView
android:id="#+id/tab_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/something"
android:textColor="#color/white"
android:textStyle="bold"
android:textSize="12sp"
android:visibility="invisible"/>
The result is the ImageView being clipped when animating its position/bounds.
Cheers
Ok, this was quick. I found the solution. It seems to me that Android creates an intermediate parent view between the TabLayout and the actual tab content.
So doing the following for each tab...:
ViewGroup realTabs = ((ViewGroup) mTabLayout.getChildAt(0));
realTabs.setClipToPadding(false);
realTabs.setClipChildren(false);
if (realTabs.getChildAt(0) instanceof ViewGroup) { // <-- This is the intermediate parent ViewGroup
((ViewGroup)realTab0.getChildAt(0)).setClipToPadding(false);
((ViewGroup)realTab0.getChildAt(0)).setClipChildren(false);
}
...will solve the problem.
Thanks
This is the activity_main.xml layout for Androids default tab application:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".activities.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<!-- When I add my own view here and use match_parent, it fills ENTIRE screen, even over the Toolbar. The ViewPager right above does not do this. Why? -->
</android.support.design.widget.CoordinatorLayout>
I am trying to add my own buttons/textviews/etc to my activity_main.xml but I do not know where to add them. The android.support.v4.view.ViewPager uses match_parent although it does not fit the whole screen, it expands across the entire screen besides the Toolbar area at the top. However, whenever I add my own view underneath the android.support.v4.view.ViewPager, lets say RelativeView and set it to match_parent, it expands OVER the Toolbar. This led me to believe that I should put my contents inside the ViewPager tags but that does not work either.
Where should I put my views so that they are not overlapping the Toolbar?
You can wrap your ViewPager in an RelativeLayout and you can add the view child also.
Here is the code snippet which may help you-
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorAccent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="48dp"
android:text="I am clickable" />
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/button"
android:background="#color/colorNeutral"
android:layout_above="#+id/button2" />
<Button
android:layout_marginBottom="56dp"
android:layout_alignParentBottom="true"
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="48dp"
android:text="I am clickable too" />
</RelativeLayout>
I have a problem where sometimes the AppBarLayout will not show its full content all the time when you play around with it:
<android.support.design.widget.CoordinatorLayout
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.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.AppBarLayout
android:orientation="vertical"
android:layout_height="148dp"
android:layout_width="match_parent">
<android.support.design.widget.TabLayout
app:layout_scrollFlags="scroll|enterAlways"
android:layout_height="48dp"
android:background="#color/primarycolor"
.../>
<RelativeLayout
app:layout_scrollFlags="scroll|enterAlways"
android:background="#color/white"
android:layout_height="100dp"
...>
</RelativeLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
A solution provided is
CoordinatorLayout Toolbar invisible on enter until full height
BUT: it provides a full line that is not the same color as the primary color I specify in the bottom layout, because its background is white. Thoughts?
This is a solution extending the one provided above:
Use this instead of the one provided, which will blend the appbarlayout and the subtle shadow elevation below it.
<View
android:id="#+id/appbar_bottom"
android:layout_width="match_parent"
android:layout_height=".3dp"
android:background="#606060"
android:visibility="visible"/>
and the resultant layout:
<android.support.design.widget.AppBarLayout
android:orientation="vertical"
android:layout_height="148.3dp"
android:layout_width="match_parent">
<android.support.design.widget.TabLayout
app:layout_scrollFlags="scroll|enterAlways"
android:layout_height="48dp"
android:background="#color/primarycolor"
.../>
<RelativeLayout
app:layout_scrollFlags="scroll|enterAlways"
android:background="#color/white"
android:layout_height="100dp"
...>
</RelativeLayout>
<View
android:id="#+id/appbar_bottom"
android:layout_width="match_parent"
android:layout_height=".3dp"
android:background="#606060"
android:visibility="visible"/>
</android.support.design.widget.AppBarLayout>
I´m attempting to use the new Android Design Library´s CoordinatorLayout inside of another layout. The CoordinatorLayout contains a RecyclerView. What I´m attempting to do is to place a simple LinearLayout below the CoordinatorLayout. This layout should be placed below the CoordinatorLayout. This is XML I´m using:
<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="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="fill_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/conversation_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="150dp"
android:orientation="horizontal">
<EditText
android:layout_width="fill_parent"
android:layout_height="match_parent" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/ic_send_white_36dp" />
</LinearLayout>
</LinearLayout>
As you can see, I´m attempting to wrap the CoordinatorLayout inside another LinearLayout. However, on-screen the second part of the layout doesn´t even render.
That is because the CoordinatorLayout has layout_height="match_parent". That means it takes the whole size of the screen and your LinearLayout is rendered but it is below the CoordinatorLayout and off-screen.
An easy way to fix this would be setting the weight of the CoordinatorLayout to fill the parent layout but leave space necesseary to display the footer LinearLayout. This would be
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
But this is not ideal way so I would suggest leaving the CoordinatorLayout as the root element and place your LinearLayout just bellow the RecyclerView where it belongs. Since your footer LinearLayout has fixed height this can be done easily
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.design.widget.AppBarLayout>
<android.support.v7.widget.Toolbar />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:paddingBottom="150dp" />
<LinearLayout
android:layout_height="150dp"
android:layout_gravity="bottom">
<EditText />
<ImageButton />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>