Im trying to display a DialogFragment which after showing up on the screen should display a start destination from the nav_graph specified in the NavHostFragment. Here's DialogFragment layout:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<!-- <androidx.constraintlayout.widget.ConstraintLayout -->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="800dp">-->
<androidx.coordinatorlayout.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">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:visibility="visible">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="8dp"
android:orientation="vertical">
<fragment
android:id="#+id/nav_host_home_bottom_sheet"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/dismiss_registration_button"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/membership_navigation" />
<com.google.android.material.button.MaterialButton
android:id="#+id/dismiss_registration_button"
style="#style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/open_sans_regular"
android:text="#string/all_dismiss"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- </androidx.constraintlayout.widget.ConstraintLayout>-->
What happens is only Dismiss button displays in the DialogFragment. When I uncomment ConstraintLayout with layout_height fixed to 800dp then startDestination from NavHostFragment loads ok. The problem is that I don't want to hadrcode the layout_height - how can I display it with either CoordinatorLayou or ConstraintLayout without hardcoding the layout_height?
To make it work I simply changed DialogFragment layout to
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.coordinatorlayout.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">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/membership_navigation" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
and then handle scroll view and others in fragments where it's needed.
Related
Im using viewbinding, and i get this error when i build
Configurations for activity_main.xml must agree on the root element's ID.
Missing ID:
- layout
#+id/drawer_layout:
- layout-land
It says i need to have two different id for rootview. But i have different root for portrait layout and landscape layout. Like below. If i put same id to drawerlayout(landscape) and same id for constraintlayout(portrait) it creates problem in code. That to i wrote common code without checking orientation.
How to get rid of this error, using <include id> or <merge> or anyother ways?
(i dont know how these works exactly for my needs) without checking orientations in code blocks.
activity_main.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/purple_500"
android:theme="#style/Widget.AppCompat.Toolbar"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<fragment
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/mobile_navigation"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/bottom_nav"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/toolbar" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/nav_host_fragment"
app:layout_constraintVertical_bias="1.0"
app:menu="#menu/menu_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
land/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorPrimary"
android:theme="#style/ToolbarTheme" />
<fragment
android:id="#+id/nav_host_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/mobile_navigation"
app:defaultNavHost="true" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/menu_navigation" />
</androidx.drawerlayout.widget.DrawerLayout>
code
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
You're using a </androidx.constraintlayout.widget.ConstraintLayout> for the portrait and a </androidx.drawerlayout.widget.DrawerLayout> for the landscape orientation. Hence the error.. You can try running the app after wrapping the drawer layout in a constraint layout and giving each an identical id
As one can see in image, RecyclerView items are visible through Standard/Persistent BottomSheet and collapsing/expanding of BottomSheet is also not happening in Standard/Persistent BottomSheet. RecyclerView items are scrollable but when I do any kind of activity in Standard/Persistent BottomSheet, it directly scrolling the RecyclerView item behind this Standard/Persistent BottomSheet.
Note: Background color used in BottomSheet is solid. It's not transparent.
I'm wondering how to solve this issue?
Here's the code snippet ->
activity_main.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:id="#+id/layout_container_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="app.standardbottomsheet.ui.MainActivity">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/layout_container_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:context="app.standardbottomsheet.ui.MainActivity">
<include
android:id="#+id/included_layout_standard_bottom_sheet"
layout="#layout/layout_standard_bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
layout_standard_bottom_sheet.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"
android:id="#+id/layout_container_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/bottom_sheet_behavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/thumbnail"
android:layout_width="?actionBarSize"
android:layout_height="?actionBarSize"
android:src="#mipmap/ic_launcher"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#id/thumbnail"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.slider.Slider
android:id="#+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/summary" />
</androidx.constraintlayout.widget.ConstraintLayout>
As you can see in the image your bottom sheet is behind the recycler view. To change that you have to change the order of recyclerview and coordinatelayour in your activity_main.xml
You can try by changing the order like this
<?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:id="#+id/layout_container_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="app.standardbottomsheet.ui.MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/layout_container_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:context="app.standardbottomsheet.ui.MainActivity">
<include
android:id="#+id/included_layout_standard_bottom_sheet"
layout="#layout/layout_standard_bottom_sheet" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Since both recycler view and CoordinatorLayout are match_parent, There order decide which is above to another.
I have created Bottom Navigation Activity in Android Studio. Now I'm adapting all layouts to my needs but I have a severe problem with removing that margin between nav_host_fragment and it's parent which is Constraint Layout. This causes the layout of all fragments to be displayed with an unwanted offset or a margin.
https://obrazki.elektroda.pl/6421823700_1611991870.png
The layout is defined as follows
<?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"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu" />
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
The android:paddingTop in your constraint layout is the cause of your issue, remove it and you must be good to go.
Try the following,
<?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"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- child view remains the same -->
</androidx.constraintlayout.widget.ConstraintLayout>
I tried to add Swipe-to-Refresh inside a fragment that contains a RecyclerView but after adding it the fragment becomes white.
Tried with a simple textview and in fragment .setRefreshing(true) and still the fragment is white.
If I move the Swipe to refresh layout to the activity everything works like a piece of charm.
My questions is what am I doing wrong or why I can't have the Swipe to refresh inside the fragment?
My fragment XML:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</layout>
Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainActivity">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="100dp">
<FrameLayout
android:id="#+id/screenContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.core.widget.NestedScrollView>
<!-- TODO REFACTOR COLORS -->
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="#000000"
app:fabCradleMargin="10dp"
app:hideOnScroll="true"
app:menu="#menu/bottom_app_bar"
app:navigationIcon="#drawable/ic_menu_24dp" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#e0f2f1"
app:layout_anchor="#id/bottomAppBar"
app:shapeAppearance="#style/FabDiamondOverlay"
app:srcCompat="#drawable/ic_add_24dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
Gradle:
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
Emulator:
Uploaded a sample project on github.
https://github.com/tirlaovidiu/swipe-to-refresh-bug-example
Solved::
NestedScrollView replaced with a ConstraitLayout and the issue went away.
I faced with the following problem: I need to make a fragment, which height would be the same as height of the screen except bottom navigation view. Here's 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainActivity">
<FrameLayout
android:id="#+id/tabs_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#111111"
app:layout_constraintBottom_toTopOf="#id/bottom_nav" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="#dimen/bottom_nav_height"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/bottom_nav_menu" />
</android.support.constraint.ConstraintLayout>
I added android:background="#111111" to see, what is the real height of fragment. Probably I thought that app:layout_constraintBottom_toTopOf="#id/bottom_nav" can help me, but unfortunately it didn't solve my problem. So, how can I deal with it?
You need to set the layout_height of the FrameLayout to 0dp if you want the height to fit your constraints.
<?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=".ui.main.MainActivity">
<FrameLayout
android:id="#+id/tabs_fragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#111111"
app:layout_constraintBottom_toTopOf="#id/bottom_nav"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="0dp"
android:layout_height="#dimen/bottom_nav_height"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/bottom_nav_menu" />
</android.support.constraint.ConstraintLayout>