Change IDrawerProfile, IUnreadCounter to interface. Add BS item description. Add BS on close listener. Fix BS list filtering. Add toolbar image.

This commit is contained in:
kubasz 2019-09-05 20:28:52 +02:00
parent e8a64a7c9b
commit 2efa7f4947
21 changed files with 497 additions and 244 deletions

View File

@ -5,13 +5,13 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
compileSdkVersion setup.compileSdk
defaultConfig {
applicationId "pl.szczodrzynski.navigation"
minSdkVersion 16
targetSdkVersion 28
versionCode 300
versionName "0.3.0"
minSdkVersion setup.minSdk
targetSdkVersion setup.targetSdk
versionCode release.versionCode
versionName release.versionName
}
buildTypes {
release {
@ -33,15 +33,15 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "com.mikepenz:materialdrawer:7.0.0-rc05"
implementation "androidx.appcompat:appcompat:${versions.appcompat}"
implementation "androidx.legacy:legacy-support-v4:${versions.legacy}"
implementation "com.github.kuba2k2.MaterialDrawer:library:${versions.materialdrawer}"
//implementation "com.mikepenz:crossfader:1.6.0" // do not update
implementation "com.mikepenz:iconics-core:${iconics}" // do not update. >3.1.0 Breaks jelly bean
implementation "com.mikepenz:iconics-views:${iconics}" // do not update
implementation "com.mikepenz:community-material-typeface:3.5.95.1-kotlin@aar"
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation "com.google.android.material:material:$material_version"
implementation "com.mikepenz:iconics-core:${versions.iconics}" // do not update. >3.1.0 Breaks jelly bean
implementation "com.mikepenz:iconics-views:${versions.iconics}" // do not update
implementation "com.mikepenz:community-material-typeface:${versions.font_cmd}@aar"
implementation "androidx.core:core-ktx:${versions.ktx}"
implementation "androidx.constraintlayout:constraintlayout:${versions.constraintLayout}"
implementation "com.google.android.material:material:${versions.material}"
implementation project(":navlib")
}

View File

@ -0,0 +1,27 @@
package pl.szczodrzynski.navigation
import android.content.Context
import android.graphics.drawable.Drawable
import android.widget.ImageView
import pl.szczodrzynski.navlib.ImageHolder
import pl.szczodrzynski.navlib.drawer.IDrawerProfile
class DrawerProfile(
override var id: Int,
override var name: String?,
override var subname: String?,
override var image: String?
) : IDrawerProfile {
override fun getImageDrawable(context: Context): Drawable? {
return null
}
override fun getImageHolder(context: Context): ImageHolder? {
return ImageHolder(image ?: return null)
}
override fun applyImageTo(imageView: ImageView) {
ImageHolder(image ?: return).applyTo(imageView)
}
}

View File

@ -85,10 +85,6 @@ class MainActivity : AppCompatActivity() {
recreate()
}
commitButton.setOnClickListener {
navView.systemBarsUtil?.commit()
}
//navView.init(this)
// init the drawer before SystemBarsUtil
@ -285,12 +281,12 @@ class MainActivity : AppCompatActivity() {
setAccountHeaderBackground("/sdcard/ban.gif")
appendProfiles(
IDrawerProfile(1, "Think Pad", "think with a pad", "/sdcard/thinkpad.gif"),
IDrawerProfile(2, "Phil Swift", "I sawed this boat in half!!!", "/sdcard/phil.jpg"),
IDrawerProfile(3, "The meme bay", "Visit my amazing website", "/sdcard/loader.gif"),
IDrawerProfile(4, "Mark Zuckerberg", "", null),
IDrawerProfile(5, "I love GDPR", "spotify:user:popjustice:playlist:5Pe51v0sHLybSEkX0m0JRf", "/sdcard/tenor2.gif"),
IDrawerProfile(6, "Gandalf", "http://sax.hol.es/", "/sdcard/facepalm.gif")
DrawerProfile(1, "Think Pad", "think with a pad", "/sdcard/thinkpad.gif"),
DrawerProfile(2, "Phil Swift", "I sawed this boat in half!!!", "/sdcard/phil.jpg"),
DrawerProfile(3, "The meme bay", "Visit my amazing website", "/sdcard/loader.gif"),
DrawerProfile(4, "Mark Zuckerberg", "", null),
DrawerProfile(5, "I love GDPR", "spotify:user:popjustice:playlist:5Pe51v0sHLybSEkX0m0JRf", "/sdcard/tenor2.gif"),
DrawerProfile(6, "Gandalf", "http://sax.hol.es/", "/sdcard/facepalm.gif")
)
addProfileSettings(

View File

@ -29,11 +29,6 @@
android:layout_width="wrap_content"
android:layout_height="48dp"
android:text="Switch theme" />
<Button
android:id="@+id/commitButton"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:text="Commit SystemBarsUtil" />
<TextView
android:layout_width="match_parent"

View File

@ -1,14 +1,59 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.41'
ext.material_version = '1.1.0-alpha09'
ext {
kotlin_version = '1.3.50'
release = [
versionName: "0.4.0",
versionCode: 400
]
setup = [
compileSdk: 28,
buildTools: "28.0.3",
minSdk : 16,
targetSdk : 28
]
versions = [
kotlin : "1.3.50",
ktx : "1.0.2",
androidX : '1.0.0',
annotation : '1.1.0',
recyclerView : '1.1.0-beta03',
material : '1.1.0-alpha09',
appcompat : '1.1.0-rc01',
constraintLayout : '2.0.0-beta2',
cardview : '1.0.0',
gridLayout : '1.0.0',
navigation : "2.0.0",
navigationFragment: "1.0.0",
legacy : "1.0.0",
room : "2.2.0-beta01",
lifecycle : "2.2.0-alpha03",
firebase : '17.2.0',
firebasemessaging: "20.0.0",
play_services : "17.0.0",
materialdialogs : "0.9.6.0",
materialdrawer : "e603091449",
iconics : "4.0.1-b02",
font_cmd : "3.5.95.1-kotlin",
gifdrawable : "1.2.15"
]
}
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0-rc03'
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
@ -24,23 +69,6 @@ allprojects {
}
}
ext {
compileSdkVersion = 28
buildToolsVersion = '28.0.3'
targetSdkVersion = compileSdkVersion
minSdkVersion = 16
androidXAppCompat = '1.1.0-beta01'
androidXRecyclerView = '1.1.0-alpha06'
androidXCardView = '1.0.0'
androidXGridLayout = '1.0.0'
androidXConstraintLayout = '1.1.3'
googleMaterial = '1.1.0-alpha09'
iconics = '4.0.1-b01'
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@ -3,14 +3,13 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
compileSdkVersion setup.compileSdk
defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 300
versionName "0.3.0"
minSdkVersion setup.minSdk
targetSdkVersion setup.targetSdk
versionCode release.versionCode
versionName release.versionName
consumerProguardFiles 'consumer-rules.pro'
@ -35,21 +34,20 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'com.google.android.material:material:1.1.0-alpha09'
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "com.mikepenz:materialdrawer:7.0.0-rc05"
implementation "com.mikepenz:iconics-core:4.0.1-b01"
implementation 'com.mikepenz:community-material-typeface:3.5.95.1-kotlin@aar'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.15'
implementation "androidx.annotation:annotation:${versions.annotation}"
implementation "androidx.appcompat:appcompat:${versions.appcompat}"
implementation "androidx.constraintlayout:constraintlayout:${versions.constraintLayout}"
implementation "androidx.core:core-ktx:${versions.ktx}"
implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.legacy:legacy-support-v4:${versions.legacy}"
implementation "androidx.recyclerview:recyclerview:${versions.recyclerView}"
implementation "com.google.android.material:material:${versions.material}"
implementation "androidx.appcompat:appcompat:${androidXAppCompat}"
implementation "androidx.recyclerview:recyclerview:${androidXRecyclerView}"
implementation "androidx.annotation:annotation:1.1.0"
implementation "com.google.android.material:material:${googleMaterial}"
implementation "androidx.constraintlayout:constraintlayout:${androidXConstraintLayout}"
implementation 'androidx.gridlayout:gridlayout:1.0.0'
api "com.github.kuba2k2.MaterialDrawer:library:${versions.materialdrawer}"
api "com.mikepenz:community-material-typeface:${versions.font_cmd}@aar"
api "com.mikepenz:iconics-core:${versions.iconics}"
implementation "com.mikepenz:itemanimators:1.1.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${versions.kotlin}"
implementation "pl.droidsonroids.gif:android-gif-drawable:${versions.gifdrawable}"
}

View File

@ -3,10 +3,12 @@ package pl.szczodrzynski.navlib
import android.content.Context
import android.graphics.Bitmap
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.drawable.Drawable
import android.net.Uri
import android.view.View
import android.widget.ImageView
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import androidx.appcompat.content.res.AppCompatResources
import com.mikepenz.iconics.IconicsColor
@ -33,10 +35,22 @@ open class ImageHolder : com.mikepenz.materialdrawer.holder.ImageHolder {
constructor(@DrawableRes iconRes: Int) : super(iconRes) {}
constructor(@DrawableRes iconRes: Int, colorFilter: Int?) : super(iconRes) {
this.colorFilter = colorFilter
}
constructor(iicon: IIcon) : super(null as Bitmap?) {
this.iIcon = iicon
}
@ColorInt
var colorFilter: Int? = null
var colorFilterMode: PorterDuff.Mode = PorterDuff.Mode.DST_OVER
override fun applyTo(imageView: ImageView): Boolean {
return applyTo(imageView, null)
}
/**
* sets an existing image to the imageView
*
@ -69,6 +83,11 @@ open class ImageHolder : com.mikepenz.materialdrawer.holder.ImageHolder {
imageView.setImageBitmap(null)
return false
}
if (colorFilter != null) {
imageView.colorFilter = PorterDuffColorFilter(colorFilter!!, colorFilterMode)
}
return true
}
}

View File

@ -2,6 +2,8 @@ package pl.szczodrzynski.navlib
import android.content.Context
import android.util.AttributeSet
import android.widget.ImageView
import androidx.core.view.children
import com.google.android.material.appbar.MaterialToolbar
class NavToolbar : MaterialToolbar {
@ -17,7 +19,23 @@ class NavToolbar : MaterialToolbar {
create(attrs, defStyle)
}
var toolbarImage: ImageView? = null
set(value) {
field = value
toolbarImage?.setOnClickListener {
profileImageClickListener?.invoke()
}
}
private fun create(attrs: AttributeSet?, defStyle: Int) {
}
var profileImageClickListener: (() -> Unit)? = null
var profileImage
get() = toolbarImage?.drawable
set(value) {
toolbarImage?.setImageDrawable(value)
}
}

View File

@ -78,7 +78,8 @@ class NavView : FrameLayout {
findViewById(R.id.nv_drawerContainer),
findViewById(R.id.nv_fixedDrawerContainer),
findViewById(R.id.nv_miniDrawerContainerLandscape),
findViewById(R.id.nv_miniDrawerContainerPortrait)
findViewById(R.id.nv_miniDrawerContainerPortrait),
findViewById(R.id.nv_miniDrawerElevation)
)
toolbar = findViewById(R.id.nv_toolbar)
bottomBar = findViewById(R.id.nv_bottomBar)
@ -87,6 +88,8 @@ class NavView : FrameLayout {
drawer.toolbar = toolbar
drawer.bottomBar = bottomBar
toolbar.toolbarImage = findViewById(R.id.nv_toolbar_image)
bottomBar.drawer = drawer
bottomBar.bottomSheet = bottomSheet
bottomBar.fabView = floatingActionButton
@ -96,14 +99,15 @@ class NavView : FrameLayout {
}
fun configSystemBarsUtil(systemBarsUtil: SystemBarsUtil) {
this.systemBarsUtil = systemBarsUtil
systemBarsUtil.statusBarBgView = statusBarBackground
systemBarsUtil.navigationBarBgView = navigationBarBackground
systemBarsUtil.statusBarDarkView = nv_statusBarDarker
//systemBarsUtil.navigationBarDarkView = navigationBarBackground
systemBarsUtil.insetsListener = nv_drawerContainer
systemBarsUtil.marginBySystemBars = mainView
systemBarsUtil.paddingByNavigationBar = bottomSheet.getContentView()
this.systemBarsUtil = systemBarsUtil.apply {
this.statusBarBgView = statusBarBackground
this.navigationBarBgView = navigationBarBackground
this.statusBarDarkView = nv_statusBarDarker
//this.navigationBarDarkView = navigationBarBackground
this.insetsListener = nv_drawerContainer
this.marginBySystemBars = mainView
this.paddingByNavigationBar = bottomSheet.getContentView()
}
}
@ -136,7 +140,7 @@ class NavView : FrameLayout {
extendedFloatingActionButton.setOnClickListener(onClickListener)
}
var systemBarsUtil: SystemBarsUtil? = null
internal var systemBarsUtil: SystemBarsUtil? = null
private fun setContentMargins() {
val layoutParams = CoordinatorLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)

View File

@ -3,7 +3,6 @@ package pl.szczodrzynski.navlib
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.os.Build
import android.util.TypedValue
@ -14,17 +13,12 @@ import com.google.android.material.elevation.ElevationOverlayProvider
import com.mikepenz.iconics.IconicsColor
import com.mikepenz.iconics.IconicsDrawable
import android.util.DisplayMetrics
import android.view.Display
import android.view.WindowManager
import android.R.attr.y
import android.R.attr.x
import android.graphics.Point
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import com.mikepenz.materialdrawer.Drawer
import com.mikepenz.materialdrawer.holder.StringHolder
import com.mikepenz.materialdrawer.model.BaseDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.Badgeable
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
/*private val displayMetrics by lazy {
@ -63,12 +57,6 @@ fun getBottomInset(context: Context, view: View): Float {
} * context.resources.displayMetrics.density
}
fun getColorFromAttr(context: Context, @AttrRes color: Int): Int {
val typedValue = TypedValue()
context.theme.resolveAttribute(color, typedValue, true)
return typedValue.data
}
fun View.getActivity(): Activity {
return findViewById<View>(android.R.id.content).context as Activity
}
@ -136,6 +124,12 @@ fun hasNavigationBar(context: Context): Boolean {
fun IconicsDrawable.colorAttr(context: Context, @AttrRes attrRes: Int) = color(IconicsColor.colorInt(getColorFromAttr(context, attrRes)))
fun getColorFromAttr(context: Context, @AttrRes color: Int): Int {
val typedValue = TypedValue()
context.theme.resolveAttribute(color, typedValue, true)
return typedValue.data
}
fun Context.getDrawableFromRes(@DrawableRes id: Int): Drawable {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
resources.getDrawable(id, theme)
@ -145,10 +139,34 @@ fun Context.getDrawableFromRes(@DrawableRes id: Int): Drawable {
}
}
@ColorInt
fun Context.getColorFromRes(@ColorRes id: Int): Int {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
resources.getColor(id, theme)
}
else {
resources.getColor(id)
}
}
fun Drawer.updateBadge(identifier: Long, badge: StringHolder?) {
val drawerItem = getDrawerItem(identifier)
if (drawerItem is Badgeable<*>) {
drawerItem.withBadge(badge)
updateItem(drawerItem)
}
}
fun crc16(buffer: String): Int {
/* Note the change here */
var crc = 0x1D0F
for (j in buffer) {
crc = crc.ushr(8) or (crc shl 8) and 0xffff
crc = crc xor (j.toInt() and 0xff)//byte to int, trunc sign
crc = crc xor (crc and 0xff shr 4)
crc = crc xor (crc shl 12 and 0xffff)
crc = crc xor (crc and 0xFF shl 5 and 0xffff)
}
crc = crc and 0xffff
return crc
}

View File

@ -152,6 +152,7 @@ class NavBottomSheet : CoordinatorLayout {
// steal the focus from any EditTexts
dragBar.requestFocus()
hideKeyboard()
onCloseListener?.invoke()
}
else if (!bottomSheetVisible) {
bottomSheetVisible = true
@ -179,6 +180,8 @@ class NavBottomSheet : CoordinatorLayout {
textInputEditText.addTextChangedListener(textInputWatcher)
}
var onCloseListener: (() -> Unit)? = null
/* _____ _
|_ _| |
| | | |_ ___ _ __ ___ ___
@ -189,38 +192,52 @@ class NavBottomSheet : CoordinatorLayout {
appendItem(item)
}
fun appendItem(item: IBottomSheetItem<*>) {
items += item
adapter.notifyItemInserted(items.size - 1)
items.add(item)
adapter.notifyDataSetChanged()
//adapter.notifyItemInserted(items.size - 1)
}
fun appendItems(vararg items: IBottomSheetItem<*>) {
this.items.addAll(items)
adapter.notifyDataSetChanged()
//adapter.notifyItemRangeInserted(this.items.size - items.size, items.size)
}
fun prependItem(item: IBottomSheetItem<*>) {
items.add(0, item)
adapter.notifyItemInserted(0)
adapter.notifyDataSetChanged()
//adapter.notifyItemInserted(0)
}
fun prependItems(vararg items: IBottomSheetItem<*>) {
this.items.addAll(0, items.toList())
adapter.notifyDataSetChanged()
//adapter.notifyItemRangeInserted(0, items.size)
}
fun addItemAt(index: Int, item: IBottomSheetItem<*>) {
items.add(index, item)
adapter.notifyItemInserted(index)
adapter.notifyDataSetChanged()
//adapter.notifyItemInserted(index)
}
fun removeItemById(id: Int) {
items.filterNot { it.id == id }
}
fun removeItemAt(index: Int) {
items.removeAt(index)
adapter.notifyItemRemoved(index)
adapter.notifyDataSetChanged()
//adapter.notifyItemRemoved(index)
}
fun removeAllItems() {
items.clear()
adapter.notifyDataSetChanged()
}
fun removeAllStatic() {
items.filter { it.isContextual }
items.removeAll { !it.isContextual }
adapter.notifyDataSetChanged()
}
fun removeAllContextual() {
items.filter { !it.isContextual }
items.removeAll { it.isContextual }
adapter.notifyDataSetChanged()
}
fun removeSeparators() {
items.filterNot { it is BottomSheetSeparatorItem }
items.removeAll { it is BottomSheetSeparatorItem }
adapter.notifyDataSetChanged()
}
@ -300,7 +317,7 @@ class NavBottomSheet : CoordinatorLayout {
* bit 2 = current sorting mode
*/
if (toggleGroupSelectionMode == TOGGLE_GROUP_SORTING_ORDER) {
val button = group.findViewById<MaterialButton>(checkedId)
val button = group.findViewById<MaterialButton>(checkedId) ?: return@OnButtonCheckedListener
var tag = button.tag as Int
var sortingMode: Int? = null
if (isChecked) {

View File

@ -2,6 +2,7 @@ package pl.szczodrzynski.navlib.bottomsheet.items
import android.graphics.drawable.Drawable
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
@ -9,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.IIcon
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
import com.mikepenz.materialize.holder.ImageHolder
import pl.szczodrzynski.navlib.R
@ -33,22 +35,31 @@ data class BottomSheetPrimaryItem(override val isContextual: Boolean = true) : I
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val root = itemView.findViewById<View>(R.id.item_root)
val image = itemView.findViewById<ImageView>(R.id.item_icon)
val text = itemView.findViewById<TextView>(R.id.item_text)
val description = itemView.findViewById<TextView>(R.id.item_description)
}
override fun bindViewHolder(viewHolder: ViewHolder) {
viewHolder.root.setOnClickListener(onClickListener)
viewHolder.text.text = title
viewHolder.text.setTextColor(getColorFromAttr(viewHolder.text.context, R.attr.material_drawer_primary_text))
viewHolder.text.setCompoundDrawables(
IconicsDrawable(viewHolder.text.context)
.icon(iconicsIcon?:CommunityMaterial.Icon.cmd_android)
viewHolder.image.setImageDrawable(IconicsDrawable(viewHolder.text.context)
.icon(iconicsIcon ?: CommunityMaterial.Icon.cmd_android)
.colorAttr(viewHolder.text.context, R.attr.material_drawer_primary_icon)
.sizeDp(20),
null,
null,
null
)
.sizeDp(24))
viewHolder.description.visibility = View.VISIBLE
when {
descriptionRes != null -> viewHolder.description.setText(descriptionRes!!)
description != null -> viewHolder.description.text = description
else -> viewHolder.description.visibility = View.GONE
}
when {
titleRes != null -> viewHolder.text.setText(titleRes!!)
else -> viewHolder.text.text = title
}
viewHolder.text.setTextColor(getColorFromAttr(viewHolder.text.context, R.attr.material_drawer_primary_text))
}
/*_____ _

View File

@ -1,6 +1,17 @@
package pl.szczodrzynski.navlib.drawer
data class IDrawerProfile(var id: Int,
var name: String,
var subname: String?,
var image: String?)
import android.content.Context
import android.graphics.drawable.Drawable
import android.widget.ImageView
import pl.szczodrzynski.navlib.ImageHolder
interface IDrawerProfile {
var id: Int
var name: String?
var subname: String?
var image: String?
fun getImageDrawable(context: Context): Drawable?
fun getImageHolder(context: Context): ImageHolder?
fun applyImageTo(imageView: ImageView)
}

View File

@ -1,6 +1,8 @@
package pl.szczodrzynski.navlib.drawer
data class IUnreadCounter(val profileId: Int,
val type: Int,
var drawerItemId: Int? = null,
var count: Int)
interface IUnreadCounter {
var profileId: Int
var type: Int
var drawerItemId: Int?
var count: Int
}

View File

@ -6,8 +6,7 @@ import android.content.Context
import android.content.res.Configuration
import android.content.res.Resources
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.graphics.PorterDuff
import android.util.Log
import android.view.View
import android.widget.FrameLayout
@ -15,12 +14,7 @@ import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import androidx.customview.widget.ViewDragHelper
import androidx.drawerlayout.widget.DrawerLayout
import com.mikepenz.iconics.IconicsColor
import com.mikepenz.iconics.IconicsColor.Companion.colorRes
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.IconicsSize
import com.mikepenz.iconics.IconicsSize.Companion.dp
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.itemanimators.AlphaCrossFadeAnimator
import com.mikepenz.materialdrawer.*
import com.mikepenz.materialdrawer.holder.BadgeStyle
import com.mikepenz.materialdrawer.holder.StringHolder
@ -29,8 +23,6 @@ import com.mikepenz.materialdrawer.model.ProfileDrawerItem
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.IProfile
import pl.droidsonroids.gif.GifDrawable
import pl.droidsonroids.gif.MultiCallback
import pl.szczodrzynski.navlib.*
import pl.szczodrzynski.navlib.R
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
@ -40,7 +32,8 @@ class NavDrawer(
val drawerContainer: LinearLayout,
val fixedDrawerContainer: FrameLayout,
val miniDrawerContainerLandscape: FrameLayout,
val miniDrawerContainerPortrait: FrameLayout
val miniDrawerContainerPortrait: FrameLayout,
val miniDrawerElevation: View
) {
companion object {
private const val DRAWER_MODE_NORMAL = 0
@ -82,57 +75,61 @@ class NavDrawer(
.withColorRes(R.color.md_red_700)
val drawerBuilder = DrawerBuilder()
.withActivity(activity)
.withDrawerLayout(R.layout.material_drawer_fits_not)
.withRootView(drawerContainer)
.withFullscreen(true)
.withTranslucentStatusBar(false)
.withTranslucentNavigationBar(true)
.withTranslucentNavigationBarProgrammatically(false)
.withToolbar(bottomBar)
.withDisplayBelowStatusBar(true)
.withActionBarDrawerToggleAnimated(true)
.withGenerateMiniDrawer(true /* if it is not showing on screen, clicking items throws an exception */)
.withOnDrawerListener(object : Drawer.OnDrawerListener {
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
override fun onDrawerOpened(drawerView: View) {
drawerOpenedListener?.invoke()
}
override fun onDrawerClosed(drawerView: View) {
drawerClosedListener?.invoke()
profileSelectionClose()
}
})
.withOnDrawerItemClickListener { _, position, drawerItem ->
if (drawerItem.identifier.toInt() == selection) {
return@withOnDrawerItemClickListener false
}
when (drawerItemSelectedListener?.invoke(drawerItem.identifier.toInt(), position, drawerItem)) {
true -> {
when {
!drawerItem.isSelectable -> {
setSelection(selection, false)
return@withOnDrawerItemClickListener false
.withActivity(activity)
.withDrawerLayout(R.layout.material_drawer_fits_not)
.withHasStableIds(true)
.withItemAnimator(AlphaCrossFadeAnimator())
.withRootView(drawerContainer)
.withFullscreen(true)
.withTranslucentStatusBar(false)
.withTranslucentNavigationBar(true)
.withTranslucentNavigationBarProgrammatically(false)
.withToolbar(bottomBar)
.withDisplayBelowStatusBar(true)
.withActionBarDrawerToggleAnimated(true)
.withShowDrawerOnFirstLaunch(true)
.withShowDrawerUntilDraggedOpened(true)
.withGenerateMiniDrawer(true /* if it is not showing on screen, clicking items throws an exception */)
.withOnDrawerListener(object : Drawer.OnDrawerListener {
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
override fun onDrawerOpened(drawerView: View) {
drawerOpenedListener?.invoke()
}
override fun onDrawerClosed(drawerView: View) {
drawerClosedListener?.invoke()
profileSelectionClose()
}
})
.withOnDrawerItemClickListener { _, position, drawerItem ->
if (drawerItem.identifier.toInt() == selection) {
return@withOnDrawerItemClickListener false
}
when (drawerItemSelectedListener?.invoke(drawerItem.identifier.toInt(), position, drawerItem)) {
true -> {
when {
!drawerItem.isSelectable -> {
setSelection(selection, false)
return@withOnDrawerItemClickListener false
}
drawerItem is DrawerPrimaryItem -> toolbar.title = drawerItem.appTitle ?: drawerItem.name?.getText(context) ?: ""
drawerItem is BaseDrawerItem<*, *> -> toolbar.title = drawerItem.name?.getText(context) ?: ""
}
drawerItem is DrawerPrimaryItem -> toolbar.title = drawerItem.appTitle ?: drawerItem.name?.text ?: ""
drawerItem is BaseDrawerItem<*, *> -> toolbar.title = drawerItem.name?.text ?: ""
//setSelection(drawerItem.identifier.toInt(), false)
return@withOnDrawerItemClickListener false
}
false -> {
setSelection(selection, false)
return@withOnDrawerItemClickListener true
}
else -> {
return@withOnDrawerItemClickListener false
}
setSelection(drawerItem.identifier.toInt(), false)
return@withOnDrawerItemClickListener false
}
false -> {
setSelection(selection, false)
return@withOnDrawerItemClickListener true
}
else -> {
return@withOnDrawerItemClickListener false
}
}
}
.withOnDrawerItemLongClickListener { _, position, drawerItem ->
drawerItemLongClickListener?.invoke(drawerItem.identifier.toInt(), position, drawerItem) ?: true
}
}
.withOnDrawerItemLongClickListener { _, position, drawerItem ->
drawerItemLongClickListener?.invoke(drawerItem.identifier.toInt(), position, drawerItem) ?: true
}
val accountHeaderBuilder = AccountHeaderBuilder()
@ -144,11 +141,13 @@ class NavDrawer(
}
updateBadges()
if (current) {
profileSelectionClose()
close()
profileSelectionClose()
return@withOnAccountHeaderListener true
}
drawerProfileSelectedListener?.invoke(profile.identifier.toInt(), profile, current, view) ?: false
(drawerProfileSelectedListener?.invoke(profile.identifier.toInt(), profile, current, view) ?: false).also {
setToolbarProfileImage(profileList.singleOrNull { it.id == profile.identifier.toInt() })
}
}
.withOnAccountHeaderItemLongClickListener { view, profile, current ->
if (profile is ProfileSettingDrawerItem) {
@ -182,6 +181,7 @@ class NavDrawer(
}
return@withOnMiniDrawerItemClickListener false
}
miniDrawer?.withIncludeSecondaryDrawerItems(false)
// TODO 2019-08-27 build miniDrawerView only if needed
// building in decideDrawerMode causes an exception when clicking drawer items
@ -189,6 +189,11 @@ class NavDrawer(
miniDrawerView = miniDrawer?.build(context)
updateMiniDrawer()
toolbar.profileImageClickListener = {
profileSelectionOpen()
open()
}
val configuration = context.resources.configuration
decideDrawerMode(
configuration.orientation,
@ -260,6 +265,12 @@ class NavDrawer(
}
}
fun setItems(vararg items: IDrawerItem<*>) {
drawer?.removeAllItems()
drawer?.addItems(*items)
updateMiniDrawer()
}
/* _____ _ _ _ _ _
| __ \ (_) | | | | | | | |
| |__) | __ ___ ____ _| |_ ___ _ __ ___ ___| |_| |__ ___ __| |___
@ -377,6 +388,8 @@ class NavDrawer(
Log.d("NavLib", "- slider enabled")
}
}
miniDrawerElevation.visibility = if (drawerMode == DRAWER_MODE_MINI) View.VISIBLE else View.GONE
}
private fun updateMiniDrawer() {
@ -434,13 +447,25 @@ class NavDrawer(
fun miniDrawerEnabled(): Boolean = drawerMode == DRAWER_MODE_MINI
fun fixedDrawerEnabled(): Boolean = drawerMode == DRAWER_MODE_FIXED
fun setSelection(id: Int, fireOnClick: Boolean = true) {
Log.d("NavDebug", "setSelection(id = $id, fireOnClick = $fireOnClick)")
// seems that this cannot be open, because the itemAdapter has Profile items
// instead of normal Drawer items...
profileSelectionClose()
selection = id
if (drawer?.currentSelection != id.toLong())
if (drawer?.currentSelection != id.toLong()) {
}
if (drawer?.currentSelection != id.toLong() || !fireOnClick)
drawer?.setSelection(id.toLong(), fireOnClick)
if (drawerMode == DRAWER_MODE_MINI)
miniDrawer?.setSelection(id.toLong())
}
fun getSelection(): Int = selection
// TODO 2019-08-27 add methods for Drawable, @DrawableRes
fun setAccountHeaderBackground(path: String?) {
@ -457,7 +482,7 @@ class NavDrawer(
| ___/ '__/ _ \| _| | |/ _ \/ __|
| | | | | (_) | | | | | __/\__ \
|_| |_| \___/|_| |_|_|\___||__*/
private var profileList = arrayListOf<IDrawerProfile>()
private var profileList: MutableList<IDrawerProfile> = mutableListOf()
fun addProfileSettings(vararg items: ProfileSettingDrawerItem) {
accountHeader?.profiles?.addAll(items)
@ -465,47 +490,40 @@ class NavDrawer(
private fun updateProfileList() {
// remove all profile items
accountHeader?.profiles?.filterNot { it is ProfileDrawerItem }
val profiles = accountHeader?.profiles?.filterNot { it is ProfileDrawerItem } as MutableList<IProfile<*>>?
if (profileList.isEmpty())
drawerProfileListEmptyListener?.invoke()
profileList.forEachIndexed { index, profile ->
val image = if (profile.image != null) {
try {
ImageHolder(profile.image ?: "")
}
catch (_: Exception) {
ImageHolder(R.drawable.profile4)
}
}
else {
ImageHolder(R.drawable.profile4)
}
val image = profile.getImageHolder(context)
ProfileDrawerItem()
.withIdentifier(profile.id.toLong())
.withName(profile.name)
.withEmail(profile.subname)
.also { it.icon = image }
.withNameShown(true)
.also { accountHeader?.profiles?.add(index, it) }
.also { profiles?.add(index, it) }
}
accountHeader?.profiles = accountHeader?.profiles
accountHeader?.profiles = profiles
updateMiniDrawer()
}
fun setProfileList(profiles: ArrayList<IDrawerProfile>) {
profileList = profiles
fun setProfileList(profiles: MutableList<out IDrawerProfile>) {
profileList = profiles as MutableList<IDrawerProfile>
updateProfileList()
/*profileList.clear()
profileList.addAll(profiles)*/
}
val profileListEmpty: Boolean
get() = profileList.isEmpty()
var currentProfile: Int
get() = accountHeader?.activeProfile?.identifier?.toInt() ?: -1
set(value) {
accountHeader?.setActiveProfile(value.toLong(), true)
Log.d("NavDebug", "currentProfile = $value")
accountHeader?.setActiveProfile(value.toLong(), false)
setToolbarProfileImage(profileList.singleOrNull { it.id == value })
updateBadges()
}
fun appendProfile(profile: IDrawerProfile) {
profileList.add(profile)
@ -532,7 +550,7 @@ class NavDrawer(
updateProfileList()
}
fun removeProfileById(id: Int) {
profileList.filterNot { it.id == id }
profileList = profileList.filterNot { it.id == id }.toMutableList()
updateProfileList()
}
fun removeProfileAt(index: Int) {
@ -543,6 +561,9 @@ class NavDrawer(
profileList.clear()
updateProfileList()
}
fun removeAllProfileSettings() {
accountHeader?.profiles = accountHeader?.profiles?.filterNot { it is ProfileSettingDrawerItem }?.toMutableList()
}
fun getProfileById(id: Int, run: (it: IDrawerProfile?) -> Unit) {
profileList.singleOrNull { it.id == id }.also {
@ -557,6 +578,10 @@ class NavDrawer(
}
}
private fun setToolbarProfileImage(profile: IDrawerProfile?) {
toolbar.profileImage = profile?.getImageDrawable(context)
}
/* ____ _
| _ \ | |
@ -566,10 +591,11 @@ class NavDrawer(
|____/ \__,_|\__,_|\__, |\___||___/
__/ |
|__*/
private var unreadCounterList = arrayListOf<IUnreadCounter>()
private var unreadCounterList: MutableList<IUnreadCounter> = mutableListOf()
private val unreadCounterTypeMap = mutableMapOf<Int, Int>()
fun updateBadges() {
Log.d("NavDebug", "updateBadges()")
unreadCounterList.map {
it.drawerItemId = unreadCounterTypeMap[it.type]
}
@ -577,9 +603,11 @@ class NavDrawer(
if (it.drawerItemId == null)
return@forEach
if (it.profileId != currentProfile) {
Log.d("NavDebug", "- Remove badge for ${it.drawerItemId}")
drawer?.updateBadge(it.drawerItemId?.toLong() ?: 0, null)
return@forEach
}
Log.d("NavDebug", "- Set badge ${it.count} for ${it.drawerItemId}")
drawer?.updateBadge(
it.drawerItemId?.toLong() ?: 0,
when {
@ -592,8 +620,8 @@ class NavDrawer(
updateMiniDrawer()
}
fun setUnreadCounterList(unreadCounterList: ArrayList<IUnreadCounter>) {
this.unreadCounterList = unreadCounterList
fun setUnreadCounterList(unreadCounterList: MutableList<out IUnreadCounter>) {
this.unreadCounterList = unreadCounterList as MutableList<IUnreadCounter>
updateBadges()
}
@ -601,6 +629,13 @@ class NavDrawer(
unreadCounterTypeMap[type] = drawerItem
}
data class UnreadCounter(
override var profileId: Int,
override var type: Int,
override var drawerItemId: Int?,
override var count: Int
) : IUnreadCounter
fun setUnreadCount(profileId: Int, type: Int, count: Int) {
val item = unreadCounterList.singleOrNull {
it.type == type && it.profileId == profileId
@ -610,7 +645,7 @@ class NavDrawer(
updateBadges()
}
else {
unreadCounterList.add(IUnreadCounter(profileId, type, null, count))
unreadCounterList.add(UnreadCounter(profileId, type, null, count))
}
}
}

View File

@ -8,4 +8,11 @@ class DrawerPrimaryItem : PrimaryDrawerItem() {
this.appTitle = appTitle
return this
}
}
fun PrimaryDrawerItem.withAppTitle(appTitle: String?): PrimaryDrawerItem {
if (this !is DrawerPrimaryItem)
return this
this.appTitle = appTitle
return this
}

View File

@ -99,7 +99,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"
android:minHeight="50dp"
tools:minHeight="50dp"
tools:listitem="@layout/nav_bs_item_primary"/>
</LinearLayout>

View File

@ -3,20 +3,47 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="48dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:gravity="center"
android:background="?selectableItemBackground"
android:orientation="vertical">
android:orientation="horizontal">
<TextView
android:id="@+id/item_text"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginLeft="16dp"
<ImageView
android:id="@+id/item_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:drawablePadding="16dp"
android:fontFamily="sans-serif-medium"
android:gravity="start|center_vertical"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textSize="14sp"
tools:text="Search activity" />
tools:srcCompat="@drawable/ic_android" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/item_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:gravity="start|center_vertical"
android:textAppearance="@style/NavView.TextView"
android:textSize="14sp"
tools:text="Search activity" />
<TextView
android:id="@+id/item_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:gravity="center_vertical|start"
android:lines="1"
android:singleLine="true"
android:textAppearance="@style/NavView.TextView.Small"
android:textSize="12sp"
tools:text="Some drawer text" />
</LinearLayout>
</LinearLayout>

View File

@ -53,7 +53,20 @@
android:background="?actionBarBackground"
android:elevation="4dp"
app:title="@string/app_name"
tools:targetApi="lollipop" />
tools:targetApi="lollipop">
<com.mikepenz.materialdrawer.view.BezelImageView
android:id="@+id/nv_toolbar_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="end"
android:layout_marginEnd="13dp"
android:layout_marginRight="13dp"
android:scaleType="centerCrop"
app:biv_selectorOnPress="#80ffffff"
tools:src="@tools:sample/backgrounds/scenic" />
</pl.szczodrzynski.navlib.NavToolbar>
<View
android:id="@+id/nv_toolbarElevation"

View File

@ -6,4 +6,14 @@
<color name="background_light">#ffffff</color>
<color name="background_dark">#242424</color>
<color name="background_black">#000000</color>
<color name="colorSurface_1dp">#0dffffff</color>
<color name="colorSurface_2dp">#12ffffff</color>
<color name="colorSurface_3dp">#14ffffff</color>
<color name="colorSurface_4dp">#17ffffff</color>
<color name="colorSurface_6dp">#1cffffff</color>
<color name="colorSurface_8dp">#1fffffff</color>
<color name="colorSurface_12dp">#24ffffff</color>
<color name="colorSurface_16dp">#26ffffff</color>
<color name="colorSurface_24dp">#29ffffff</color>
</resources>

View File

@ -12,27 +12,41 @@
<item name="backgroundTint">?colorFab</item>
<item name="android:textColor">?colorOnFab</item>
</style>
<!-- default body text -->
<style name="NavView.TextView" parent="Widget.MaterialComponents.TextView">
<item name="android:textAppearance">?attr/textAppearanceBody2</item>
<style name="NavView.TextView">
<item name="android:textAppearance">@style/NavView.TextView.Normal</item>
</style>
<!-- title text 20sp, primary, medium -->
<!-- subtitle text 16sp, primary, medium -->
<!-- large body text 22sp, primary, regular -->
<!-- medium body text 18sp, primary, regular -->
<!-- normal(default) body text 14sp, primary, regular -->
<!-- small body text 14sp, secondary, medium -->
<!-- helper body text 14sp, secondary, regular -->
<style name="NavView.TextView.Normal" parent="Widget.MaterialComponents.TextView">
<item name="android:textAppearance">?attr/textAppearanceBody2</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">?android:textColorPrimary</item>
</style>
<!-- title text -->
<style name="NavView.TextView.Title" parent="TextAppearance.AppCompat.Title">
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
<!-- subtitle text, smaller than medium -->
<style name="NavView.TextView.Subtitle" parent="TextAppearance.AppCompat.Subhead">
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif-medium</item>
</style>
<!-- large body text -->
<style name="NavView.TextView.Large" parent="TextAppearance.AppCompat.Large">
</style>
<!-- medium body text -->
<style name="NavView.TextView.Medium" parent="TextAppearance.AppCompat.Medium">
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
<!-- small (helper) body text -->
<style name="NavView.TextView.Small" parent="TextAppearance.AppCompat.Small">
<item name="android:textSize">14sp</item>
<item name="android:fontFamily">sans-serif-medium</item>
</style>
<style name="NavView.TextView.Helper" parent="TextAppearance.AppCompat.Small">
<item name="android:textSize">14sp</item>
</style>
@ -48,8 +62,9 @@
<item name="colorSecondaryVariant">#018786</item>
<!-- window colors -->
<item name="android:colorBackground">@color/background_light</item>
<item name="android:windowBackground">?android:colorBackground</item>
<!-- a descendant theme should specify those two as background colors -->
<item name="android:colorBackground">@color/background_light</item>
<item name="colorSurface">#ffffff</item>
<!-- FAB styling -->
@ -58,10 +73,12 @@
<item name="colorOnFab">?colorOnSecondary</item>
<!-- text colors -->
<item name="android:textColorPrimary">#db000000</item>
<item name="android:textColorSecondary">#99000000</item>
<item name="colorOnPrimary">#ffffff</item>
<item name="colorOnSecondary">#ffffff</item>
<item name="colorOnBackground">#000000</item>
<item name="colorOnSurface">#000000</item>
<item name="colorOnBackground">?android:textColorPrimary</item>
<item name="colorOnSurface">?android:textColorPrimary</item>
<item name="elevationOverlayColor">#ffffff</item>
@ -79,9 +96,9 @@
<!-- drawer & bottom sheet styling -->
<item name="material_drawer_background">?android:colorBackground</item>
<item name="material_drawer_primary_text">#242424</item>
<item name="material_drawer_primary_text">?android:textColorPrimary</item>
<item name="material_drawer_primary_icon">#5F6368</item>
<item name="material_drawer_secondary_text">@color/material_drawer_secondary_text</item>
<item name="material_drawer_secondary_text">?android:textColorSecondary</item>
<item name="material_drawer_hint_text">@color/material_drawer_hint_text</item>
<item name="material_drawer_divider">@color/material_drawer_divider</item>
<item name="material_drawer_selected">@color/material_drawer_selected</item> <!-- Material 2 defines 12% alpha, primary color -->
@ -100,9 +117,10 @@
<item name="colorSecondaryVariant">?colorAccent</item>
<!-- window colors -->
<item name="android:colorBackground">@color/background_dark</item>
<item name="android:windowBackground">?android:colorBackground</item>
<item name="colorSurface">#303030</item>
<!-- a descendant theme should specify those two as background colors -->
<item name="android:colorBackground">@color/background_dark</item>
<item name="colorSurface">#333333</item>
<!-- FAB styling -->
<item name="colorFab">?colorAccent</item>
@ -110,10 +128,12 @@
<item name="colorOnFab">?colorOnSecondary</item>
<!-- text colors -->
<item name="android:textColorPrimary">#ffffffff</item>
<item name="android:textColorSecondary">#99ffffff</item>
<item name="colorOnPrimary">#ffffff</item>
<item name="colorOnSecondary">#ffffff</item>
<item name="colorOnBackground">#ffffff</item>
<item name="colorOnSurface">#ffffff</item>
<item name="colorOnBackground">?android:textColorPrimary</item>
<item name="colorOnSurface">?android:textColorPrimary</item>
<!-- system bars config -->
<item name="actionBarBackground">?colorSurface</item>
@ -129,9 +149,9 @@
<!-- drawer & bottom sheet styling -->
<item name="material_drawer_background">?android:colorBackground</item>
<item name="material_drawer_primary_text">#FFFFFF</item>
<item name="material_drawer_primary_text">?android:textColorPrimary</item>
<item name="material_drawer_primary_icon">#9AA0A6</item>
<item name="material_drawer_secondary_text">@color/material_drawer_dark_secondary_text</item>
<item name="material_drawer_secondary_text">?android:textColorSecondary</item>
<item name="material_drawer_hint_text">@color/material_drawer_dark_hint_text</item>
<item name="material_drawer_divider">@color/material_drawer_dark_divider</item>
<item name="material_drawer_selected">@color/material_drawer_dark_selected</item> <!-- Material 2 defines 12% alpha, primary color -->
@ -142,10 +162,7 @@
<style name="NavView.Black" parent="NavView.Dark">
<item name="android:colorBackground">@color/background_black</item>
<item name="android:windowBackground">?android:colorBackground</item>
<item name="colorSurface">#121212</item>
<item name="colorBackgroundFloating">#2D2D2D</item>
</style>