I want remove scroll mode from Navigation Drawer Android - android

i want remove this space from navigation drawer
I want remove scroll mode from Navigation Drawer or any solution for create custom navigation drawer without menu
Here is my layout code.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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"
android:overScrollMode="never"
tools:openDrawer="end">
<include
layout="#layout/app_bar_live"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
app:headerLayout="#layout/nav_header_live"
android:overScrollMode="never" />
</android.support.v4.widget.DrawerLayout>

Creating a truly custom NavDrawer is possible, with little tweaking to the components.
Here are the steps:
1 - No menu layout, just headerView
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view_end"
android:layout_width="match_parent"
android:layout_marginLeft="-64dp"
android:layout_marginStart="-64dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="true"
app:headerLayout="#layout/shop_list"
/>
Notice that i placed margin start and left to -64dp. That's to get the drawer layout to be full width.
2 - Disable NavigationMenuView's scroll
Even though we didn't put a menu layout, it's still created and we need to access it and disable the scroll. Because this view is instance of the RecyclerView, we just need to override it's layout manager and disable the vertical scroll.
private fun disableMenuScroll(navView: NavigationView) {
val navMenu = navView.getChildAt(0) as NavigationMenuView
navMenu.layoutManager = object : LinearLayoutManager(this) {
override fun canScrollVertically(): Boolean {
return false
}
}
}
3 - Set the header layout to be full height
Here we use reflection to get the presenter from HeaderView and from that presenter we get the LinearLayout that holds our headerLayout. That LinearLayout is the one that doesn't let our layout stretch to match parent. We just change the LayoutParams for that LinearLayout and it's done.
private fun changeDrawerLayoutHeight(navView: NavigationView) {
/*With reflection get the navView's presenter*/
val field = navView.javaClass.getDeclaredField("presenter")
field.isAccessible = true
val presenter = field.get(navView) as NavigationMenuPresenter
/*From presenter, get the header layout field*/
val layoutField = presenter.javaClass.getDeclaredField("headerLayout")
layoutField.isAccessible = true
val headerLayout = layoutField.get(presenter) as LinearLayout
/*Set layout params on the HeaderLayout to match parent*/
val params = headerLayout.layoutParams
params.height = LinearLayout.LayoutParams.MATCH_PARENT
headerLayout.layoutParams = params
}
Where does this code execute?
In your Activity's onCreate method. Here is the code needed to execute this:
val navView = findViewById<NavigationView>(R.id.nav_view_end)
disableMenuScroll(navView)
changeDrawerLayoutHeight(navView)
Hope this helps somebody!

Try to add this to root tag (android.support.v4.widget.DrawerLayout)...hope it helps.
android:fitsSystemWindows="true"
and try removing that android:overScrollMode from both root tag and navigationview

Related

RecyclerView in BottomSheet not working as expected

