I have read on Android Developers that ConstraintLayout can be used to design a responsive layout for an application. There is a parent ConstraintLayout which houses a toolbar and two other ConstraintLayouts. The first child ConstraintLayout is going to act as empty view for my ListView. The second ConstraintLayout holds my listview and a floating action button. Currently, the the listview appears under the Toolbar, rather than below it. Also as seen in the screenshot, the floating action button appears outside visible area.
See the screenshot below:
And this is the app layout when the list is empty:
This is the code for my layout:
<?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"
android:id="#+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<android.support.v7.widget.Toolbar xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<android.support.constraint.ConstraintLayout
app:layout_constraintTop_toBottomOf="#id/toolbar"
android:id="#+id/empty_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize">
<TextView
app:layout_constraintTop_toTopOf="parent"
android:id="#+id/tv_empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/list_is_empty"
android:textSize="#dimen/large_text"
android:textStyle="bold"
/>
<ImageView
android:id="#+id/iv_empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/tv_empty_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:contentDescription="#string/list_is_empty"
android:src="#drawable/emptybox" />
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="#+id/main_area"
android:layout_marginTop="50dp"
android:layout_marginBottom="?actionBarSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/toolbar"
app:layout_constraintBottom_toBottomOf="parent">
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="?attr/actionBarSize"
android:layout_marginLeft="#dimen/margin_side"
android:layout_marginStart="#dimen/margin_side"
android:layout_marginRight="#dimen/margin_side"
android:layout_marginEnd="#dimen/margin_side"
android:layout_marginTop="?attr/actionBarSize"
/>
<android.support.design.widget.FloatingActionButton
android:layout_below="#+id/listview"
android:id="#+id/fab"
android:layout_width="#android:dimen/notification_large_icon_width"
android:layout_height="#android:dimen/notification_large_icon_height"
android:layout_gravity="end|bottom"
android:src="#drawable/plus"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
While using ConstraintLayout you have to add constraints for 'constraintTop',constraintRight,constraintBottom,constraintLeft or constraintStart and constraintEnd. only if you constraint all your four sides the constraint layout (or Constraint Start or End with other References) works well. Otherwise the layout will not work correctly
For Further Reference https://codelabs.developers.google.com/codelabs/constraint-layout/index.html?index=..%2F..%2Findex#0
https://developer.android.com/training/constraint-layout/index.html
There are a couple of things that you can improve with the XML and make the design easier.
First, the main layout will match the screen, to have the preview correctly simulate that, you can set its width/height to match_parent
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
Then, Android Studio should be giving you warnings/errors and saying The view is not constrained horizontally/vertically. In ConstraintLayout, you have to use constraints to specify how your views are placed. If you don't, by default they will position at 0/0 and most probably will look different when it runs on the device:
<ListView
android:id="#+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="0dp" />
Now, you should be able to that the main_area overlaps with the toolbar. To fix it, you can change main_area height to match the constrains:
android:id="#+id/main_area"
android:layout_height="0dp"
You should be able to obtain a design similar to what you intended.
Here is your desired result, I've made some changes like margins, src just to make it work in my studio, so you'll have to choose whatever you were using, just replace mine with your src's and margins etc...
<?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"
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="56dp"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<android.support.constraint.ConstraintLayout
app:layout_constraintTop_toBottomOf="#+id/toolbar"
android:id="#+id/empty_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<TextView
app:layout_constraintTop_toTopOf="parent"
android:id="#+id/tv_empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
android:text="list_is_empty"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<ImageView
android:id="#+id/iv_empty_view"
android:layout_width="20dp"
android:layout_height="20dp"
app:layout_constraintTop_toBottomOf="#+id/tv_empty_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#fff222" />
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="#+id/main_area"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#+id/toolbar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<ListView
android:id="#+id/listview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<android.support.design.widget.FloatingActionButton
android:layout_marginEnd="30dp"
android:layout_marginBottom="30dp"
android:id="#+id/fab"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="#drawable/bg"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
Here's the output:
I was also facing the same issue.
I made a mistake of keeping layout_width of ListView as fixed width. I changed it to match_constraint and it's coming correctly without any cut.
For height I was facing similar issue so I changed it to match_constraint and it worked.
Related
I am using constraint layout with a vertical bias to fill view in recycler view. I successfully did that.
<?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"
android:background="#color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recylerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0" />
</androidx.constraintlayout.widget.ConstraintLayout>
My recyclerview items showing me in reverse order because I want to make chat application. So I added reverseLayout and stackFromEnd true. So it look like this.
If my item is single my ui convert into like this by above xml code
Now I want to add edittext and button in bottom. Its not working vertical bias. Does any one know how to fix. Any suggestion to what can i use
Expected Output
Scenerio 1
Scenerio 2
Actual Output
I tried this code
<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"
android:background="#color/white">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart=10dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toTopOf="#+id/inputContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/inputContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/crecyclerView">
<EditText
android:id="#+id/editTextContainer"
android:layout_width="200dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<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_constraintStart_toEndOf="#+id/editTextContainer"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
UPDATE
After adding #MartinMarconcini answer it fixed my Scenario 2. I want to fix as Scenario 1 as well.
The idea is that your RV will handle its own item size and space by itself. You don't need to worry about this.
The Remainder of the space, will be used by ConstraintLayout.
So you need to pin the RV and the "Bottom Container" together. This would by default cause the CL to try to pull and balance layouts, so you have to tell the bottom container to be biased at the bottom.
In pseudo-XML:
<ConstraintLayout>
<RecyclerView
width=0dp
height=0dp
start/end = parent
TopToTop=parent
BottomToTopOf=BottomContainer
>
<BottomContainer>
width=0dp
height=wrap_content
TopToBottomOf=RecyclerView
BottomToBottomOf=parent
start/end = parent>
</ConstraintLayout>
Now this needs one more thing, because the RV would take all the space, you want to ensure the BottomContainer has more information about where it wants to be placed.
So you add:
app:layout_constraintVertical_bias="1.0"
to the Bottom Container.
This means, vertically, as "bottom" as you can. (0.0 would be the opposite).
The end result is:
<?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"
xmlns:tools="http://schemas.android.com/tools">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recylerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingBottom="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:listitem="#android:layout/simple_list_item_2" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp"
app:layout_constraintVertical_bias="1.0"
android:layout_height="wrap_content"
android:id="#+id/bottomContainer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/recylerview"
app:layout_constraintBottom_toBottomOf="parent">
<EditText
android:id="#+id/editTextContainer"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<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_constraintStart_toEndOf="#+id/editTextContainer"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Which looks like this:
UPDATE
If you add both
app:stackFromEnd="true"
app:reverseLayout="true"
It works the same way, except the item "0" is at the bottom, and the "last" item is at the top. Adding another item would add it at the top but the BottomContainer has no participation (or influence) over this:
I'm dealing with a weird issue and I'm kind of lost about which direction to take:
I have a fragment which is opened from several places in the app(it shows a user profile). Most of the places it's ok but in one, in particular, it has a strange behavior, the first time it's open, most views are blank, but some like the profile picture and the toolbar title are ok, if I go back and enter it again then all the views are visible as expected.
I have tried several approached to solve this, one, in particular, is to call activity.recreate() in the fragment onCreateView() which makes the views visible but has some side effects that I want to avoid and also is just a patch and not dealing directly with the problem.
Now, the most strange part to me is that if I open the screen in the layout inspector I see this:
As you can see the textviews and other elements are set, but just not visible.
One experiment I tried was giving a textview a fixed width and in that case it is visible, could this be some problem with the constraintLayout?
Any other ideas?
Thanks in advance!
EDIT:
One other thing, could the viewstubs have anything to do here?
This is the layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsingToolBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="0dp"
android:fitsSystemWindows="true"
app:expandedTitleGravity="top"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:titleEnabled="false">
<androidx.constraintlayout.widget.ConstraintLayout
style="#style/ProfileContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:elevation="0dp"
android:paddingBottom="#dimen/padding_margin_large_20">
<include
layout="#layout/common_profile_picture"
style="#style/ProfileImage"
android:id="#+id/userPicture"
android:layout_width="#dimen/round_avatar_size"
android:layout_height="#dimen/round_avatar_size"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.constraintlayout.widget.Group
android:id="#+id/follow_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:constraint_referenced_ids="user_followers_label_textview,user_followers_number_textview,follow_divider,user_following_label_textview,user_following_number_textview,sectionFollowers,sectionFollowing" />
<TextView
style="#style/ProfileFollowerTextLabel"
android:id="#+id/user_followers_label_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toStartOf="#+id/user_following_label_textview"/>
<TextView
style="#style/ProfileFollowerText"
android:id="#+id/user_followers_number_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/user_followers_label_textview"
app:layout_constraintStart_toStartOf="#+id/user_followers_label_textview"
app:layout_constraintEnd_toEndOf="#+id/user_followers_label_textview"/>
<View
android:id="#+id/sectionFollowers"
android:layout_width="0dp"
android:layout_height="#dimen/profile_vertical_divider_height"
android:layout_marginTop="#dimen/padding_margin_large_28"
android:background="?selectableItemBackground"
android:visibility="gone"
app:layout_constraintTop_toTopOf="#+id/user_followers_label_textview"
app:layout_constraintStart_toStartOf="#+id/user_followers_label_textview"
app:layout_constraintEnd_toStartOf="#id/user_following_label_textview"
app:layout_constraintBottom_toBottomOf="#+id/user_followers_number_textview"/>
<include layout="#layout/common_divider"
android:id="#+id/follow_divider"
android:layout_width="1dp"
android:layout_height="#dimen/profile_vertical_divider_height"
android:layout_marginTop="#dimen/padding_margin_large_28"
app:layout_constraintTop_toTopOf="#+id/user_followers_label_textview"
app:layout_constraintBottom_toBottomOf="#+id/user_followers_number_textview"
app:layout_constraintStart_toEndOf="#+id/user_followers_label_textview"
app:layout_constraintEnd_toStartOf="#+id/user_following_label_textview"
app:layout_constraintHorizontal_bias="1.0"/>
<TextView
style="#style/ProfileFollowingTextLabel"
android:id="#+id/user_following_label_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="#+id/user_followers_label_textview"
app:layout_constraintBottom_toBottomOf="#+id/user_followers_label_textview"
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
style="#style/ProfileFollowingText"
android:id="#+id/user_following_number_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/user_following_label_textview"
app:layout_constraintStart_toStartOf="#+id/user_following_label_textview"
app:layout_constraintEnd_toEndOf="#+id/user_following_label_textview"/>
<View
android:id="#+id/sectionFollowing"
android:layout_width="0dp"
android:layout_height="#dimen/profile_vertical_divider_height"
android:layout_marginTop="#dimen/padding_margin_large_28"
android:background="?selectableItemBackground"
android:visibility="gone"
app:layout_constraintTop_toTopOf="#+id/user_followers_label_textview"
app:layout_constraintStart_toStartOf="#+id/user_following_label_textview"
app:layout_constraintEnd_toEndOf="#id/user_following_label_textview"
app:layout_constraintBottom_toBottomOf="#+id/user_following_number_textview"/>
<ViewStub
style="#style/ProfileAction"
android:id="#+id/profileaction_viewstub"
android:inflatedId="#+id/profileaction_viewstub"
android:layout_width="#dimen/profile_action_width"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/user_following_number_textview"
app:layout_constraintStart_toStartOf="#+id/user_followers_label_textview"/>
<TextView
style="#style/ProfileName"
android:id="#+id/user_fullname_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:text="#string/placeholder"
android:drawablePadding="#dimen/padding_margin_small_4"
app:layout_constraintTop_toBottomOf="#+id/userPicture"
app:layout_constraintBottom_toTopOf="#+id/donation_list_label_textview"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"/>
<TextView
android:id="#+id/userTitleTextView"
style="#style/ProfileTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintStart_toStartOf="#+id/user_fullname_textview"
app:layout_constraintTop_toBottomOf="#+id/user_fullname_textview" />
<androidx.emoji.widget.EmojiAppCompatTextView
style="#style/ProfileDesc"
android:id="#+id/user_description_textview"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:text="#string/placeholderLong"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/userTitleTextView"/>
<TextView
android:id="#+id/userWebSiteTextView"
style="#style/ProfileWebSite"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:autoLink="web"
android:visibility="invisible"
app:layout_constraintStart_toStartOf="#+id/user_fullname_textview"
app:layout_constraintTop_toBottomOf="#+id/user_description_textview" />
<androidx.constraintlayout.widget.Group
android:id="#+id/donating_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="donation_list_label_textview,donating_arrow_imageview,donationList,donationDivider" />
<include
android:id="#+id/donationDivider"
layout="#layout/common_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="#dimen/padding_margin_medium_16"
android:layout_marginTop="#dimen/padding_margin_medium_16"
android:layout_marginEnd="#dimen/padding_margin_medium_16"
android:layout_marginBottom="#dimen/padding_margin_medium_16"
app:layout_constraintBottom_toTopOf="#+id/donation_list_label_textview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/userWebSiteTextView" />
<TextView
android:id="#+id/donation_list_label_textview"
style="#style/ProfileDonatingLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/profile_donating"
app:layout_constraintStart_toStartOf="#+id/user_fullname_textview"
app:layout_constraintTop_toBottomOf="#+id/donationDivider" />
<ImageView
android:id="#+id/donating_arrow_imageview"
android:layout_width="#dimen/profile_arrow_size"
android:layout_height="#dimen/profile_arrow_size"
app:srcCompat="#drawable/ic_chevron_accent_right"
android:tint="?iconColorSelected"
app:layout_constraintBottom_toBottomOf="#+id/donation_list_label_textview"
app:layout_constraintStart_toEndOf="#+id/donation_list_label_textview"
app:layout_constraintTop_toTopOf="#+id/donation_list_label_textview"
app:layout_constraintVertical_bias="0.75" />
<TextView
android:id="#+id/donationList"
style="#style/TextValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start"
android:paddingTop="#dimen/padding_margin_small_4"
android:paddingBottom="#dimen/padding_margin_large_30"
app:layout_constraintStart_toStartOf="#+id/user_fullname_textview"
app:layout_constraintTop_toBottomOf="#+id/donation_list_label_textview" />
</androidx.constraintlayout.widget.ConstraintLayout>
<include layout="#layout/common_divider"
android:id="#+id/postsDivider"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_gravity="bottom"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:layout_marginStart="#dimen/padding_margin_medium_16"
android:layout_marginEnd="#dimen/padding_margin_medium_16"
android:layout_marginBottom="#dimen/padding_margin_medium_18"/>
<include layout="#layout/common_toolbar_back"
android:id="#+id/profileToolbar"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="#+id/tabContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<TextView
android:id="#+id/private_profile_textview"
style="#style/TextValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="#dimen/profile_private_label_bottom_margin"
android:text="#string/profile_private"
android:visibility="gone" />
<androidx.core.widget.ContentLoadingProgressBar
android:id="#+id/postsLoadingProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:theme="?android:attr/progressBarStyleLarge"
android:visibility="gone" />
<include layout="#layout/loader"
android:id="#+id/profileLoader"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
The first thing you want to do is check color of the font that you are using. the second is the theme that you are using after that in your fragment xmls root tag put color="white" and clickable is true.
This problem is occurred mostly due to the delay and high processing , like your are loading something heavy on your views or overlapping some containers and these are being skipped.
Easy one is just put a background color to this fragment's root container.
Try to remove overlapping of layouts/views because GPU overrides are increasing and rendering becomes slow.
I think the problem must be in layout file. As you said when you open layout file the textviews and other elements are set, but just not visible.
That's what troubling the fragment while inflating the views when you open it first time.
Try:
1.Check your style.xml and layout file again
2.Debug by replacing the code in layout with simple views
This is my qff_layout.xml file
<merge
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textview.MaterialTextView
android:id="#+id/questions_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/questions"
android:textSize="#dimen/text_normal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintEnd_toStartOf="#+id/followers_label"
app:layout_constraintTop_toTopOf="parent"/>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/followers_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/followers"
android:textSize="#dimen/text_normal"
app:layout_constraintStart_toEndOf="#+id/questions_label"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintEnd_toStartOf="#+id/following_label"
app:layout_constraintTop_toTopOf="parent"/>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/following_label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/following"
android:textSize="#dimen/text_normal"
app:layout_constraintStart_toEndOf="#+id/followers_label"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/questions_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="#dimen/text_normal"
android:textStyle="bold"
tools:text="0"
app:layout_constraintStart_toStartOf="#+id/questions_label"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="#+id/questions_label"
android:layout_marginRight="8dp"
app:layout_constraintTop_toBottomOf="#+id/questions_label"/>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/followers_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="#dimen/text_normal"
android:textStyle="bold"
tools:text="0"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintStart_toEndOf="#+id/questions_label"
app:layout_constraintEnd_toStartOf="#+id/following_label"
app:layout_constraintTop_toBottomOf="#+id/followers_label"/>
<com.google.android.material.textview.MaterialTextView
android:id="#+id/following_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="#dimen/text_normal"
android:textStyle="bold"
tools:text="0"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintStart_toStartOf="#+id/following_label"
app:layout_constraintEnd_toEndOf="#+id/following_label"
app:layout_constraintTop_toBottomOf="#+id/following_label"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</merge>
This displays 6 textviews in two rows, something you would see in instagram app in profile section with Posts-Followers-Following and bellow numbers under each of those.
Now the problem is when I include that in my main layout which is ConstraintLayout:
profile_fragment.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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="?attr/actionBarTheme"
android:minHeight="?attr/actionBarSize"
android:elevation="4dp"
android:id="#+id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profile_image"
android:layout_width="80dp"
android:layout_height="80dp"
app:srcCompat="#drawable/ic_profile_24dp"
tools:src="#drawable/ic_profile_24dp"
app:civ_border_color="#color/secondaryDarkColor"
app:civ_border_width="1dp"
android:layout_marginTop="#dimen/spacing_normal"
android:layout_marginStart="#dimen/spacing_normal"
android:layout_marginLeft="#dimen/spacing_normal"
app:layout_constraintTop_toBottomOf="#+id/title"
app:layout_constraintStart_toStartOf="parent"/>
<com.google.android.material.textview.MaterialTextView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/description"
android:layout_marginEnd="#dimen/spacing_normal"
android:layout_marginRight="#dimen/spacing_normal"
android:layout_marginLeft="#dimen/spacing_normal"
android:layout_marginStart="#dimen/spacing_normal"
app:layout_constraintStart_toEndOf="#+id/profile_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="#+id/profile_image"
app:layout_constraintTop_toTopOf="#+id/profile_image"/>
<include
layout="#layout/qff_layout"
android:id="#+id/qff_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/spacing_small"
app:layout_constraintTop_toBottomOf="#+id/profile_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<com.google.android.material.tabs.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/primaryLightColor"
app:tabMode="fixed"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/qff_layout"/>
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/sliding_tabs" />
</androidx.constraintlayout.widget.ConstraintLayout>
Nothing gets displayed.
I tried changing my main layout to linear and it's the same.
But when I remove merge tag from qff_layout.xml and use the same include tag in main layout it works well and displays the qff_layout, How??Why??
What is the use of merge tag then, please do not quote something from the stupidest documentation ever because it makes no sense.
You should use merge when you dont want to repeat same ViewGroup. In this case, it could save you from not using two nested ConstraintLayouts - you could remove ConstraintLayout from qff_layout.xml and use merge as your root element like:
<merge
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- your text view -->
</merge>
If your ConstraintLayout in qff_layout.xml has some other purpose, you just leave it, and include qff_layout.xml without merge as root element.
In other words merge purpose is to replace root ViewGroup.
Read more here.
UPDATE:
You can fix your XML this way without removing marge.
Positioning constraints you defined on element, should be also applied on your ConstraintLayout inside qff_layout.xml like:
<merge
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/qff_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/spacing_small"
app:layout_constraintTop_toBottomOf="#+id/profile_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<!-- your text view -->
</androidx.constraintlayout.widget.ConstraintLayout>
</merge>
Why you need to apply this: When you put layout inside element it will basically get pasted in the line you include it. When you don't define constraints for some layout inside ConstraintLyout, it jumps to the top left corner of the screen and thats what happend to layout you included. It didnt have defined constraints inside qff_layout.xml that will apply when it gets included, so it jumped to the top left corner.
My App is supposed to have the following layout (ie these 3 things stacked vertically):
Chart Name (String)
Tools (a pager with 3 tabs)
ChartGrid
The Chart Name is a set size, and then I want the Tools below that to use as much space as they need to, and then the ChartGrid should take up the rest of the space below that.
The overall layout is as follows (I've taken out the irrelevant bits):
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textViewChartName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<fragment
android:id="#+id/fragment_tools"
android:name="com.path.appname.fragments.ToolsFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#+id/textViewChartName"
tools:layout="#layout/fragment_tools" />
<fragment
android:id="#+id/fragment_chartGrid"
android:name="com.path.appname.fragments.ChartGridFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/au_adView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/fragment_tools"
app:layout_constraintVertical_chainStyle="spread"
app:layout_constraintVertical_weight="5"
tools:layout="#layout/fragment_chart_grid" />
<com.google.android.gms.ads.AdView
android:id="#+id/au_adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_gravity="bottom"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
fragment_tools.xml is as follows:
<android.support.constraint.ConstraintLayout
android:id="#+id/chart_tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/toolsWrapper"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tabs" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
and fragment_chartGrid is:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<com.path.appname.models.ChartGrid
android:id="#+id/chartGrid"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
The problem I'm having is that the tools are taking up all the screen space, so I see the Chart Name and then the tools, and then nothing below that - just white space (if I add a background colour to the tools then I see the background colour). If I take out the tools, I can see the grid again.
Where am I going wrong?
EDIT: here's what I want (I've coloured the tools orange just to show which bit I mean; obviously I also need to sort out the numbers on the chart!):
And here's what I'm getting:
The content of the main activity looks like:
the main screen looks like (all this inside ConstraintLayout):
image title
date
the image itself
image description
The image description may be too long to be displayed, to fix this I can put it inside a ScrollView, and this works just fine. However, I would like to ScrollView the whole ConstraintLayout, and this is not functioning properly: cannot scroll and some TextViews do not appear!
Relevant Code:
<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:id="#+id/desciptionScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.picture.nasa.nasadailyimage.NasaDailyImage"
tools:showIn="#layout/activity_nasa_daily_image">
<TextView
android:id="#+id/imageTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:text="#string/test_image_title"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/imageDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:text="#string/test_image_date"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageTitle" />
<ImageView
android:id="#+id/imageDisplay"
android:layout_width="368dp"
android:layout_height="408dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="3dp"
android:src="#mipmap/test_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageDate" />
<TextView
android:id="#+id/imageDescription"
android:layout_width="368dp"
android:layout_height="0dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:text="#string/test_image_description"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageDisplay" />
</android.support.constraint.ConstraintLayout>
For making the elements in the screen scrollable I think you could use a NestedScrollView inside a CoordinatorLayout.
I usually put a LinearLayout with all the elements I would display there.
For example:
<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="com.xengar.android.puzzlewildanimals.ui.HelpActivity">
<android.support.design.widget.AppBarLayout
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/ThemeOverlay.AppCompat.Dark" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<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:id="#+id/desciptionScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.picture.nasa.nasadailyimage.NasaDailyImage"
tools:showIn="#layout/activity_nasa_daily_image">
<TextView
android:id="#+id/imageTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:text="#string/test_image_title"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/imageDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:text="#string/test_image_date"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageTitle" />
<ImageView
android:id="#+id/imageDisplay"
android:layout_width="368dp"
android:layout_height="408dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="3dp"
android:src="#mipmap/test_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageDate" />
<TextView
android:id="#+id/imageDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:text="#string/test_image_description"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/imageDisplay" />
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
If that doesn't work you can replace the ConstraintLayout with a LinearLayout.
I hope that helps.
To add scrolling to any view, you add a ScrollView. In your code, add it as the root(If the ScrolLView isn't the root and there is more content, add the ScrollView around the ConstraintLayout). move the namespaces(lines containing xmlns) to the new root. Add width and height in the ScrollView to match_parent(or whatever you have) and set the height of the ConstraintLayout to wrap_content.
However, you will not be able to scroll correctly in design mode. (reference). But it will still work as ecpected on a device.
NOTE:
If your layout doesn't scroll with a SCrollView, make sure you set the height of the ConstraintLayout to wrap_content
No need to use a NestedScrollView as long as you can get the constraint layout to "extend" beyond its ScrollView parent as described in this related SO answer
surrounded my constrinat-layout with a ScrollView tag and gave it the property android:isScrollContainer="true".