mirror of
https://github.com/kuba2k2/NavLib.git
synced 2025-02-22 22:44:45 +01:00
Fix status bar colors for Huawei, Samsung, KitKat, Jelly Bean. Fix bottom sheet dragging. Add & fix MaterialDrawer fullscreen with custom container. Add more switches/options, bottomsheet items & recyclerview WIP. BottomBar custom view & config options. Removed all bugs, added one bug.
This commit is contained in:
parent
f2fef9ddbd
commit
adb45d8e7e
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
/_hakerskie
|
8
.idea/dictionaries/Kuba.xml
generated
Normal file
8
.idea/dictionaries/Kuba.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="Kuba">
|
||||
<words>
|
||||
<w>navlib</w>
|
||||
<w>samsung</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@ -8,7 +8,6 @@
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/MaterialDrawer" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/navlib" />
|
||||
</set>
|
||||
|
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../MaterialDrawer" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -31,10 +31,11 @@ dependencies {
|
||||
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:6.1.2"
|
||||
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@aar"
|
||||
implementation "com.mikepenz:community-material-typeface:3.5.95.1-kotlin@aar"
|
||||
implementation 'androidx.core:core-ktx:1.0.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation "com.google.android.material:material:$material_version"
|
||||
|
2
app/proguard-rules.pro
vendored
2
app/proguard-rules.pro
vendored
@ -1,6 +1,6 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
# proguardFiles setting in init.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
@ -2,13 +2,16 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="pl.szczodrzynski.navigation">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme.Light">
|
||||
android:theme="@style/AppTheme.Light"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -1,21 +1,20 @@
|
||||
package pl.szczodrzynski.navigation
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.Color
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.Switch
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import android.widget.Toast
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import com.google.android.material.bottomappbar.BottomAppBar
|
||||
import android.view.WindowManager
|
||||
import android.os.Build
|
||||
import android.view.Gravity
|
||||
import kotlinx.android.synthetic.main.sample_nav_view.*
|
||||
import pl.szczodrzynski.navlib.SystemBarsUtil
|
||||
import pl.szczodrzynski.navlib.SystemBarsUtil.Companion.COLOR_DO_NOT_CHANGE
|
||||
import pl.szczodrzynski.navlib.SystemBarsUtil.Companion.COLOR_HALF_TRANSPARENT
|
||||
import pl.szczodrzynski.navlib.SystemBarsUtil.Companion.COLOR_PRIMARY_DARK
|
||||
import pl.szczodrzynski.navlib.getColorFromAttr
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
@ -23,8 +22,7 @@ class MainActivity : AppCompatActivity() {
|
||||
var darkTheme: Boolean? = null
|
||||
}
|
||||
|
||||
var showing = false
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@ -36,19 +34,30 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
setContentView(R.layout.sample_nav_view)
|
||||
|
||||
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or (when {
|
||||
darkTheme == true -> 0
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
else -> 0
|
||||
})
|
||||
appFullscreen.isChecked = getSharedPreferences("prefs", Context.MODE_PRIVATE).getBoolean("appFullscreen", false)
|
||||
statusBarDarker.isChecked = getSharedPreferences("prefs", Context.MODE_PRIVATE).getBoolean("statusBarDarker", false)
|
||||
statusBarTranslucent.isChecked = getSharedPreferences("prefs", Context.MODE_PRIVATE).getBoolean("statusBarTranslucent", false)
|
||||
navigationBarTransparent.isChecked = getSharedPreferences("prefs", Context.MODE_PRIVATE).getBoolean("navigationBarTransparent", true)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
val w = window // in Activity's onCreate() for instance
|
||||
w.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
|
||||
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
||||
)
|
||||
}
|
||||
statusBarColor.check(when (getSharedPreferences("prefs", Context.MODE_PRIVATE).getString("statusBarColor", "colorBackground")) {
|
||||
"colorPrimaryDark" -> R.id.colorPrimaryDark
|
||||
"colorPrimary" -> R.id.colorPrimary
|
||||
"colorAccent" -> R.id.colorAccent
|
||||
"colorBackground" -> R.id.colorBackground
|
||||
else -> R.id.colorBackground
|
||||
})
|
||||
statusBarFallbackLight.check(when (getSharedPreferences("prefs", Context.MODE_PRIVATE).getString("statusBarFallbackLight", "lightHalfTransparent")) {
|
||||
"lightHalfTransparent" -> R.id.lightHalfTransparent
|
||||
"lightPrimaryDark" -> R.id.lightPrimaryDark
|
||||
"lightDoNotChange" -> R.id.lightDoNotChange
|
||||
else -> R.id.lightHalfTransparent
|
||||
})
|
||||
statusBarFallbackGradient.check(when (getSharedPreferences("prefs", Context.MODE_PRIVATE).getString("statusBarFallbackGradient", "gradientDoNotChange")) {
|
||||
"gradientHalfTransparent" -> R.id.gradientHalfTransparent
|
||||
"gradientPrimaryDark" -> R.id.gradientPrimaryDark
|
||||
"gradientDoNotChange" -> R.id.gradientDoNotChange
|
||||
else -> R.id.gradientDoNotChange
|
||||
})
|
||||
|
||||
button.setOnClickListener {
|
||||
// use commit instead of apply because of recreating the activity
|
||||
@ -57,62 +66,136 @@ class MainActivity : AppCompatActivity() {
|
||||
recreate()
|
||||
}
|
||||
|
||||
/*val dim = findViewById<View>(R.id.view)
|
||||
|
||||
val nestedScrollView = findViewById<View>(R.id.nestedScrollView)
|
||||
val bottomSheetBehavior = BottomSheetBehavior.from(nestedScrollView)
|
||||
//navView.init(this)
|
||||
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
// init the drawer before SystemBarsUtil
|
||||
navView.addDrawer(activity = this)
|
||||
|
||||
val fab = findViewById<FloatingActionButton>(R.id.floatingActionButton)
|
||||
fab.setOnClickListener {
|
||||
if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_HIDDEN) {
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
|
||||
SystemBarsUtil(this).apply {
|
||||
paddingByKeyboard = navView
|
||||
appFullscreen = this@MainActivity.appFullscreen.isChecked
|
||||
statusBarColor = when (this@MainActivity.statusBarColor.checkedRadioButtonId) {
|
||||
R.id.colorPrimaryDark -> COLOR_PRIMARY_DARK
|
||||
R.id.colorPrimary -> getColorFromAttr(this@MainActivity, R.attr.colorPrimary)
|
||||
R.id.colorAccent -> getColorFromAttr(this@MainActivity, R.attr.colorAccent)
|
||||
R.id.colorBackground -> getColorFromAttr(this@MainActivity, android.R.attr.colorBackground)
|
||||
else -> 0xffff00ff.toInt()
|
||||
}
|
||||
else {
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
statusBarDarker = this@MainActivity.statusBarDarker.isChecked
|
||||
statusBarFallbackLight = when (this@MainActivity.statusBarFallbackLight.checkedRadioButtonId) {
|
||||
R.id.lightHalfTransparent -> COLOR_HALF_TRANSPARENT
|
||||
R.id.lightPrimaryDark -> COLOR_PRIMARY_DARK
|
||||
R.id.lightDoNotChange -> COLOR_DO_NOT_CHANGE
|
||||
else -> 0xff00ffff.toInt()
|
||||
}
|
||||
statusBarFallbackGradient = when (this@MainActivity.statusBarFallbackGradient.checkedRadioButtonId) {
|
||||
R.id.gradientHalfTransparent -> COLOR_HALF_TRANSPARENT
|
||||
R.id.gradientPrimaryDark -> COLOR_PRIMARY_DARK
|
||||
R.id.gradientDoNotChange -> COLOR_DO_NOT_CHANGE
|
||||
else -> 0xffffff00.toInt()
|
||||
}
|
||||
statusBarTranslucent = this@MainActivity.statusBarTranslucent.isChecked
|
||||
navigationBarTransparent = this@MainActivity.navigationBarTransparent.isChecked
|
||||
|
||||
navView.configSystemBarsUtil(this)
|
||||
|
||||
commit()
|
||||
}
|
||||
|
||||
dim.setOnClickListener {
|
||||
|
||||
appFullscreen.setOnCheckedChangeListener { _, isChecked ->
|
||||
getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().putBoolean("appFullscreen", isChecked).commit()
|
||||
recreate()
|
||||
}
|
||||
dim.setOnTouchListener { v, event ->
|
||||
if (event.action == MotionEvent.ACTION_UP) {
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
true
|
||||
statusBarDarker.setOnCheckedChangeListener { _, isChecked ->
|
||||
getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().putBoolean("statusBarDarker", isChecked).commit()
|
||||
recreate()
|
||||
}
|
||||
statusBarTranslucent.setOnCheckedChangeListener { _, isChecked ->
|
||||
getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().putBoolean("statusBarTranslucent", isChecked).commit()
|
||||
recreate()
|
||||
}
|
||||
navigationBarTransparent.setOnCheckedChangeListener { _, isChecked ->
|
||||
getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().putBoolean("navigationBarTransparent", isChecked).commit()
|
||||
recreate()
|
||||
}
|
||||
|
||||
val bottomAppBar = findViewById<BottomAppBar>(R.id.bottomAppBar)
|
||||
bottomAppBar.setOnTouchListener { v, event ->
|
||||
Log.d("Main", "Y: ${event.y}, Raw Y: ${event.rawY}")
|
||||
event.setLocation(event.rawX, event.rawY)
|
||||
nestedScrollView.dispatchTouchEvent(event)
|
||||
statusBarColor.setOnCheckedChangeListener { _, checkedId ->
|
||||
getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().putString("statusBarColor",
|
||||
when (checkedId) {
|
||||
R.id.colorPrimaryDark -> "colorPrimaryDark"
|
||||
R.id.colorPrimary -> "colorPrimary"
|
||||
R.id.colorAccent -> "colorAccent"
|
||||
R.id.colorBackground -> "colorBackground"
|
||||
else -> "colorBackground"
|
||||
}).commit()
|
||||
recreate()
|
||||
}
|
||||
statusBarFallbackLight.setOnCheckedChangeListener { _, checkedId ->
|
||||
getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().putString("statusBarFallbackLight",
|
||||
when (checkedId) {
|
||||
R.id.lightHalfTransparent -> "lightHalfTransparent"
|
||||
R.id.lightPrimaryDark -> "lightPrimaryDark"
|
||||
R.id.lightDoNotChange -> "lightDoNotChange"
|
||||
else -> "lightHalfTransparent"
|
||||
}).commit()
|
||||
recreate()
|
||||
}
|
||||
statusBarFallbackGradient.setOnCheckedChangeListener { _, checkedId ->
|
||||
getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().putString("statusBarFallbackGradient",
|
||||
when (checkedId) {
|
||||
R.id.gradientHalfTransparent -> "gradientHalfTransparent"
|
||||
R.id.gradientPrimaryDark -> "gradientPrimaryDark"
|
||||
R.id.gradientDoNotChange -> "gradientDoNotChange"
|
||||
else -> "gradientDoNotChange"
|
||||
}).commit()
|
||||
recreate()
|
||||
}
|
||||
|
||||
bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
navView.enableBottomSheetDrag = true
|
||||
navView.enableBottomSheet = true
|
||||
|
||||
}
|
||||
switchToolbar.setOnCheckedChangeListener { _, isChecked ->
|
||||
navView.showToolbar = isChecked
|
||||
}
|
||||
switchBottomAppBar.setOnCheckedChangeListener { _, isChecked ->
|
||||
navView.bottomBarEnable = isChecked
|
||||
}
|
||||
switchFab.setOnCheckedChangeListener { _, isChecked ->
|
||||
navView.bottomBar.fabEnable = isChecked
|
||||
}
|
||||
extendFab.setOnCheckedChangeListener { _, isChecked ->
|
||||
navView.bottomBar.fabExtended = isChecked
|
||||
}
|
||||
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
when (newState) {
|
||||
BottomSheetBehavior.STATE_HIDDEN -> {
|
||||
if (showing) {
|
||||
showing = false
|
||||
Anim.fadeOut(dim, 300, null)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
if (!showing) {
|
||||
showing = true
|
||||
Anim.fadeIn(dim, 300, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
//Toast.makeText(this@MainActivity, "Bottom Sheet State Changed to: $state", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})*/
|
||||
navView.setFabOnClickListener(View.OnClickListener {
|
||||
Toast.makeText(this, "FAB clicked", Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
|
||||
scrimClose.setOnCheckedChangeListener { _, isChecked ->
|
||||
navView.bottomSheet.scrimViewTapToClose = isChecked
|
||||
}
|
||||
|
||||
scrimEnable.setOnCheckedChangeListener {_, isChecked ->
|
||||
navView.bottomSheet.scrimViewEnabled = isChecked
|
||||
}
|
||||
|
||||
fabPosition.setOnCheckedChangeListener { _, checkedId ->
|
||||
navView.bottomBar.fabGravity = if (checkedId == R.id.fabCenter) Gravity.CENTER else Gravity.END
|
||||
}
|
||||
|
||||
extendable.setOnCheckedChangeListener { _, isChecked ->
|
||||
navView.bottomBar.fabExtendable = isChecked
|
||||
}
|
||||
|
||||
bsEnable.setOnCheckedChangeListener {_, isChecked ->
|
||||
navView.bottomSheet.enable = isChecked
|
||||
}
|
||||
bsDrag.setOnCheckedChangeListener {_, isChecked ->
|
||||
navView.bottomSheet.enableDragToOpen = isChecked
|
||||
}
|
||||
|
||||
navView.bottomBar.fabExtendedText = "Compose"
|
||||
navView.bottomBar.fabExtended = false
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
package pl.szczodrzynski.navigation
|
||||
|
||||
import android.app.Dialog
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
|
||||
class ThemeInfoBottomSheetDialog : BottomSheetDialogFragment() {
|
||||
|
||||
|
||||
override fun setupDialog(dialog: Dialog, style: Int) {
|
||||
val view = LayoutInflater.from(requireContext()).inflate(R.layout.bottom_sheet_fragment_theme_info, null)
|
||||
setupViews(view)
|
||||
dialog.setContentView(view)
|
||||
}
|
||||
|
||||
private fun setupViews(view: View) {
|
||||
|
||||
}
|
||||
|
||||
fun showIfNeed(fragmentManager: FragmentManager) {
|
||||
if (fragmentManager.findFragmentByTag(TAG) != null) {
|
||||
return
|
||||
}
|
||||
show(fragmentManager, TAG)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ThemeInfoBottomSheetDialog"
|
||||
|
||||
fun newInstance(): ThemeInfoBottomSheetDialog = ThemeInfoBottomSheetDialog()
|
||||
}
|
||||
}
|
@ -5,58 +5,303 @@
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<pl.szczodrzynski.navlib.NavView
|
||||
android:id="@+id/navView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:text="booton" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/switch1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Switch" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar2"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="@style/Widget.MaterialComponents.CardView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp">
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iconImageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:contentDescription="Card Icon"
|
||||
app:tint="?attr/colorOnSurface" />
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:text="Switch theme" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/titleTextView"
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="?attr/textAppearanceHeadline6"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
tools:text="Title" />
|
||||
android:text="NavView config"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/switchToolbar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="Toolbar" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/switchBottomAppBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="Bottom app bar" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/switchFab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="FAB" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/extendable"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="FAB extendable" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/extendFab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="FAB extended" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="FAB config"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/fabPosition"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/fabCenter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="true"
|
||||
android:text="FAB center" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/fabEnd"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="FAB end" />
|
||||
</RadioGroup>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="BottomSheet config"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/bsEnable"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="Enable Bottom sheet" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/bsDrag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="Enable BS drag to open" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/scrimEnable"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="Enable ScrimView" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/scrimClose"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="ScrimView on click close" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView6"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="System bars config"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/appFullscreen"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="App is fullscreen" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Status bar color"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="5.0+ with dark SB color, 6.0+" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/statusBarColor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/colorPrimaryDark"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="false"
|
||||
android:text="COLOR_PRIMARY_DARK" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/colorPrimary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="false"
|
||||
android:text="\?colorPrimary" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/colorAccent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="false"
|
||||
android:text="\?colorAccent" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/colorBackground"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="true"
|
||||
android:text="\?colorBackground" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/statusBarDarker"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="Status bar darker" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Status bar fallback if light"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="5.0 with SB color white, TouchWiz 4.1-4.3" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/statusBarFallbackLight"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/lightHalfTransparent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="true"
|
||||
android:text="COLOR_HALF_TRANSPARENT" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/lightPrimaryDark"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="false"
|
||||
android:text="COLOR_PRIMARY_DARK" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/lightDoNotChange"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="false"
|
||||
android:text="COLOR_DO_NOT_CHANGE" />
|
||||
</RadioGroup>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Status bar fallback if gradient"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="4.4, 5.0 Huawei" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/statusBarFallbackGradient"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/gradientHalfTransparent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="false"
|
||||
android:text="COLOR_HALF_TRANSPARENT" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/gradientPrimaryDark"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="false"
|
||||
android:text="COLOR_PRIMARY_DARK" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/gradientDoNotChange"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:checked="true"
|
||||
android:text="COLOR_DO_NOT_CHANGE" />
|
||||
</RadioGroup>
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/statusBarTranslucent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="SB color mode - translucent (not transparent)" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/navigationBarTransparent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="Nav bar fully transparent" />
|
||||
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</pl.szczodrzynski.navlib.NavView>
|
||||
|
||||
|
@ -1,26 +1,34 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<style name="AppTheme.Widget" />
|
||||
|
||||
<style name="AppTheme.Widget.ExtendedFloatingActionButton" parent="Widget.MaterialComponents.ExtendedFloatingActionButton">
|
||||
<item name="android:textColor">?colorOnSecondary</item>
|
||||
<item name="android:iconTint" tools:targetApi="o">?colorSecondaryVariant</item>
|
||||
<item name="iconTint">?colorSecondaryVariant</item>
|
||||
</style>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="NavView">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">#64b5f6</item>
|
||||
<item name="colorPrimaryDark">#1976d2</item>
|
||||
<item name="colorPrimaryVariant">#1976d2</item>
|
||||
<item name="colorAccent">#ff6e40</item>
|
||||
<item name="colorSecondary">#ff6e40</item>
|
||||
<item name="colorSecondaryVariant">#ff3d00</item>
|
||||
<item name="colorPrimaryVariant">#2196f3</item>
|
||||
<item name="colorAccent">#ffb300</item>
|
||||
<item name="colorSecondary">?colorAccent</item>
|
||||
<item name="colorSecondaryVariant">#fff59d</item>
|
||||
<item name="android:colorBackground">@color/black</item>
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
<item name="colorSurface">#1f1f1f</item>
|
||||
|
||||
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
|
||||
<!--<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
|
||||
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">false</item>
|
||||
|
||||
<item name="android:navigationBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
|
||||
<item name="android:windowTranslucentNavigation" tools:targetApi="kitkat">false</item>
|
||||
<!–<item name="android:navigationBarColor" tools:targetApi="lollipop">@android:color/transparent</item>–>
|
||||
<item name="android:windowTranslucentNavigation" tools:targetApi="kitkat">true</item>-->
|
||||
|
||||
<item name="colorOnPrimary">#000000</item>
|
||||
<item name="colorOnSecondary">#000000</item>
|
||||
<item name="colorOnPrimary">#ffffff</item>
|
||||
<item name="colorOnSecondary">#ffffff</item>
|
||||
<item name="colorOnBackground">#ffffff</item>
|
||||
<item name="colorOnSurface">#ffffff</item>
|
||||
|
||||
@ -28,35 +36,37 @@
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
|
||||
|
||||
<item name="extendedFloatingActionButtonStyle">@style/AppTheme.Widget.ExtendedFloatingActionButton</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.Light" parent="NavView.Light">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">#2196f3</item>
|
||||
<item name="colorPrimaryDark">#1976d2</item>
|
||||
<item name="colorPrimaryVariant">#90caf9</item>
|
||||
<item name="colorAccent">#ff6e40</item>
|
||||
<item name="colorSecondary">#ff6e40</item>
|
||||
<item name="colorSecondaryVariant">#ff3d00</item>
|
||||
<item name="colorPrimaryVariant">#2196f3</item>
|
||||
<item name="colorAccent">#ffb300</item>
|
||||
<item name="colorSecondary">?colorAccent</item>
|
||||
<item name="colorSecondaryVariant">#fff59d</item>
|
||||
<item name="android:colorBackground">@color/white</item>
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
<item name="colorSurface">#ffffff</item>
|
||||
|
||||
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
|
||||
<!--<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
|
||||
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">false</item>
|
||||
|
||||
<item name="android:navigationBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
|
||||
<item name="android:windowTranslucentNavigation" tools:targetApi="kitkat">false</item>
|
||||
<!–<item name="android:navigationBarColor" tools:targetApi="lollipop">@android:color/transparent</item>–>
|
||||
<item name="android:windowTranslucentNavigation" tools:targetApi="kitkat">true</item>-->
|
||||
|
||||
<item name="colorOnPrimary">#000000</item>
|
||||
<item name="colorOnSecondary">#000000</item>
|
||||
<item name="colorOnPrimary">#ffffff</item>
|
||||
<item name="colorOnSecondary">#ffffff</item>
|
||||
<item name="colorOnBackground">#000000</item>
|
||||
<item name="colorOnSurface">#000000</item>
|
||||
|
||||
<item name="nv_actionBarBackground">?colorSurface</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
|
||||
<item name="extendedFloatingActionButtonStyle">@style/AppTheme.Widget.ExtendedFloatingActionButton</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@ -6,11 +6,11 @@ buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0-rc03'
|
||||
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
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
@ -20,7 +20,7 @@ allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,9 +36,9 @@ ext {
|
||||
androidXCardView = '1.0.0'
|
||||
androidXGridLayout = '1.0.0'
|
||||
androidXConstraintLayout = '1.1.3'
|
||||
googleMaterial = '1.1.0-alpha07'
|
||||
googleMaterial = '1.1.0-alpha09'
|
||||
|
||||
iconics = '3.2.5'
|
||||
iconics = '4.0.1-b01'
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
@ -23,6 +24,13 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
dataBinding {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'META-INF/library-core_release.kotlin_module'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -32,4 +40,14 @@ dependencies {
|
||||
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:6.1.2"
|
||||
implementation "com.mikepenz:iconics-core:4.0.1-b01"
|
||||
implementation 'com.mikepenz:community-material-typeface:3.5.95.1-kotlin@aar'
|
||||
|
||||
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}"
|
||||
}
|
||||
|
2
navlib/proguard-rules.pro
vendored
2
navlib/proguard-rules.pro
vendored
@ -1,6 +1,6 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
# proguardFiles setting in init.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
177
navlib/src/main/java/pl/szczodrzynski/navlib/NavBottomBar.kt
Normal file
177
navlib/src/main/java/pl/szczodrzynski/navlib/NavBottomBar.kt
Normal file
@ -0,0 +1,177 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.content.Context
|
||||
import android.system.Os.close
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import com.google.android.material.bottomappbar.BottomAppBar
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import com.mikepenz.materialdrawer.Drawer
|
||||
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
|
||||
|
||||
class NavBottomBar : BottomAppBar {
|
||||
constructor(context: Context) : super(context) {
|
||||
create(null, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
create(attrs, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
|
||||
create(attrs, defStyle)
|
||||
}
|
||||
|
||||
var drawer: Drawer? = null
|
||||
var bottomSheet: NavBottomSheet? = null
|
||||
var fabView: FloatingActionButton? = null
|
||||
var fabExtendedView: ExtendedFloatingActionButton? = null
|
||||
|
||||
/**
|
||||
* Shows the BottomAppBar and sets the contentView's margin to be
|
||||
* above the BottomAppBar.
|
||||
*/
|
||||
var enable = true
|
||||
set(value) {
|
||||
field = value
|
||||
visibility = if (value) View.VISIBLE else View.GONE
|
||||
setFabParams()
|
||||
}
|
||||
/**
|
||||
* Whether the FAB should be visible.
|
||||
*/
|
||||
var fabEnable = true
|
||||
set(value) {
|
||||
field = value
|
||||
setFabVisibility()
|
||||
}
|
||||
/**
|
||||
* Whether an ExtendableFloatingActionButton should be used
|
||||
* instead of a normal FloatingActionButton.
|
||||
* Note that the extendable button does not support end alignment/gravity
|
||||
* when used together with the bottom app bar.
|
||||
*/
|
||||
var fabExtendable = true
|
||||
set(value) {
|
||||
field = value
|
||||
setFabParams()
|
||||
}
|
||||
/**
|
||||
* If BottomAppBar is enabled, sets its fabAlignmentMode.
|
||||
* Else, sets the actual FAB's gravity.
|
||||
*/
|
||||
var fabGravity = Gravity.CENTER
|
||||
set(value) {
|
||||
field = value
|
||||
setFabParams()
|
||||
}
|
||||
/**
|
||||
* Whether the FAB should be extended and its text visible.
|
||||
*/
|
||||
var fabExtended = false
|
||||
set(value) {
|
||||
field = value
|
||||
if (fabExtended)
|
||||
fabExtendedView?.extend()
|
||||
else
|
||||
fabExtendedView?.shrink()
|
||||
}
|
||||
/**
|
||||
* Set the ExtendedFAB's text.
|
||||
*/
|
||||
var fabExtendedText
|
||||
get() = fabExtendedView?.text
|
||||
set(value) {
|
||||
fabExtendedView?.text = value
|
||||
}
|
||||
|
||||
private fun create(attrs: AttributeSet?, defStyle: Int) {
|
||||
setOnTouchListener { _, event ->
|
||||
if (bottomSheet?.enable != true || bottomSheet?.enableDragToOpen != true)
|
||||
return@setOnTouchListener false
|
||||
bottomSheet?.dispatchBottomBarEvent(event)
|
||||
true
|
||||
}
|
||||
|
||||
navigationIcon = IconicsDrawable(context)
|
||||
.icon(CommunityMaterial.Icon2.cmd_menu)
|
||||
.sizeDp(20)
|
||||
.colorInt(getColorFromAttr(context, R.attr.colorOnPrimary))
|
||||
|
||||
menu.add(0, -1, 0, "Menu")
|
||||
.setIcon(
|
||||
IconicsDrawable(context)
|
||||
.icon(CommunityMaterial.Icon.cmd_dots_vertical)
|
||||
.sizeDp(20)
|
||||
.colorInt(getColorFromAttr(context, R.attr.colorOnPrimary)))
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
|
||||
setNavigationOnClickListener {
|
||||
if (drawer?.isDrawerOpen == true)
|
||||
drawer?.closeDrawer()
|
||||
else
|
||||
drawer?.openDrawer()
|
||||
}
|
||||
|
||||
super.setOnMenuItemClickListener {
|
||||
if (it.itemId == -1 && bottomSheet?.enable == true) {
|
||||
bottomSheet?.toggle()
|
||||
}
|
||||
else {
|
||||
onMenuItemClickListener?.onMenuItemClick(it)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private fun setFabParams() {
|
||||
val layoutParams =
|
||||
((if (fabExtendable) fabExtendedView?.layoutParams else fabView?.layoutParams) ?: return) as CoordinatorLayout.LayoutParams
|
||||
|
||||
if (enable) {
|
||||
layoutParams.anchorId = this.id
|
||||
if (fabExtendable)
|
||||
layoutParams.anchorGravity = if (fabExtendable) fabGravity or Gravity.TOP else Gravity.NO_GRAVITY
|
||||
layoutParams.gravity = Gravity.NO_GRAVITY
|
||||
}
|
||||
else {
|
||||
layoutParams.anchorId = View.NO_ID
|
||||
if (fabExtendable)
|
||||
layoutParams.anchorGravity = Gravity.NO_GRAVITY
|
||||
layoutParams.gravity = fabGravity or Gravity.BOTTOM
|
||||
}
|
||||
fabAlignmentMode = if (fabGravity == Gravity.END) FAB_ALIGNMENT_MODE_END else FAB_ALIGNMENT_MODE_CENTER
|
||||
if (fabExtendable)
|
||||
fabExtendedView?.layoutParams = layoutParams
|
||||
else
|
||||
fabView?.layoutParams = layoutParams
|
||||
setFabVisibility()
|
||||
}
|
||||
private fun setFabVisibility() {
|
||||
if (fabEnable && fabExtendable) {
|
||||
fabView?.hide()
|
||||
fabExtendedView?.show()
|
||||
}
|
||||
else if (fabEnable) {
|
||||
fabView?.show()
|
||||
fabExtendedView?.hide()
|
||||
}
|
||||
else {
|
||||
fabView?.hide()
|
||||
fabExtendedView?.hide()
|
||||
}
|
||||
}
|
||||
|
||||
private var onMenuItemClickListener: OnMenuItemClickListener? = null
|
||||
override fun setOnMenuItemClickListener(listener: OnMenuItemClickListener?) {
|
||||
onMenuItemClickListener = listener
|
||||
}
|
||||
}
|
23
navlib/src/main/java/pl/szczodrzynski/navlib/NavToolbar.kt
Normal file
23
navlib/src/main/java/pl/szczodrzynski/navlib/NavToolbar.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
|
||||
class NavToolbar : MaterialToolbar {
|
||||
constructor(context: Context) : super(context) {
|
||||
create(null, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
create(attrs, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
|
||||
create(attrs, defStyle)
|
||||
}
|
||||
|
||||
private fun create(attrs: AttributeSet?, defStyle: Int) {
|
||||
|
||||
}
|
||||
}
|
@ -1,86 +1,55 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.SeekBar
|
||||
import android.widget.*
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.*
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import com.google.android.material.bottomappbar.BottomAppBar
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mikepenz.materialdrawer.Drawer
|
||||
import com.mikepenz.materialdrawer.DrawerBuilder
|
||||
import com.mikepenz.materialdrawer.model.DividerDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
|
||||
import kotlinx.android.synthetic.main.nav_view.view.*
|
||||
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
|
||||
|
||||
class NavView : FrameLayout {
|
||||
|
||||
private var contentView: LinearLayout? = null
|
||||
private lateinit var bottomAppBar: BottomAppBar
|
||||
|
||||
private lateinit var statusBarBackground: View
|
||||
private lateinit var navigationBarBackground: View
|
||||
private lateinit var mainView: CoordinatorLayout
|
||||
private lateinit var floatingActionButton: FloatingActionButton
|
||||
private lateinit var scrimView: View
|
||||
private lateinit var bottomSheet: NestedScrollView
|
||||
private lateinit var bottomSheetBehavior: BottomSheetBehavior<View>
|
||||
private var bottomSheetVisible = false
|
||||
private lateinit var extendedFloatingActionButton: ExtendedFloatingActionButton
|
||||
|
||||
var drawer: Drawer? = null
|
||||
lateinit var topBar: NavToolbar
|
||||
lateinit var bottomBar: NavBottomBar
|
||||
lateinit var bottomSheet: NavBottomSheet
|
||||
|
||||
private val displayMetrics by lazy {
|
||||
context.resources.displayMetrics
|
||||
}
|
||||
private val configuration by lazy { context.resources.configuration }
|
||||
private val displayWidth: Int by lazy { configuration.screenWidthDp }
|
||||
private val displayHeight: Int by lazy { configuration.screenHeightDp }
|
||||
|
||||
fun getTopInset(view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetTop ?: 24)
|
||||
} else {
|
||||
24
|
||||
}*displayMetrics.density
|
||||
}
|
||||
fun getLeftInset(view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetLeft ?: 0)
|
||||
} else {
|
||||
0
|
||||
} * displayMetrics.density
|
||||
}
|
||||
fun getRightInset(view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetRight ?: 0)
|
||||
} else {
|
||||
0
|
||||
} * displayMetrics.density
|
||||
}
|
||||
fun getBottomInset(view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetBottom ?: 48)
|
||||
} else {
|
||||
48
|
||||
} * displayMetrics.density
|
||||
}
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
init(null, 0)
|
||||
create(null, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
init(attrs, 0)
|
||||
create(attrs, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
|
||||
init(attrs, defStyle)
|
||||
create(attrs, defStyle)
|
||||
}
|
||||
|
||||
private fun init(attrs: AttributeSet?, defStyle: Int) {
|
||||
private fun create(attrs: AttributeSet?, defStyle: Int) {
|
||||
// Load attributes
|
||||
val a = context.obtainStyledAttributes(attrs, R.styleable.NavView, defStyle, 0)
|
||||
/*_exampleString = a.getString(
|
||||
@ -93,78 +62,117 @@ class NavView : FrameLayout {
|
||||
|
||||
contentView = findViewById<LinearLayout>(R.id.nv_content)
|
||||
|
||||
//findViewById<TextView>(R.id.textView).text = "${displayWidth}dp x ${displayHeight}dp"
|
||||
|
||||
// TODO add vars for status/navigation bar background
|
||||
|
||||
bottomAppBar = findViewById(R.id.nv_bottomAppBar)
|
||||
statusBarBackground = findViewById(R.id.nv_statusBarBackground)
|
||||
navigationBarBackground = findViewById(R.id.nv_navigationBarBackground)
|
||||
mainView = findViewById(R.id.nv_main)
|
||||
floatingActionButton = findViewById(R.id.nv_floatingActionButton)
|
||||
scrimView = findViewById(R.id.nv_scrim)
|
||||
extendedFloatingActionButton = findViewById(R.id.nv_extendedFloatingActionButton)
|
||||
|
||||
topBar = findViewById(R.id.nv_toolbar)
|
||||
bottomBar = findViewById(R.id.nv_bottomBar)
|
||||
bottomSheet = findViewById(R.id.nv_bottomSheet)
|
||||
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
|
||||
|
||||
bottomSheetBehavior.state = STATE_HIDDEN
|
||||
bottomSheetBehavior.peekHeight = displayHeight
|
||||
bottomBar.drawer = drawer
|
||||
bottomBar.bottomSheet = bottomSheet
|
||||
bottomBar.fabView = floatingActionButton
|
||||
bottomBar.fabExtendedView = extendedFloatingActionButton
|
||||
|
||||
nv_main.setPadding(
|
||||
getLeftInset(nv_main).toInt(),
|
||||
getTopInset(nv_main).toInt(),
|
||||
getRightInset(nv_main).toInt(),
|
||||
getBottomInset(nv_main).toInt()
|
||||
)
|
||||
nv_statusBarBackground.layoutParams.height = getTopInset(nv_main).toInt()
|
||||
nv_navigationBarBackground.layoutParams.height = getBottomInset(nv_main).toInt()
|
||||
|
||||
|
||||
bottomAppBar.setOnTouchListener { v, event ->
|
||||
val location = IntArray(2)
|
||||
bottomSheet.getLocationOnScreen(location)
|
||||
event.setLocation(event.rawX - location[0], event.rawY - location[1])
|
||||
bottomSheet.dispatchTouchEvent(event)
|
||||
true
|
||||
}
|
||||
|
||||
scrimView.setOnTouchListener { v, event ->
|
||||
if (event.action == MotionEvent.ACTION_UP && bottomSheetBehavior.state != STATE_HIDDEN) {
|
||||
bottomSheetBehavior.state = STATE_HIDDEN
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(v: View, p1: Float) {}
|
||||
override fun onStateChanged(v: View, newState: Int) {
|
||||
if (newState == STATE_HIDDEN && bottomSheetVisible) {
|
||||
bottomSheetVisible = false
|
||||
Anim.fadeOut(scrimView, 300, null)
|
||||
bottomSheet.scrollTo(0, 0)
|
||||
}
|
||||
else if (!bottomSheetVisible) {
|
||||
bottomSheetVisible = true
|
||||
Anim.fadeIn(scrimView, 300, null)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
floatingActionButton.setOnClickListener {
|
||||
if (bottomSheetBehavior.state == STATE_HIDDEN) {
|
||||
bottomSheetBehavior.state = STATE_COLLAPSED
|
||||
}
|
||||
else {
|
||||
bottomSheetBehavior.state = STATE_HIDDEN
|
||||
}
|
||||
}
|
||||
//bottomSheetBehavior.peekHeight = displayHeight
|
||||
|
||||
nv_elevation.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
|
||||
textView.text = "Set toolbar elevation ${progress}dp"
|
||||
nv_toolbar.elevation = progress * displayMetrics.density
|
||||
nv_toolbar.elevation = progress * context.resources.displayMetrics.density
|
||||
}
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
|
||||
})
|
||||
}
|
||||
|
||||
fun configSystemBarsUtil(systemBarsUtil: SystemBarsUtil) {
|
||||
systemBarsUtil.statusBarBgView = statusBarBackground
|
||||
systemBarsUtil.navigationBarBgView = navigationBarBackground
|
||||
systemBarsUtil.statusBarDarkView = nv_statusBarDarker
|
||||
//systemBarsUtil.navigationBarDarkView = navigationBarBackground
|
||||
systemBarsUtil.paddingBySystemBars = mainView
|
||||
systemBarsUtil.paddingByNavigationBar = bottomSheet.getContentView()
|
||||
}
|
||||
|
||||
|
||||
var enableBottomSheet = true
|
||||
var enableBottomSheetDrag = true
|
||||
|
||||
var bottomBarEnable = true
|
||||
get() = bottomBar.enable
|
||||
set(value) {
|
||||
field = value
|
||||
bottomBar.enable = value
|
||||
setContentMargins() // TODO combine bottomBarEnable and bottomBar.enable
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the toolbar and sets the contentView's margin to be
|
||||
* below the toolbar.
|
||||
*/
|
||||
var showToolbar = true; set(value) {
|
||||
topBar.visibility = if (value) View.VISIBLE else View.GONE
|
||||
field = value
|
||||
setContentMargins()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the FAB's on click listener
|
||||
*/
|
||||
fun setFabOnClickListener(onClickListener: OnClickListener) {
|
||||
floatingActionButton.setOnClickListener(onClickListener)
|
||||
extendedFloatingActionButton.setOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
fun init(activity: Activity) {
|
||||
|
||||
}
|
||||
|
||||
private fun setContentMargins() {
|
||||
val layoutParams = CoordinatorLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||
val actionBarSize = 56 * context.resources.displayMetrics.density
|
||||
layoutParams.topMargin = if (showToolbar) actionBarSize.toInt() else 0
|
||||
layoutParams.bottomMargin = if (bottomBarEnable) actionBarSize.toInt() else 0
|
||||
contentView?.layoutParams = layoutParams
|
||||
}
|
||||
|
||||
fun addDrawer(activity: Activity) {
|
||||
//if you want to update the items at a later time it is recommended to keep it in a variable
|
||||
val item1 = PrimaryDrawerItem().withIdentifier(1).withName("Home")
|
||||
val item2 = SecondaryDrawerItem().withIdentifier(2).withName("Settings")
|
||||
|
||||
drawer = DrawerBuilder(activity)
|
||||
.withDrawerLayout(R.layout.material_drawer_fits_not)
|
||||
.withRootView(R.id.nv_drawerContainer)
|
||||
.withFullscreen(true)
|
||||
.withTranslucentStatusBar(false)
|
||||
.withTranslucentNavigationBar(false)
|
||||
.withTranslucentNavigationBarProgrammatically(false)
|
||||
.withToolbar(topBar)
|
||||
.withDisplayBelowStatusBar(true)
|
||||
.withActionBarDrawerToggleAnimated(true)
|
||||
.addDrawerItems(
|
||||
item1,
|
||||
DividerDrawerItem(),
|
||||
item2,
|
||||
SecondaryDrawerItem().withName("Settings")
|
||||
)
|
||||
.withOnDrawerItemClickListener { view, position, drawerItem ->
|
||||
true
|
||||
}
|
||||
.build()
|
||||
|
||||
bottomBar.drawer = drawer
|
||||
}
|
||||
|
||||
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
|
||||
if (contentView == null) {
|
||||
super.addView(child, index, params)
|
||||
|
369
navlib/src/main/java/pl/szczodrzynski/navlib/SystemBarsUtil.kt
Normal file
369
navlib/src/main/java/pl/szczodrzynski/navlib/SystemBarsUtil.kt
Normal file
@ -0,0 +1,369 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.res.Configuration.ORIENTATION_PORTRAIT
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.os.Build.VERSION_CODES.*
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.view.View.*
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.mikepenz.materialize.util.KeyboardUtil
|
||||
|
||||
class SystemBarsUtil(val activity: Activity) {
|
||||
companion object {
|
||||
private const val COLOR_TRANSPARENT = Color.TRANSPARENT
|
||||
/**
|
||||
* A fallback color.
|
||||
* Tells to apply a #22000000 overlay over the status/nav bar color.
|
||||
* This has the same effect as [statusBarDarker].
|
||||
*/
|
||||
const val COLOR_HALF_TRANSPARENT = -1
|
||||
/**
|
||||
* Use ?colorPrimaryDark as a fallback or status bar color.
|
||||
*/
|
||||
const val COLOR_PRIMARY_DARK = -2
|
||||
/**
|
||||
* A fallback color.
|
||||
* Not recommended to use as [statusBarFallbackLight] because it will make status bar
|
||||
* icons almost invisible.
|
||||
*/
|
||||
const val COLOR_DO_NOT_CHANGE = -3
|
||||
|
||||
private const val COLOR_DARK_OVERLAY = 0x22000000
|
||||
|
||||
private const val TARGET_MODE_NORMAL = 0
|
||||
private const val TARGET_MODE_LIGHT = 1
|
||||
private const val TARGET_MODE_GRADIENT = 2
|
||||
}
|
||||
|
||||
val window: Window by lazy {
|
||||
activity.window
|
||||
}
|
||||
val resources: Resources by lazy {
|
||||
activity.resources
|
||||
}
|
||||
|
||||
/**
|
||||
* A view which will have the padding added when the soft input keyboard appears.
|
||||
*/
|
||||
var paddingByKeyboard: View? = null
|
||||
/**
|
||||
* Whether the app should be fullscreen.
|
||||
*
|
||||
* This means it will display under the system bars
|
||||
* and you should probably provide [statusBarBgView],
|
||||
* [navigationBarBgView] and [paddingBySystemBars].
|
||||
*/
|
||||
var appFullscreen = false
|
||||
|
||||
/**
|
||||
* Define the color used to tint the status bar background.
|
||||
*
|
||||
* Valid values are [COLOR_PRIMARY_DARK] or a color integer.
|
||||
*
|
||||
* You cannot use neither [COLOR_HALF_TRANSPARENT] nor [COLOR_DO_NOT_CHANGE] here.
|
||||
* See [statusBarDarker].
|
||||
*/
|
||||
var statusBarColor = COLOR_PRIMARY_DARK
|
||||
/**
|
||||
* Whether the status bar should have a dark overlay (#22000000).
|
||||
*
|
||||
* Useful if the [statusBarColor] is set to a bright color and is the same as an action bar.
|
||||
* Not useful if [statusBarColor] is [COLOR_PRIMARY_DARK].
|
||||
*/
|
||||
var statusBarDarker = false
|
||||
/**
|
||||
* A fallback status bar color used on Android Lollipop
|
||||
* when the [statusBarColor] combined with [statusBarDarker] is
|
||||
* too bright not to blend with status bar icons (they cannot be
|
||||
* set to dark).
|
||||
*
|
||||
* This will (most likely) not be used when [statusBarDarker] is true.
|
||||
*
|
||||
* Valid values are [COLOR_HALF_TRANSPARENT], [COLOR_PRIMARY_DARK], [COLOR_DO_NOT_CHANGE].
|
||||
*/
|
||||
var statusBarFallbackLight = COLOR_HALF_TRANSPARENT
|
||||
/**
|
||||
* A fallback status bar color used on Android KitKat and older.
|
||||
* On these systems there is a black-to-transparent gradient as
|
||||
* the status bar background.
|
||||
*
|
||||
* Valid values are [COLOR_HALF_TRANSPARENT], [COLOR_PRIMARY_DARK], [COLOR_DO_NOT_CHANGE].
|
||||
*/
|
||||
var statusBarFallbackGradient = COLOR_DO_NOT_CHANGE
|
||||
|
||||
// TODO remove - test for huawei
|
||||
var statusBarTranslucent = false
|
||||
|
||||
/**
|
||||
* If false, the nav bar is mostly translucent but not completely transparent.
|
||||
*/
|
||||
var navigationBarTransparent = true
|
||||
|
||||
/**
|
||||
* A background view to be resized in order to fit under the status bar.
|
||||
*/
|
||||
var statusBarBgView: View? = null
|
||||
/**
|
||||
* A background view to be resized in order to fit under the nav bar.
|
||||
*/
|
||||
var navigationBarBgView: View? = null
|
||||
|
||||
/**
|
||||
* A dark, half-transparent view to be resized in order to fit under the status bar.
|
||||
*/
|
||||
var statusBarDarkView: View? = null
|
||||
/**
|
||||
* A dark, half-transparent view to be resized in order to fit under the nav bar.
|
||||
*/
|
||||
var navigationBarDarkView: View? = null
|
||||
|
||||
/**
|
||||
* A view which will have the padding added not to overlap with the status/nav bar.
|
||||
*/
|
||||
var paddingBySystemBars: View? = null
|
||||
/**
|
||||
* A view which will have the padding added not to overlap with the nav bar.
|
||||
* Useful for persistent bottom sheets.
|
||||
* Requires [paddingBySystemBars].
|
||||
*/
|
||||
var paddingByNavigationBar: View? = null
|
||||
|
||||
private var keyboardUtil: KeyboardUtil? = null
|
||||
private var insetsApplied = false
|
||||
|
||||
fun commit() {
|
||||
if (paddingByKeyboard != null) {
|
||||
// thanks mikepenz for this life-saving class
|
||||
keyboardUtil = KeyboardUtil(activity, paddingByKeyboard)
|
||||
keyboardUtil?.enable()
|
||||
}
|
||||
|
||||
// get the correct target SB color
|
||||
var targetStatusBarColor = statusBarColor
|
||||
if (targetStatusBarColor == COLOR_PRIMARY_DARK)
|
||||
targetStatusBarColor = getColorFromAttr(activity, R.attr.colorPrimaryDark)
|
||||
|
||||
var targetStatusBarDarker = statusBarDarker
|
||||
|
||||
// fallback if the SB color is too light for the icons to be visible
|
||||
// applicable on Lollipop 5.0 and TouchWiz 4.1-4.3
|
||||
var targetStatusBarFallbackLight = statusBarFallbackLight
|
||||
if (targetStatusBarFallbackLight == COLOR_PRIMARY_DARK)
|
||||
targetStatusBarFallbackLight = getColorFromAttr(activity, R.attr.colorPrimaryDark)
|
||||
|
||||
// fallback if there is a gradient under the status bar
|
||||
// applicable on AOSP/similar 4.4 and Huawei EMUI Lollipop
|
||||
// TODO check huawei 6.0+ for gradient bars, check huawei 4.4
|
||||
var targetStatusBarFallbackGradient = statusBarFallbackGradient
|
||||
if (targetStatusBarFallbackGradient == COLOR_PRIMARY_DARK)
|
||||
targetStatusBarFallbackGradient = getColorFromAttr(activity, R.attr.colorPrimaryDark)
|
||||
|
||||
// determines the target mode that will be applied
|
||||
var targetStatusBarMode = TARGET_MODE_NORMAL
|
||||
|
||||
val targetStatusBarLight = ColorUtils.calculateLuminance(targetStatusBarColor) > 0.75 && !targetStatusBarDarker
|
||||
|
||||
if (appFullscreen) {
|
||||
window.decorView.systemUiVisibility = 0
|
||||
// API 19+ (KitKat 4.4+) - make the app fullscreen.
|
||||
// On lower APIs this is useless because
|
||||
// #1 the status/nav bar cannot be transparent (except Samsung TouchWiz)
|
||||
// #2 tablets do not report status/nav bar height correctly
|
||||
// #3 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the activity not resize when keyboard is open
|
||||
// Samsung TouchWiz - app will go fullscreen. There is a problem though, see #3.
|
||||
var targetAppFullscreen = false
|
||||
if (SDK_INT >= KITKAT) {
|
||||
targetAppFullscreen = true
|
||||
}
|
||||
|
||||
|
||||
if (SDK_INT in KITKAT until LOLLIPOP) {
|
||||
// API 19-20 (KitKat 4.4) - set gradient status bar
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
||||
// take FallbackGradient color
|
||||
targetStatusBarMode = TARGET_MODE_GRADIENT
|
||||
// disable darker even if [statusBarDarker] == true BUT gradient fallback is not COLOR_HALF_TRANSPARENT
|
||||
//targetStatusBarDarker = targetStatusBarDarker && targetStatusBarFallbackGradient == COLOR_HALF_TRANSPARENT
|
||||
}
|
||||
else if (SDK_INT >= LOLLIPOP) {
|
||||
// API 21+ (Lollipop 5.0+) - set transparent status bar
|
||||
if (statusBarTranslucent) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
||||
}
|
||||
else {
|
||||
window.statusBarColor = Color.TRANSPARENT
|
||||
}
|
||||
if (SDK_INT < M && targetStatusBarLight) {
|
||||
// take FallbackLight color
|
||||
targetStatusBarMode = TARGET_MODE_LIGHT
|
||||
}
|
||||
}
|
||||
if (SDK_INT >= M && targetStatusBarLight) {
|
||||
// API 23+ (Marshmallow 6.0+) - set the status bar icons to dark color if [statusBarLight] is true
|
||||
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
}
|
||||
// FOR SAMSUNG/SONY DEVICES (TouchWiz 4.1-4.3)
|
||||
if (SDK_INT < KITKAT) {
|
||||
val libs = activity.packageManager.systemSharedLibraryNames
|
||||
var reflect: String? = null
|
||||
// TODO galaxy s3 - opening keyboard does not resize activity if fullscreen
|
||||
if (libs != null) {
|
||||
for (lib in libs) {
|
||||
Log.d("SBU", lib)
|
||||
if (lib == "touchwiz")
|
||||
// SYSTEM_UI_FLAG_TRANSPARENT_BACKGROUND = 0x00001000
|
||||
reflect = "SYSTEM_UI_FLAG_TRANSPARENT_BACKGROUND"
|
||||
else if (lib.startsWith("com.sonyericsson.navigationbar"))
|
||||
reflect = "SYSTEM_UI_FLAG_TRANSPARENT"
|
||||
}
|
||||
if (reflect != null) {
|
||||
try {
|
||||
val field = View::class.java.getField(reflect)
|
||||
var flag = 0
|
||||
if (field.type === Integer.TYPE)
|
||||
flag = field.getInt(null)
|
||||
if (flag != 0) {
|
||||
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or flag
|
||||
targetStatusBarMode = TARGET_MODE_LIGHT /* or TARGET_MODE_GRADIENT */
|
||||
targetAppFullscreen = true
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO huawei detection for 5.0+
|
||||
|
||||
targetStatusBarColor = when (targetStatusBarMode) {
|
||||
TARGET_MODE_LIGHT -> when (targetStatusBarFallbackLight) {
|
||||
COLOR_DO_NOT_CHANGE -> targetStatusBarColor
|
||||
COLOR_HALF_TRANSPARENT -> {
|
||||
targetStatusBarDarker = true
|
||||
targetStatusBarColor
|
||||
}
|
||||
else -> targetStatusBarFallbackLight
|
||||
}
|
||||
TARGET_MODE_GRADIENT -> when (targetStatusBarFallbackGradient) {
|
||||
COLOR_DO_NOT_CHANGE -> {
|
||||
targetStatusBarDarker = false
|
||||
targetStatusBarColor
|
||||
}
|
||||
COLOR_HALF_TRANSPARENT -> {
|
||||
targetStatusBarDarker = true
|
||||
targetStatusBarColor
|
||||
}
|
||||
else -> {
|
||||
targetStatusBarDarker = false
|
||||
targetStatusBarFallbackGradient
|
||||
}
|
||||
}
|
||||
else -> targetStatusBarColor
|
||||
}
|
||||
|
||||
statusBarBgView?.setBackgroundColor(targetStatusBarColor)
|
||||
statusBarDarkView?.visibility = if (targetStatusBarDarker) VISIBLE else GONE
|
||||
|
||||
if (targetAppFullscreen) {
|
||||
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
}
|
||||
|
||||
// TODO navigation bar options like status bar
|
||||
// NAVIGATION BAR
|
||||
if (SDK_INT >= KITKAT && (SDK_INT < LOLLIPOP || !navigationBarTransparent)) {
|
||||
// API 19-20 (KitKat 4.4) - set gradient navigation bar
|
||||
// API 21+ (Lollipop 5.0+) - set half-transparent navigation bar if [navigationBarTransparent] is false
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
|
||||
}
|
||||
|
||||
if (SDK_INT >= LOLLIPOP && navigationBarTransparent) {
|
||||
// API 21+ (Lollipop 5.0+) - set fully transparent navigation bar if [navigationBarTransparent] is true
|
||||
window.navigationBarColor = Color.TRANSPARENT
|
||||
}
|
||||
|
||||
// PADDING
|
||||
if (paddingBySystemBars != null) {
|
||||
if (SDK_INT >= LOLLIPOP) {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(paddingBySystemBars!!) { _, insets ->
|
||||
if (insetsApplied)
|
||||
return@setOnApplyWindowInsetsListener insets.consumeSystemWindowInsets()
|
||||
insetsApplied = true
|
||||
applyPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
insets.systemWindowInsetTop,
|
||||
insets.systemWindowInsetRight,
|
||||
insets.systemWindowInsetBottom
|
||||
)
|
||||
insets.consumeSystemWindowInsets()
|
||||
}
|
||||
}
|
||||
else {
|
||||
var statusBarSize = 0
|
||||
val statusBarRes = resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||
if (statusBarRes > 0 && targetAppFullscreen) {
|
||||
statusBarSize = resources.getDimensionPixelSize(statusBarRes)
|
||||
}
|
||||
|
||||
|
||||
var navigationBarSize = 0
|
||||
val hasMenuKey = ViewConfiguration.get(activity).hasPermanentMenuKey()
|
||||
val hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK)
|
||||
if (!hasMenuKey && !hasBackKey && targetAppFullscreen) {
|
||||
val orientation = resources.configuration.orientation
|
||||
|
||||
val navigationBarRes = when {
|
||||
orientation == ORIENTATION_PORTRAIT ->
|
||||
resources.getIdentifier("navigation_bar_height", "dimen", "android")
|
||||
isTablet(activity) ->
|
||||
resources.getIdentifier("navigation_bar_height_landscape", "dimen", "android")
|
||||
else ->
|
||||
resources.getIdentifier("navigation_bar_width", "dimen", "android")
|
||||
}
|
||||
|
||||
if (navigationBarRes > 0) {
|
||||
navigationBarSize = resources.getDimensionPixelSize(navigationBarRes)
|
||||
}
|
||||
}
|
||||
|
||||
applyPadding(
|
||||
0,
|
||||
statusBarSize,
|
||||
0,
|
||||
navigationBarSize
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// app not fullscreen
|
||||
// TODO statusBarColor & navigationBarColor if not fullscreen (it's possible)
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||
paddingBySystemBars?.setPadding(left, top, right, bottom)
|
||||
|
||||
statusBarBgView?.layoutParams?.height = top
|
||||
navigationBarBgView?.layoutParams?.height = bottom
|
||||
|
||||
statusBarDarkView?.layoutParams?.height = top
|
||||
navigationBarDarkView?.layoutParams?.height = bottom
|
||||
|
||||
paddingByNavigationBar?.setPadding(
|
||||
(8 * resources.displayMetrics.density).toInt(),
|
||||
0,
|
||||
(8 * resources.displayMetrics.density).toInt(),
|
||||
bottom
|
||||
)
|
||||
}
|
||||
|
||||
fun destroy() {
|
||||
if (paddingByKeyboard != null) {
|
||||
keyboardUtil?.disable()
|
||||
}
|
||||
}
|
||||
}
|
81
navlib/src/main/java/pl/szczodrzynski/navlib/Utils.kt
Normal file
81
navlib/src/main/java/pl/szczodrzynski/navlib/Utils.kt
Normal file
@ -0,0 +1,81 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.core.graphics.ColorUtils
|
||||
|
||||
/*private val displayMetrics by lazy {
|
||||
context.resources.displayMetrics
|
||||
}*/
|
||||
/*private val configuration by lazy { context.resources.configuration }
|
||||
private val displayWidth: Int by lazy { configuration.screenWidthDp }
|
||||
private val displayHeight: Int by lazy { configuration.screenHeightDp }*/
|
||||
|
||||
fun getTopInset(context: Context, view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetTop ?: 24)
|
||||
} else {
|
||||
24
|
||||
} * context.resources.displayMetrics.density
|
||||
}
|
||||
fun getLeftInset(context: Context, view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetLeft ?: 0)
|
||||
} else {
|
||||
0
|
||||
} * context.resources.displayMetrics.density
|
||||
}
|
||||
fun getRightInset(context: Context, view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetRight ?: 0)
|
||||
} else {
|
||||
0
|
||||
} * context.resources.displayMetrics.density
|
||||
}
|
||||
fun getBottomInset(context: Context, view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetBottom ?: 48)
|
||||
} else {
|
||||
48
|
||||
} * 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
|
||||
}
|
||||
|
||||
fun blendColors(background: Int, foreground: Int): Int {
|
||||
val r1 = (background shr 16 and 0xff)
|
||||
val g1 = (background shr 8 and 0xff)
|
||||
val b1 = (background and 0xff)
|
||||
|
||||
val r2 = (foreground shr 16 and 0xff)
|
||||
val g2 = (foreground shr 8 and 0xff)
|
||||
val b2 = (foreground and 0xff)
|
||||
val a2 = (foreground shr 24 and 0xff)
|
||||
//ColorUtils.compositeColors()
|
||||
|
||||
val factor = a2.toFloat() / 255f
|
||||
val red = (r1 * (1 - factor) + r2 * factor)
|
||||
val green = (g1 * (1 - factor) + g2 * factor)
|
||||
val blue = (b1 * (1 - factor) + b2 * factor)
|
||||
|
||||
return (0xff000000 or (red.toLong() shl 16) or (green.toLong() shl 8) or (blue.toLong())).toInt()
|
||||
}
|
||||
|
||||
fun isTablet(c: Context): Boolean {
|
||||
return (c.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet
|
||||
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import pl.szczodrzynski.navlib.R
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.EditTextFilledItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.IBottomSheetItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.PrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.SeparatorItem
|
||||
|
||||
class BottomSheetAdapter(val items: List<IBottomSheetItem<*>>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
private val viewHolderProvider = ViewHolderProvider()
|
||||
|
||||
init {
|
||||
viewHolderProvider.registerViewHolderFactory(1, R.layout.nav_bs_item_primary) { itemView ->
|
||||
PrimaryItem.ViewHolder(itemView)
|
||||
}
|
||||
viewHolderProvider.registerViewHolderFactory(2, R.layout.nav_bs_item_separator) { itemView ->
|
||||
SeparatorItem.ViewHolder(itemView)
|
||||
}
|
||||
viewHolderProvider.registerViewHolderFactory(3, R.layout.nav_bs_item_edittext_filled) { itemView ->
|
||||
EditTextFilledItem.ViewHolder(itemView)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return viewHolderProvider.provideViewHolder(viewGroup = parent, viewType = viewType)
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return items[position].viewType
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return items.size
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
items[position].bindViewHolder(viewHolder = holder)
|
||||
}
|
||||
}
|
@ -0,0 +1,207 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.View.OnClickListener
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Toast
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import kotlinx.android.synthetic.main.nav_bottom_sheet.view.*
|
||||
import pl.szczodrzynski.navlib.Anim
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.EditTextFilledItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.IBottomSheetItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.PrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.SeparatorItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.listeners.OnItemInputListener
|
||||
import pl.szczodrzynski.navlib.getColorFromAttr
|
||||
|
||||
|
||||
class NavBottomSheet : CoordinatorLayout {
|
||||
constructor(context: Context) : super(context) {
|
||||
create(null, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
create(attrs, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
|
||||
create(attrs, defStyle)
|
||||
}
|
||||
|
||||
private lateinit var scrimView: View
|
||||
private lateinit var bottomSheet: NestedScrollView
|
||||
private lateinit var bottomSheetContent: LinearLayout
|
||||
private lateinit var bottomSheetDragBar: View
|
||||
|
||||
private lateinit var bottomSheetBehavior: BottomSheetBehavior<View>
|
||||
private var bottomSheetVisible = false
|
||||
|
||||
/**
|
||||
* Enable the bottom sheet.
|
||||
* This value is mostly relevant to the [pl.szczodrzynski.navlib.NavBottomBar].
|
||||
*/
|
||||
var enable = true
|
||||
set(value) {
|
||||
field = value
|
||||
if (!value && bottomSheetVisible)
|
||||
close()
|
||||
}
|
||||
/**
|
||||
* Whether the [pl.szczodrzynski.navlib.NavBottomBar] should open this BottomSheet
|
||||
* when the user drags the bottom bar.
|
||||
*/
|
||||
var enableDragToOpen = true
|
||||
|
||||
/**
|
||||
* Control the scrim view visibility, shown when BottomSheet
|
||||
* is expanded.
|
||||
*/
|
||||
var scrimViewEnabled = true
|
||||
set(value) {
|
||||
scrimView.visibility = if (value) View.INVISIBLE else View.GONE // INVISIBLE
|
||||
field = value
|
||||
}
|
||||
/**
|
||||
* Whether tapping the Scrim view should hide the BottomSheet.
|
||||
*/
|
||||
var scrimViewTapToClose = true
|
||||
|
||||
|
||||
fun hideKeyboard() {
|
||||
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(rootView.windowToken, 0)
|
||||
}
|
||||
|
||||
|
||||
private fun create(attrs: AttributeSet?, defStyle: Int) {
|
||||
val layoutInflater = LayoutInflater.from(context)
|
||||
layoutInflater.inflate(pl.szczodrzynski.navlib.R.layout.nav_bottom_sheet, this)
|
||||
|
||||
scrimView = findViewById(pl.szczodrzynski.navlib.R.id.nv_scrim)
|
||||
bottomSheet = findViewById(pl.szczodrzynski.navlib.R.id.nv_bottomSheetView)
|
||||
bottomSheetContent = findViewById(pl.szczodrzynski.navlib.R.id.nv_bottomSheetContent)
|
||||
bottomSheetDragBar = findViewById(pl.szczodrzynski.navlib.R.id.nv_bottomSheetDragBar)
|
||||
|
||||
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
|
||||
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
|
||||
scrimView.setOnTouchListener { _, event ->
|
||||
if (!scrimViewTapToClose)
|
||||
return@setOnTouchListener true
|
||||
if (event.action == MotionEvent.ACTION_UP && bottomSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN) {
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(v: View, p1: Float) {}
|
||||
override fun onStateChanged(v: View, newState: Int) {
|
||||
if (newState == BottomSheetBehavior.STATE_HIDDEN && bottomSheetVisible) {
|
||||
bottomSheetVisible = false
|
||||
bottomSheet.scrollTo(0, 0)
|
||||
if (scrimViewEnabled)
|
||||
Anim.fadeOut(scrimView, 300, null)
|
||||
// steal the focus from any EditTexts
|
||||
bottomSheetDragBar.requestFocus()
|
||||
hideKeyboard()
|
||||
}
|
||||
else if (!bottomSheetVisible) {
|
||||
bottomSheetVisible = true
|
||||
if (scrimViewEnabled)
|
||||
Anim.fadeIn(scrimView, 300, null)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
bottomSheetContent.background.colorFilter = PorterDuffColorFilter(
|
||||
getColorFromAttr(
|
||||
context,
|
||||
pl.szczodrzynski.navlib.R.attr.colorBackgroundFloating
|
||||
), PorterDuff.Mode.SRC_ATOP)
|
||||
|
||||
// steal the focus from any EditTexts
|
||||
bottomSheetDragBar.requestFocus()
|
||||
|
||||
val items = ArrayList<IBottomSheetItem<*>>()
|
||||
|
||||
items += EditTextFilledItem(true).apply {
|
||||
id = 0
|
||||
hint = "Search"
|
||||
helperText = "0 results found"
|
||||
onItemInputListener = object : OnItemInputListener {
|
||||
override fun onItemInput(itemId: Int, item: EditTextFilledItem, text: CharSequence) {
|
||||
item.helperText = "${text.length} results found"
|
||||
bs_list.adapter?.notifyItemChanged(itemId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items += PrimaryItem(true)
|
||||
.withId(1)
|
||||
.withTitle("Compose")
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_pencil)
|
||||
.withOnClickListener(OnClickListener {
|
||||
Toast.makeText(context, "Compose message", Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
// TODO add separator item
|
||||
items += SeparatorItem(true)
|
||||
items += PrimaryItem(true)
|
||||
.withId(3)
|
||||
.withTitle("Synchronise")
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_sync)
|
||||
.withOnClickListener(OnClickListener {
|
||||
Toast.makeText(context, "Synchronising...", Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
items += PrimaryItem(true)
|
||||
.withId(4)
|
||||
.withTitle("Help")
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_help)
|
||||
.withOnClickListener(OnClickListener {
|
||||
Toast.makeText(context, "Want some help?", Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
bs_list.apply {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = BottomSheetAdapter(items)
|
||||
}
|
||||
}
|
||||
|
||||
fun dispatchBottomBarEvent(event: MotionEvent) {
|
||||
val location = IntArray(2)
|
||||
bottomSheet.getLocationOnScreen(location)
|
||||
event.setLocation(event.rawX - location[0], event.rawY - location[1])
|
||||
bottomSheet.dispatchTouchEvent(event)
|
||||
}
|
||||
|
||||
fun setContentPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||
bottomSheetContent.setPadding(left, top, right, bottom)
|
||||
}
|
||||
fun getContentView() = bottomSheetContent
|
||||
|
||||
var isOpen
|
||||
get() = bottomSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN
|
||||
set(value) {
|
||||
bottomSheetBehavior.state = if (value) BottomSheetBehavior.STATE_EXPANDED else BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
fun open() { isOpen = true }
|
||||
fun close() { isOpen = true }
|
||||
fun toggle() {
|
||||
if (!enable)
|
||||
return
|
||||
isOpen = !isOpen
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class ViewHolderProvider {
|
||||
private val viewHolderFactories = hashMapOf<Int, Pair<Int, (View) -> RecyclerView.ViewHolder>>()
|
||||
|
||||
fun provideViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val (layoutId: Int, f: (View) -> RecyclerView.ViewHolder) = viewHolderFactories[viewType]!!
|
||||
val view = LayoutInflater.from(viewGroup.getContext()).inflate(layoutId, viewGroup, false)
|
||||
return f(view)
|
||||
}
|
||||
|
||||
fun registerViewHolderFactory(viewType: Int, layoutId: Int, viewHolderFactory: (View) -> RecyclerView.ViewHolder) {
|
||||
viewHolderFactories[viewType] = Pair(layoutId, viewHolderFactory)
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet.items
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
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.sizeDp
|
||||
import com.mikepenz.materialize.holder.ImageHolder
|
||||
import pl.szczodrzynski.navlib.R
|
||||
import pl.szczodrzynski.navlib.bottomsheet.listeners.OnItemInputListener
|
||||
|
||||
class EditTextFilledItem(override val isContextual: Boolean = true) : IBottomSheetItem<EditTextFilledItem.ViewHolder> {
|
||||
|
||||
/*_ _
|
||||
| | | |
|
||||
| | __ _ _ _ ___ _ _| |_
|
||||
| | / _` | | | |/ _ \| | | | __|
|
||||
| |___| (_| | |_| | (_) | |_| | |_
|
||||
|______\__,_|\__, |\___/ \__,_|\__|
|
||||
__/ |
|
||||
|__*/
|
||||
override var id: Int = -1
|
||||
override val viewType: Int
|
||||
get() = 3
|
||||
override val layoutId: Int
|
||||
get() = R.layout.nav_bs_item_edittext_filled
|
||||
|
||||
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val textInputLayout = itemView.findViewById<TextInputLayout>(R.id.item_text_input_layout)
|
||||
val textInputEditText = itemView.findViewById<TextInputEditText>(R.id.item_text_input_edit_text)
|
||||
}
|
||||
|
||||
override fun bindViewHolder(viewHolder: ViewHolder) {
|
||||
viewHolder.textInputLayout.apply {
|
||||
hint = this@EditTextFilledItem.hint
|
||||
helperText = this@EditTextFilledItem.helperText
|
||||
error = this@EditTextFilledItem.error
|
||||
}
|
||||
viewHolder.textInputEditText.apply {
|
||||
setText(this@EditTextFilledItem.text)
|
||||
|
||||
removeTextChangedListener(textChangedListener)
|
||||
addTextChangedListener(textChangedListener)
|
||||
}
|
||||
}
|
||||
|
||||
/*_____ _
|
||||
| __ \ | |
|
||||
| | | | __ _| |_ __ _
|
||||
| | | |/ _` | __/ _` |
|
||||
| |__| | (_| | || (_| |
|
||||
|_____/ \__,_|\__\__,*/
|
||||
var hint: CharSequence? = null
|
||||
var helperText: CharSequence? = null
|
||||
var error: CharSequence? = null
|
||||
var text: CharSequence? = null
|
||||
private var textChangedListener: TextWatcher? = null
|
||||
var onItemInputListener: OnItemInputListener? = null
|
||||
set(value) {
|
||||
field = value
|
||||
textChangedListener = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
onItemInputListener?.onItemInput(id, this@EditTextFilledItem, s?:"")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet.items
|
||||
|
||||
import android.view.View
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
interface IBottomSheetItem<T> {
|
||||
|
||||
val isContextual: Boolean
|
||||
var id: Int
|
||||
val viewType: Int
|
||||
val layoutId: Int
|
||||
|
||||
fun bindViewHolder(viewHolder: T)
|
||||
fun bindViewHolder(viewHolder: RecyclerView.ViewHolder) {
|
||||
bindViewHolder(viewHolder as T)
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet.items
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
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.sizeDp
|
||||
import com.mikepenz.materialize.holder.ImageHolder
|
||||
import pl.szczodrzynski.navlib.R
|
||||
|
||||
data class PrimaryItem(override val isContextual: Boolean = true) : IBottomSheetItem<PrimaryItem.ViewHolder> {
|
||||
|
||||
/*_ _
|
||||
| | | |
|
||||
| | __ _ _ _ ___ _ _| |_
|
||||
| | / _` | | | |/ _ \| | | | __|
|
||||
| |___| (_| | |_| | (_) | |_| | |_
|
||||
|______\__,_|\__, |\___/ \__,_|\__|
|
||||
__/ |
|
||||
|__*/
|
||||
override var id: Int = -1
|
||||
override val viewType: Int
|
||||
get() = 1
|
||||
override val layoutId: Int
|
||||
get() = R.layout.nav_bs_item_primary
|
||||
|
||||
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val root = itemView.findViewById<View>(R.id.item_root)
|
||||
val text = itemView.findViewById<TextView>(R.id.item_text)
|
||||
}
|
||||
|
||||
override fun bindViewHolder(viewHolder: ViewHolder) {
|
||||
viewHolder.root.setOnClickListener(onClickListener)
|
||||
viewHolder.text.text = title
|
||||
viewHolder.text.setCompoundDrawables(
|
||||
IconicsDrawable(viewHolder.text.context)
|
||||
.icon(iconicsIcon?:CommunityMaterial.Icon.cmd_android)
|
||||
.sizeDp(20),
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
/*_____ _
|
||||
| __ \ | |
|
||||
| | | | __ _| |_ __ _
|
||||
| | | |/ _` | __/ _` |
|
||||
| |__| | (_| | || (_| |
|
||||
|_____/ \__,_|\__\__,*/
|
||||
var title: CharSequence? = null
|
||||
@StringRes
|
||||
var titleRes: Int? = null
|
||||
var description: CharSequence? = null
|
||||
@StringRes
|
||||
var descriptionRes: Int? = null
|
||||
var icon: ImageHolder? = null
|
||||
var iconicsIcon: IIcon? = null
|
||||
var onClickListener: View.OnClickListener? = null
|
||||
|
||||
fun withId(id: Int): PrimaryItem {
|
||||
this.id = id
|
||||
return this
|
||||
}
|
||||
|
||||
fun withTitle(title: CharSequence): PrimaryItem {
|
||||
this.title = title
|
||||
this.titleRes = null
|
||||
return this
|
||||
}
|
||||
fun withTitle(@StringRes title: Int): PrimaryItem {
|
||||
this.title = null
|
||||
this.titleRes = title
|
||||
return this
|
||||
}
|
||||
|
||||
fun withDescription(description: CharSequence): PrimaryItem {
|
||||
this.description = description
|
||||
this.descriptionRes = null
|
||||
return this
|
||||
}
|
||||
fun withDescription(@StringRes description: Int): PrimaryItem {
|
||||
this.description = null
|
||||
this.descriptionRes = description
|
||||
return this
|
||||
}
|
||||
|
||||
fun withIcon(icon: Drawable): PrimaryItem {
|
||||
this.icon = ImageHolder(icon)
|
||||
return this
|
||||
}
|
||||
fun withIcon(@DrawableRes icon: Int): PrimaryItem {
|
||||
this.icon = ImageHolder(icon)
|
||||
return this
|
||||
}
|
||||
fun withIcon(icon: IIcon): PrimaryItem {
|
||||
this.iconicsIcon = icon
|
||||
return this
|
||||
}
|
||||
|
||||
fun withOnClickListener(onClickListener: View.OnClickListener): PrimaryItem {
|
||||
this.onClickListener = onClickListener
|
||||
return this
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet.items
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import pl.szczodrzynski.navlib.R
|
||||
|
||||
data class SeparatorItem(override val isContextual: Boolean = true) : IBottomSheetItem<SeparatorItem.ViewHolder> {
|
||||
|
||||
/*_ _
|
||||
| | | |
|
||||
| | __ _ _ _ ___ _ _| |_
|
||||
| | / _` | | | |/ _ \| | | | __|
|
||||
| |___| (_| | |_| | (_) | |_| | |_
|
||||
|______\__,_|\__, |\___/ \__,_|\__|
|
||||
__/ |
|
||||
|__*/
|
||||
override var id: Int = -1
|
||||
override val viewType: Int
|
||||
get() = 2
|
||||
override val layoutId: Int
|
||||
get() = R.layout.nav_bs_item_separator
|
||||
|
||||
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
|
||||
|
||||
override fun bindViewHolder(viewHolder: ViewHolder) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet.listeners
|
||||
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.EditTextFilledItem
|
||||
|
||||
interface OnItemInputListener {
|
||||
fun onItemInput(itemId: Int, item: EditTextFilledItem, text: CharSequence)
|
||||
}
|
10
navlib/src/main/res/drawable-v21/bs_item_background.xml
Normal file
10
navlib/src/main/res/drawable-v21/bs_item_background.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple android:color="#202196f3"
|
||||
android:radius="5dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@android:id/mask"
|
||||
android:top="3dp"
|
||||
android:bottom="3dp"
|
||||
android:drawable="@color/color" />
|
||||
</ripple>
|
@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:shape="rectangle">
|
||||
<corners
|
||||
android:topLeftRadius="16dp"
|
||||
android:topRightRadius="16dp" />
|
||||
<solid android:color="?colorBackgroundFloating" />
|
||||
<solid android:color="#ffffff" tools:color="?colorBackgroundFloating" />
|
||||
</shape>
|
10
navlib/src/main/res/drawable/bs_item_background.xml
Normal file
10
navlib/src/main/res/drawable/bs_item_background.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This will be the drawable used on API < 21 -->
|
||||
<!-- Obviously you can specify here whatever you want -->
|
||||
<!-- like activated states, animated states, shapes, pngs, whatever like any other drawable-->
|
||||
<!-- I've just put 2 states (pressed,focused) using the same color than the v21 ripple -->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/bs_item_background_base" android:state_focused="true"/>
|
||||
<item android:drawable="@drawable/bs_item_background_base" android:state_pressed="true"/>
|
||||
<item android:drawable="@android:color/transparent"/>
|
||||
</selector>
|
11
navlib/src/main/res/drawable/bs_item_background_base.xml
Normal file
11
navlib/src/main/res/drawable/bs_item_background_base.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:top="3dp"
|
||||
android:bottom="3dp">
|
||||
<shape>
|
||||
<solid android:color="#202196f3"/>
|
||||
<corners android:radius="5dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
@ -1,90 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout 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="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/bottom_sheet_controll_bar" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Button" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Button" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Button" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Button" />
|
||||
|
||||
<CalendarView
|
||||
android:id="@+id/calendarView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
app:srcCompat="@android:drawable/checkbox_on_background" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<RatingBar
|
||||
android:id="@+id/ratingBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<SearchView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</SearchView>
|
||||
|
||||
<Switch
|
||||
android:id="@+id/switch1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Switch" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/floatingActionButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:srcCompat="@drawable/ic_android" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
6
navlib/src/main/res/layout/material_drawer.xml
Normal file
6
navlib/src/main/res/layout/material_drawer.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/material_drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="false" />
|
25
navlib/src/main/res/layout/material_drawer_slider.xml
Normal file
25
navlib/src/main/res/layout/material_drawer_slider.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.mikepenz.materialize.view.ScrimInsetsRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/material_drawer_slider_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:layout_marginEnd="@dimen/material_drawer_margin"
|
||||
android:layout_marginRight="@dimen/material_drawer_margin"
|
||||
android:clickable="true"
|
||||
android:elevation="8dp"
|
||||
android:fitsSystemWindows="true"
|
||||
android:focusable="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:id="@+id/material_drawer_inner_shadow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentStart="false"
|
||||
android:layout_alignParentLeft="false"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:background="@drawable/material_drawer_shadow_left"
|
||||
android:visibility="gone" />
|
||||
</com.mikepenz.materialize.view.ScrimInsetsRelativeLayout>
|
110
navlib/src/main/res/layout/nav_bottom_sheet.xml
Normal file
110
navlib/src/main/res/layout/nav_bottom_sheet.xml
Normal file
@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout 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">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:translationZ="10dp"
|
||||
tools:targetApi="lollipop">
|
||||
|
||||
<View
|
||||
android:id="@+id/nv_scrim"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#99000000"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/nv_bottomSheetView"
|
||||
style="@style/width_max_600dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="auto"
|
||||
app:layout_behavior="@string/bottom_sheet_behavior"
|
||||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/nv_bottomSheetContent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bottom_sheet_background"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
tools:paddingBottom="48dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/nv_bottomSheetDragBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
app:srcCompat="@drawable/bottom_sheet_control_bar"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Sorting order" />
|
||||
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:singleSelection="true">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button2"
|
||||
style="?materialButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="By date"
|
||||
app:icon="@drawable/ic_android"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button3"
|
||||
style="?materialButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="By subject" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button4"
|
||||
style="?materialButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="By sender" />
|
||||
|
||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/bs_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="50dp"
|
||||
tools:listitem="@layout/nav_bs_item_primary"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</layout>
|
21
navlib/src/main/res/layout/nav_bs_item_edittext_filled.xml
Normal file
21
navlib/src/main/res/layout/nav_bs_item_edittext_filled.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.textfield.TextInputLayout 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/item_text_input_layout"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.Dense"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
tools:helperText="2 results found"
|
||||
tools:hint="Search">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/item_text_input_edit_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="text"
|
||||
android:singleLine="true"
|
||||
tools:text="Kowalski" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
22
navlib/src/main/res/layout/nav_bs_item_primary.xml
Normal file
22
navlib/src/main/res/layout/nav_bs_item_primary.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/item_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginLeft="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" />
|
||||
</LinearLayout>
|
12
navlib/src/main/res/layout/nav_bs_item_separator.xml
Normal file
12
navlib/src/main/res/layout/nav_bs_item_separator.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="17dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/material_drawer_divider" />
|
||||
</LinearLayout>
|
@ -10,25 +10,32 @@
|
||||
<View
|
||||
android:id="@+id/nv_statusBarBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="25dp"
|
||||
android:layout_height="0dp"
|
||||
tools:layout_height="25dp"
|
||||
android:background="?android:windowBackground" />
|
||||
|
||||
<View
|
||||
android:id="@+id/nv_navigationBarBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_height="0dp"
|
||||
tools:layout_height="48dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?colorPrimaryDark"
|
||||
android:background="?colorPrimaryVariant"
|
||||
tools:background="?colorPrimaryVariant" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/nv_drawerContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/nv_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingBottom="48dp">
|
||||
tools:paddingTop="24dp"
|
||||
tools:paddingBottom="48dp">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
<pl.szczodrzynski.navlib.NavToolbar
|
||||
android:id="@+id/nv_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
@ -52,74 +59,67 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:max="20"
|
||||
android:progress="4" />
|
||||
android:progress="4"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Set toolbar elevation" />
|
||||
android:text="Set toolbar elevation"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.bottomappbar.BottomAppBar
|
||||
android:id="@+id/nv_bottomAppBar"
|
||||
<pl.szczodrzynski.navlib.NavBottomBar
|
||||
android:id="@+id/nv_bottomBar"
|
||||
style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:fabAlignmentMode="end" />
|
||||
android:visibility="visible"
|
||||
app:fabAlignmentMode="center"
|
||||
app:fabAnimationMode="scale" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/nv_floatingActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:visibility="gone"
|
||||
app:layout_anchor="@id/nv_bottomBar"
|
||||
app:backgroundTint="?colorAccent"
|
||||
app:layout_anchor="@id/nv_bottomAppBar"
|
||||
tools:srcCompat="@android:drawable/ic_lock_lock" />
|
||||
app:srcCompat="@android:drawable/ic_menu_edit"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:translationZ="10dp"
|
||||
tools:targetApi="lollipop">
|
||||
|
||||
<View
|
||||
android:id="@+id/nv_scrim"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#99000000"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/nv_bottomSheet"
|
||||
style="@style/width_max_600dp"
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/nv_extendedFloatingActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="auto"
|
||||
app:layout_behavior="@string/bottom_sheet_behavior"
|
||||
tools:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bottom_sheet_background"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp">
|
||||
|
||||
<include
|
||||
layout="@layout/bottom_sheet_fragment_theme_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
android:layout_margin="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:visibility="visible"
|
||||
android:text=""
|
||||
app:backgroundTint="?colorAccent"
|
||||
app:icon="@android:drawable/ic_menu_edit"
|
||||
app:layout_anchor="@+id/nv_bottomBar"
|
||||
app:layout_anchorGravity="center|top"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
|
||||
android:id="@+id/nv_bottomSheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/nv_statusBarDarker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
tools:layout_height="25dp"
|
||||
android:background="#22000000" />
|
||||
|
||||
</merge>
|
5
navlib/src/main/res/values/colors.xml
Normal file
5
navlib/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="color">#202196f3</color>
|
||||
<color name="blue">#154FBC</color>
|
||||
</resources>
|
@ -1 +1 @@
|
||||
include ':app', ':MaterialDrawer', ':navlib'
|
||||
include ':app', ':navlib'
|
Loading…
x
Reference in New Issue
Block a user