I have a problem with RecyclerView directly inside of layout with bottomsheetbehaviour. The problem is that when bottom sheet is expanded and content is scrolled down, when I go to scroll back up it causes Bottom Sheet to start collapsing, instead of RecyclerView first being scrolled back to top.
Here's a video to demonstrate the problem. As you can see the problem appears when I scroll down on expanded bottom sheet. It immediately start to collapse instead of "waiting" for RecyclerView to scroll to top first.
Here is my layout code
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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:id="#+id/scheduleRoot"
android:layout_height="match_parent"
tools:context=".schedule.ScheduleFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scheduleSheet"
app:behavior_peekHeight="300dp"
android:elevation="16dp"
android:clickable="false"
android:focusable="false"
android:background="#drawable/bg_bottom_sheet"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scheduleRecyclerView"
android:clickable="true"
android:focusable="true"
android:layout_marginTop="8dp"/>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Any help is appreciated!
I just encountered same problem, but I fixed it by adding this to onCreate:
androidx.core.view.ViewCompat.setNestedScrollingEnabled(recyclerview, false);
Add
android:nestedScrollingEnabled="true"
in the root layout of BottomSheetDialogFragment.
I had similar issue: Maybe the solution to my problem will give you some ideas. My bottom sheet was expanded to full height with recycler view in it; the bottom sheet was collapsing on user-drag, even though the first item in recycler view wasn't visible yet.
So, what I did:
You can enable/disable bottom sheet dragging by "isDraggable" = true/false
Add OnScrollListener for recycler view.
Override onScrolled and check layoutManager.findFirstVisibleItemPosition() in it
If first item is visible - update bottom sheet behavior.isDraggable = true, i also added small delay before setting behavior.isDraggable = true, because bottom sheet was collapsing too fast, but you might not need it
Maybe it's not optimal but it was fitting my needs and maybe will help you.
Your recyclerview item has overighted the scrolling state, so this error generates. The layout you provided does not have enough data to determine the cause. You change the item is a unique view to check
I played with this for a long time and tried way too many solutions. For me, this worked best:
val layoutManager = LinearLayoutManager(requireContext())
binding.recyclerView.layoutManager = layoutManager
binding.recyclerView.setOnScrollChangeListener { _, _, _, _, _ ->
if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
bottomSheetBehavior.isDraggable = layoutManager.findFirstCompletelyVisibleItemPosition() == 0
} else {
bottomSheetBehavior.isDraggable = true
}
}
The key to the solution is is controlling users ability drag the bottom sheet while the recyclerview is partially scrolled. The method only allows scrolling again once the top most cell is fully visible.
Its not ideal as the user may want to grab the very top of the bottom sheet (assuming its not part of the recycler view) and dismiss the bottom sheet regardless of its scroll position. Im just accepting.
Whatever you do, do not try these, as they just disable any recycling functionality and all cells are loaded at instantiation having a really bad impact on performance:
wrap_content
or:
binding.recyclerView.isNestedScrollingEnabled = false
Enable the scroll state of BottomSheet to allow scroll if recyclerview 0th item is visible.
activity_main.xml
<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">
<data />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#A8A7A7"
tools:context=".MainActivity">
<LinearLayout
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="80dp"
app:layout_behavior="com.asadmukhtar.recyclerviewinsidebottomsheet.LockableBottomSheetBehavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="Drag Me"
android:textColor="#000"
android:textSize="20sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_items"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
LockableBottomSheet file that used for handling allow dragging option or not.
class LockableBottomSheetBehavior<V : View?> : BottomSheetBehavior<V> {
private var mAllowUserDragging = true
constructor()
constructor(context: Context, attrs: AttributeSet?) : super(
context,
attrs
)
fun setAllowUserDragging(allowUserDragging: Boolean) {
mAllowUserDragging = allowUserDragging
}
override fun onInterceptTouchEvent(
parent: CoordinatorLayout,
child: V,
event: MotionEvent
): Boolean {
return if (!mAllowUserDragging) {
false
} else super.onInterceptTouchEvent(parent, child, event)
}
}
MainActivity.java
var bottomSheetBehavior: LockableBottomSheetBehavior<*>? = null
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding =
DataBindingUtil.setContentView(this, R.layout.activity_main)
setUpBottomSheetBehaviour()
binding.rvItems.layoutManager = LinearLayoutManager(this)
binding.rvItems.adapter = RecyclerViewAdapter(this)
binding.rvItems.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
val firstPosition = (binding.rvItems.layoutManager as LinearLayoutManager)
.findFirstVisibleItemPosition()
updateBottomSheetLockState(firstPosition == 0)
}
})
}
fun updateBottomSheetLockState(allow: Boolean) {
bottomSheetBehavior?.setAllowUserDragging(allow)
}
fun updateBottomSheetState(state: Int) {
if (bottomSheetBehavior != null) {
bottomSheetBehavior?.state = state
}
}
private fun setUpBottomSheetBehaviour() {
val bottomSheetBehavior: BottomSheetBehavior<LinearLayout> =
BottomSheetBehavior.from(binding.parent)
this.bottomSheetBehavior = bottomSheetBehavior as LockableBottomSheetBehavior<*>
updateBottomSheetState(BottomSheetBehavior.STATE_COLLAPSED)
}
Your implementation might need more coding and with the provided code we might not able to give you good feedback.
Try this documentation
https://material.io/develop/android/components/bottom-sheet-behavior/
Plus I found this another implementation.
https://www.youtube.com/watch?v=WeaylHAwIIk

Android place view (TreeView) on top of MainLayout

