Fix system bars colors, bottom sheet dragging, dark theme switching

This commit is contained in:
kubasz 2019-08-11 19:55:21 +02:00
parent d0e79b6fbb
commit f2fef9ddbd
5 changed files with 219 additions and 96 deletions

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RenderSettings">
<option name="showDecorations" value="true" />
</component>
</project>

View File

@ -1,25 +1,62 @@
package pl.szczodrzynski.navigation package pl.szczodrzynski.navigation
import android.content.Context
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.widget.Switch
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import android.widget.Toast import android.widget.Toast
import androidx.core.widget.NestedScrollView import androidx.core.widget.NestedScrollView
import com.google.android.material.bottomappbar.BottomAppBar import com.google.android.material.bottomappbar.BottomAppBar
import android.view.WindowManager
import android.os.Build
import kotlinx.android.synthetic.main.sample_nav_view.*
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
companion object {
var darkTheme: Boolean? = null
}
var showing = false var showing = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (darkTheme == null)
darkTheme = getSharedPreferences("prefs", Context.MODE_PRIVATE).getBoolean("darkTheme", false)
Log.d("MainActivity", "Dark theme $darkTheme")
setTheme(if (darkTheme == true) R.style.AppTheme else R.style.AppTheme_Light)
setContentView(R.layout.sample_nav_view) 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
})
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
)
}
button.setOnClickListener {
// use commit instead of apply because of recreating the activity
darkTheme = (darkTheme == false)
getSharedPreferences("prefs", Context.MODE_PRIVATE).edit().putBoolean("darkTheme", darkTheme == true).commit()
recreate()
}
/*val dim = findViewById<View>(R.id.view) /*val dim = findViewById<View>(R.id.view)
val nestedScrollView = findViewById<View>(R.id.nestedScrollView) val nestedScrollView = findViewById<View>(R.id.nestedScrollView)

View File

@ -6,15 +6,18 @@
<item name="colorPrimary">#64b5f6</item> <item name="colorPrimary">#64b5f6</item>
<item name="colorPrimaryDark">#1976d2</item> <item name="colorPrimaryDark">#1976d2</item>
<item name="colorPrimaryVariant">#1976d2</item> <item name="colorPrimaryVariant">#1976d2</item>
<item name="colorAccent">#ba68c8</item> <item name="colorAccent">#ff6e40</item>
<item name="colorSecondary">#ba68c8</item> <item name="colorSecondary">#ff6e40</item>
<item name="colorSecondaryVariant">#9c27b0</item> <item name="colorSecondaryVariant">#ff3d00</item>
<item name="android:colorBackground">@color/black</item> <item name="android:colorBackground">@color/black</item>
<item name="android:windowBackground">?android:colorBackground</item>
<item name="colorSurface">#1f1f1f</item> <item name="colorSurface">#1f1f1f</item>
<item name="android:statusBarColor" tools:targetApi="lollipop">?android:colorBackground</item> <item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item> <item name="android:windowTranslucentStatus" tools:targetApi="kitkat">false</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">?colorPrimaryDark</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
<item name="android:windowTranslucentNavigation" tools:targetApi="kitkat">false</item>
<item name="colorOnPrimary">#000000</item> <item name="colorOnPrimary">#000000</item>
<item name="colorOnSecondary">#000000</item> <item name="colorOnSecondary">#000000</item>
@ -24,6 +27,8 @@
<item name="nv_actionBarBackground">?colorSurface</item> <item name="nv_actionBarBackground">?colorSurface</item>
<item name="windowActionBar">false</item> <item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> <item name="windowNoTitle">true</item>
</style> </style>
<style name="AppTheme.Light" parent="NavView.Light"> <style name="AppTheme.Light" parent="NavView.Light">
@ -31,16 +36,18 @@
<item name="colorPrimary">#2196f3</item> <item name="colorPrimary">#2196f3</item>
<item name="colorPrimaryDark">#1976d2</item> <item name="colorPrimaryDark">#1976d2</item>
<item name="colorPrimaryVariant">#90caf9</item> <item name="colorPrimaryVariant">#90caf9</item>
<item name="colorAccent">#ba68c8</item> <item name="colorAccent">#ff6e40</item>
<item name="colorSecondary">#ba68c8</item> <item name="colorSecondary">#ff6e40</item>
<item name="colorSecondaryVariant">#9c27b0</item> <item name="colorSecondaryVariant">#ff3d00</item>
<item name="android:colorBackground">@color/white</item> <item name="android:colorBackground">@color/white</item>
<item name="android:windowBackground">?android:colorBackground</item> <item name="android:windowBackground">?android:colorBackground</item>
<item name="colorSurface">#ffffff</item> <item name="colorSurface">#ffffff</item>
<item name="android:statusBarColor" tools:targetApi="lollipop">?android:colorBackground</item> <item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">true</item> <item name="android:windowTranslucentStatus" tools:targetApi="kitkat">false</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">?colorPrimaryDark</item>
<item name="android:navigationBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
<item name="android:windowTranslucentNavigation" tools:targetApi="kitkat">false</item>
<item name="colorOnPrimary">#000000</item> <item name="colorOnPrimary">#000000</item>
<item name="colorOnSecondary">#000000</item> <item name="colorOnSecondary">#000000</item>

View File

@ -1,23 +1,26 @@
package pl.szczodrzynski.navlib package pl.szczodrzynski.navlib
import android.content.Context import android.content.Context
import android.os.Build
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent import android.view.MotionEvent
import android.view.MotionEvent.INVALID_POINTER_ID
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.SeekBar
import androidx.core.view.MotionEventCompat import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.*
import androidx.core.widget.NestedScrollView import androidx.core.widget.NestedScrollView
import androidx.customview.widget.ViewDragHelper
import com.google.android.material.bottomappbar.BottomAppBar import com.google.android.material.bottomappbar.BottomAppBar
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import kotlinx.android.synthetic.main.nav_view.view.*
class NavView : FrameLayout { class NavView : FrameLayout {
@ -36,6 +39,35 @@ class NavView : FrameLayout {
private val displayWidth: Int by lazy { configuration.screenWidthDp } private val displayWidth: Int by lazy { configuration.screenWidthDp }
private val displayHeight: Int by lazy { configuration.screenHeightDp } 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) { constructor(context: Context) : super(context) {
init(null, 0) init(null, 0)
} }
@ -63,6 +95,8 @@ class NavView : FrameLayout {
//findViewById<TextView>(R.id.textView).text = "${displayWidth}dp x ${displayHeight}dp" //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) bottomAppBar = findViewById(R.id.nv_bottomAppBar)
floatingActionButton = findViewById(R.id.nv_floatingActionButton) floatingActionButton = findViewById(R.id.nv_floatingActionButton)
scrimView = findViewById(R.id.nv_scrim) scrimView = findViewById(R.id.nv_scrim)
@ -70,10 +104,24 @@ class NavView : FrameLayout {
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet) bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
bottomSheetBehavior.state = STATE_HIDDEN bottomSheetBehavior.state = STATE_HIDDEN
bottomSheetBehavior.peekHeight = displayHeight
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 -> bottomAppBar.setOnTouchListener { v, event ->
val location = IntArray(2)
bottomSheet.getLocationOnScreen(location)
event.setLocation(event.rawX - location[0], event.rawY - location[1])
bottomSheet.dispatchTouchEvent(event) bottomSheet.dispatchTouchEvent(event)
false true
} }
scrimView.setOnTouchListener { v, event -> scrimView.setOnTouchListener { v, event ->
@ -89,6 +137,7 @@ class NavView : FrameLayout {
if (newState == STATE_HIDDEN && bottomSheetVisible) { if (newState == STATE_HIDDEN && bottomSheetVisible) {
bottomSheetVisible = false bottomSheetVisible = false
Anim.fadeOut(scrimView, 300, null) Anim.fadeOut(scrimView, 300, null)
bottomSheet.scrollTo(0, 0)
} }
else if (!bottomSheetVisible) { else if (!bottomSheetVisible) {
bottomSheetVisible = true bottomSheetVisible = true
@ -106,15 +155,16 @@ class NavView : FrameLayout {
} }
} }
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
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})
} }
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) { override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
if (contentView == null) { if (contentView == null) {
super.addView(child, index, params) super.addView(child, index, params)

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -7,84 +7,119 @@
android:orientation="vertical" android:orientation="vertical"
tools:parentTag="FrameLayout"> tools:parentTag="FrameLayout">
<com.google.android.material.appbar.MaterialToolbar <View
android:id="@+id/toolbar" android:id="@+id/nv_statusBarBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="25dp"
android:elevation="4dp" android:background="?android:windowBackground" />
android:background="?nv_actionBarBackground"
app:title="@string/app_name" />
<androidx.coordinatorlayout.widget.CoordinatorLayout <View
android:id="@+id/nv_navigationBarBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="48dp"
android:layout_gravity="bottom"
android:background="?colorPrimaryDark"
tools:background="?colorPrimaryVariant" />
<LinearLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/nv_content" android:id="@+id/nv_main"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center" android:paddingTop="24dp"
android:layout_marginTop="?actionBarSize" android:paddingBottom="48dp">
android:layout_marginBottom="?actionBarSize"
android:orientation="vertical" />
<com.google.android.material.bottomappbar.BottomAppBar <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/nv_bottomAppBar" android:id="@+id/nv_toolbar"
style="@style/Widget.MaterialComponents.BottomAppBar.Colored" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:layout_height="wrap_content" android:background="?nv_actionBarBackground"
android:layout_gravity="bottom" android:elevation="4dp"
app:fabAlignmentMode="end" /> app:title="@string/app_name"
tools:targetApi="lollipop" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/nv_floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
app:backgroundTint="?colorAccent"
app:layout_anchor="@id/nv_bottomAppBar"
tools:srcCompat="@android:drawable/ic_lock_lock" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:translationZ="10dp">
<View
android:id="@+id/nv_scrim"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#99000000"
android:visibility="invisible"
tools:visibility="visible" />
<androidx.core.widget.NestedScrollView
android:id="@+id/nv_bottomSheet"
style="@style/width_max_600dp"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:behavior_hideable="true"
app:behavior_peekHeight="500dp"
app:layout_behavior="@string/bottom_sheet_behavior">
<LinearLayout <LinearLayout
android:id="@+id/nv_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:background="@drawable/bottom_sheet_background" android:layout_gravity="center"
android:paddingStart="8dp" android:layout_marginTop="?actionBarSize"
android:paddingEnd="8dp"> android:layout_marginBottom="?actionBarSize"
android:orientation="vertical">
<include <SeekBar
layout="@layout/bottom_sheet_fragment_theme_info" android:id="@+id/nv_elevation"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:max="20"
android:progress="4" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Set toolbar elevation" />
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> <com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/nv_bottomAppBar"
style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:fabAlignmentMode="end" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/nv_floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
app:backgroundTint="?colorAccent"
app:layout_anchor="@id/nv_bottomAppBar"
tools:srcCompat="@android:drawable/ic_lock_lock" />
</FrameLayout> </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"
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>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</merge>