So I have this MainLayout which simply consists of a Floating Action Button (FAB) right now:
<RelativeLayout 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/lel"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.FloatingActionButton
android:id="#+id/floatingActionButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:clickable="true"
android:src="#drawable/ic_add_black_24dp" />
</RelativeLayout>
I am using this library to create a treeView similar to this
I create the AndroidTreeView object in the MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
// ...
val treeView = AndroidTreeView(this, root) // 'this' is the context
// ...
setContentView(treeView.view)
}
This will obviously only display the content of the treeView and not the mainLayout.
How can I show the TreeView and the Button at the same time / render the TreeView on top of the MainLayout?
I tried to add the FAB to the view using addView:
val view = treeView.view as ViewGroup
view.addView(floatingActionButton2)
But this results in a java.lang.IllegalStateException: ScrollView can host only one direct child
In an example project the author of TreeView used Fragments for this. But is this really necessary in this case?
I solved this problem by inflating the MainLayout on top of the rootLayout. I tried a similar solution to this before but I probably used "R.id.content" instead of "android.R.id.content".
This code belongs to the bottom of the onCreate method of the MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
// ...
setContentView(treeView.view)
val rootLayout = findViewById<FrameLayout>(android.R.id.content)
View.inflate(this, R.layout.main_layout, rootLayout)
}

Abstract Nav Drawer Android

I'm trying to abstract my Navigation Drawer to streamline my Android app but I'm running into some issues. The Nav Drawer simply doesn't respond to touches, I can't figure out why.
MainActivity.kt
class MainActivity : NavActivity() {
/** ON CREATE **/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
main_seekbar_price!!.setOnSeekBarChangeListener(this)
mDrawerLayout = findViewById(R.id.drawer_layout) // Variable in superclass
...
NavDrawer.kt
abstract class NavActivity : BaseActivity() {
/** Variables **/
lateinit var mDrawerLayout: DrawerLayout
/** ON CREATE **/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_nav)
// Set Nav Drawer listener
nav_view.setNavigationItemSelectedListener { menuItem ->
Log.d("NAV", "nav selected listener header")
menuItem.isChecked = true
mDrawerLayout.closeDrawers()
navMenuSwitch(menuItem)
true
}
// Set Nav Footer listener
nav_footer.setNavigationItemSelectedListener { menuItem ->
Log.d("NAV", "nav selected listener footer")
menuItem.isChecked = false
mDrawerLayout.closeDrawers()
navMenuSwitch(menuItem)
true
}
}
...
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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"
android:background="#color/colorBackground"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
...
</FrameLayout>
<include layout="#layout/activity_nav" />
</android.support.v4.widget.DrawerLayout>
activity_nav.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.NavigationView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_header"
app:headerLayout="#layout/nav_header">
<android.support.design.widget.NavigationView
android:id="#+id/nav_footer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:menu="#menu/drawer_footer">
</android.support.design.widget.NavigationView>
</android.support.design.widget.NavigationView>
I thought it has something to do with assigning mDrawerLayout in the child class but that didn't fix anything. It never calls the listeners though, no matter how much you click it it won't even print Logs in that listener.
Any help is welcome as I can't figure this out for the life of me, thank you in advance!
Four things happen, in this order, when your MainActivity's onCreate() is called:
MainActivity's content view is set by inflating activity_nav.xml.
The nav_view and nav_footer Kotlin variables are assigned by searching the content view for them. (Kotlin does this for you, so it's easy to forget that it's happening.)
Listeners are attached to the nav_view and nav_footer views.
MainActivity's content view is set again, this time by inflating activity_main.xml. (The include tag inside activity_main.xml tells the framework that it should inflate another copy of activity_nav.xml as part of the process.) The old content view is overwritten.
So by the time MainActivity.onCreate() finishes, the views with listeners attached are gone. One way to fix the problem would be to delete the line setContentView(R.layout.activity_nav) from NavActivity.onCreate() and to move the rest into an initNavDrawerListeners() method that's called from MainActivity.onCreate().

ViewPager's height in Coordinator layout is more than available

I have a CoordinatorLayout with a Toolbar and a TabLayout inside the AppBarLayout. Additionally, I have a ViewPager inside the CoordinatorLayout but outside the ViewPager.
The problem is that the ViewPager's height is bigger than what is actually available, resulting in some views from my Fragment being cut.
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/lightGray"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_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/toolbar2"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:layout_scrollFlags="scroll|enterAlways"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:scrollbars="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="false"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
And this what I mean when I say that the ViewPager has the wrong height.
UDPATE: I do not recommend this anymore. I found that it was causing an infinite loop of calls to onDependentViewChanged.
Based on Yevhenii's answer above, I think I managed to solve this in an even simpler way:
class KeepWithinParentBoundsScrollingBehavior : AppBarLayout.ScrollingViewBehavior {
constructor() : super()
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
if (dependency !is AppBarLayout) {
return super.onDependentViewChanged(parent, child, dependency)
}
val layoutParams = child.layoutParams as CoordinatorLayout.LayoutParams
layoutParams.height = parent.height - dependency.bottom
child.layoutParams = layoutParams
return super.onDependentViewChanged(parent, child, dependency)
}
}
Then set app:layout_behavior="your.package.KeepWithinParentBoundsScrollingBehavior" on your ViewPager or whatever view you have below the AppBar.
Take note that this is not a generic solution for all CoordinatorLayouts, but it seems to work when you have a view below an app bar that you don't want to let extend beyond the bottom of the parent CoordinatorLayout.
UPDATE:
You should also set app:layout_anchor="#id/app_bar" on your ViewPager for the situation when the keyboard disappears. If you don't the ViewPager layout will not be refreshed when the keyboard disappears and the ViewPager will appear cut off.
I've spent a lot of time googling and applying suggested answers, but I've not succeeded, so decided to dive deeper into the problem and find out a complete answer, which I want to share here. Maybe it will help somebody.
So the problem is that when ViewPager is used with Collapsing Toolbar, the first one doesn't calculate its height properly. And if you want the ViewPager fill all the space to the bottom of the screen, but not more - there is a problem. Just adding layout_marginBottom will not solve the problem because of Collapsing Toolbar will change its height when user scroll.
So if you want your ViewPager to adapt its height accordingly to Collapsing Toolbar height changes, you need 2 things:
Custom scrolling behavior.
GlobalLayoutListener, which will fix ViewPager height when it's drawn for first time.
Here they are (written in Kotlin, but it's just a separate file and can be placed into Java project directly):
import android.app.Activity
import android.content.Context
import android.graphics.Point
import android.support.design.widget.AppBarLayout
import android.support.design.widget.CoordinatorLayout
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
/**
* Custom extension of AppBarLayout.ScrollingViewBehavior to deal with ViewPager height
* in a bunch with Collapsing Toolbar Layout. Works dynamically when AppBar Layout height is changing.
*/
class ViewPagerScrollingBehavior(context: Context, attributeSet: AttributeSet? = null) :
AppBarLayout.ScrollingViewBehavior(context, attributeSet) {
override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
val layoutParams = child.layoutParams as CoordinatorLayout.LayoutParams
layoutParams.height = child.height - (dependency.bottom - child.top)
child.layoutParams = layoutParams
child.requestLayout()
return super.onDependentViewChanged(parent, child, dependency)
}
}
/**
* Custom implementation of ViewTreeObserver.OnGlobalLayoutListener to fix the View height
* in a bunch with Collapsing Toolbar Layout. Works when View is drawn on the screen for first time.
* To be used with ViewPagerScrollingBehavior.
*/
class FixHeightGlobalLayoutListener(val activity: Activity, val view: View) : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
val display = activity.windowManager.defaultDisplay
val size = Point()
display.getSize(size)
val height = size.y
val location = IntArray(2)
view.getLocationOnScreen(location)
view.post {
val layoutParams = view.layoutParams as ViewGroup.LayoutParams
layoutParams.height = height - location[1]
view.layoutParams = layoutParams
view.requestLayout()
}
view.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
And use them in your code:
Add the custom behavior to your ViewPager: app:layout_behavior="your.package.ViewPagerScrollingBehavior"
Add custom OnGlobalLayoutListener to your ViewPager: viewPager.getViewTreeObserver().addOnGlobalLayoutListener(new FixHeightGlobalLayoutListener(this, viewPager));
A possible hack can be adding same bottom margin as toolbar which is
?attr/actionBarSize . You can even fiddle around with other possible ui hacks of margins to give you best result.
You should not set behavior type "appbar_scrolling_view_behavior" to your ViewPager. But set it to the outer layout. Somethinglike below
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/tabbed_fragments_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>

Statusbar is not transparent but white

To test kotlin with anko DSL I decided to start a new proyect in last android studio ide (2.1.3), using kotlin plugin (1.0.3) and latest anko library (0.9)
I used the default proyect Navigation Drawer Activity, so I just had to convert the main xml to anko.
This is the xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<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" >
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
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" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior" >
<TextView
android:text="Hello World!"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
And it is working perfectly, as you can see here:
With anko, I tried to copy every detail from the xml, getting this code:
class MainActivityUi: AnkoComponent<MainActivity> {
override fun createView(ui: AnkoContext<MainActivity>) = with(ui) {
drawerLayout {
id = R.id.drawer_layout
fitsSystemWindows = true
coordinatorLayout {
appBarLayout(R.style.AppTheme_AppBarOverlay) {
toolbar {
id = R.id.toolbar
backgroundColor = colorAttr(R.attr.colorPrimary)
popupTheme = R.style.AppTheme_PopupOverlay
}.lparams(height=dimenAttr(R.attr.actionBarSize),width=matchParent)
}.lparams(width=matchParent)
relativeLayout {
padding = dip(16)
textView("Hello World!")
}.lparams(height=matchParent,width=matchParent) {
behavior = AppBarLayout.ScrollingViewBehavior()
}
}.lparams(height=matchParent,width=matchParent)
navigationView {
id = R.id.nav_view
inflateHeaderView(R.layout.nav_header_main)
inflateMenu(R.menu.activity_main_drawer)
}.lparams(height=matchParent) {
gravity = Gravity.START
fitsSystemWindows = true
}
}
}
}
And instead, I'm getting this white statusbar:
The only changes I did was in the MainActivity change the setContentView(R.layout.activity_main), to MainActivityUi.setContentView(this).
So, my question is, why is this happening when they are the same views and layouts? and how can I fix that?
EDIT: I'm using the default proyect that it's created when in Android Studio you choose new proyect, and then you choose DrawerNavigationActivity. If in setContentView I choose to show the xml's view, the statusbar is blue (first screenshot), but if I choose to show the anko's view I get the white statusbar.
In both cases, I'm using same themes, colors, etc, and when using the xml layout, everything is working perfectly, so it must be an anko's problem
Try to do
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
inside onCreate()
it worked for me
Reference
EDIT:
Also My Code
drawerLayout {
lparams(width = matchParent, height = matchParent)
coordinatorLayout {
setPadding(0, dip(24), 0, 0)
appBarLayout {
toolbar {
backgroundColor = primaryColor
setTitleTextColor(primaryColorText)
}.lparams(width = matchParent, height = dip(toolbar_size))
}.lparams(width = matchParent, height = dip(toolbar_size))
}.lparams(width = matchParent, height = matchParent)
navigationView {
}.lparams(width = dip(302), height = matchParent) {
gravity = Gravity.START
}
}
EDIT 2:
By looking at the source code of androidx, they add some code to handle "fitsSystemWindows". We can copy and paste to archive the same effect. Although Anko is dead, it still useful to create Drawerlayout programmatically (and with any other DSL library)
if (ViewCompat.getFitsSystemWindows(this)) {
if (Build.VERSION.SDK_INT >= 21) {
setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
#Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) {
final DrawerLayout drawerLayout = (DrawerLayout) view;
drawerLayout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
return insets.consumeSystemWindowInsets();
}
});
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
final TypedArray a = context.obtainStyledAttributes(THEME_ATTRS);
try {
mStatusBarBackground = a.getDrawable(0);
} finally {
a.recycle();
}
} else {
mStatusBarBackground = null;
}
}
You're wrong thinking that the status bar is transparent by default.
According to this image
taken from Android Developers Reference. Check: https://developer.android.com/training/material/theme.html
the status bar color depends on what you have defined in colors.xml or styles.xml in values folder as colorPrimaryDark, so it's not transparent.
Your problem is not white color in status bar which is correct for transparency, but not enough knowledge of using themes in Android applications.
EDIT: Changing status bar color (Java):
Window window = activity.getWindow();
// clear FLAG_TRANSLUCENT_STATUS flag:
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// finally change the color
window.setStatusBarColor(activity.getResources().getColor(R.color.my_statusbar_color));
or
public void setStatusBarColor(View statusBar,int color){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//status bar height
int actionBarHeight = getActionBarHeight();
int statusBarHeight = getStatusBarHeight();
//action bar height
statusBar.getLayoutParams().height = actionBarHeight + statusBarHeight;
statusBar.setBackgroundColor(color);
}
}
Hope it will help
It is not your statusbar color issue. Correct me if I am wrong, I believe you are using the Cyanogenmod OS 13.0 edition by the looks of your battery symbol. Switch it back to the default theme in your themes section. Then report back if the issue still persists with your colors.xml file.
Refer this link here for your Kotlin translucent status bar issue.
https://github.com/fython/MaterialStatusBarCompat

Categories

Resources