mirror of
https://github.com/kuba2k2/NavLib.git
synced 2025-01-18 06:16:43 -06:00
Fix navbar detection, again. Add text input to bottom sheet.
Add Drawer customization, drawer profiles, drawer badges, update Sample. Add text styles. Completed BottomSheet & Drawer implementations.
This commit is contained in:
parent
82fab7f934
commit
ab7211e85c
@ -35,7 +35,7 @@ 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:7.0.0-rc05"
|
||||
implementation "com.mikepenz:materialdrawer:7.0.0-rc05"
|
||||
//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
|
||||
|
@ -3,6 +3,8 @@
|
||||
package="pl.szczodrzynski.navigation">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@ -10,9 +12,10 @@
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme.Light"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<activity android:name=".MainActivity">
|
||||
android:theme="@style/AppTheme.Light"><!--
|
||||
android:windowSoftInputMode="adjustResize"-->
|
||||
<activity android:name=".MainActivity"
|
||||
android:configChanges="screenSize|orientation">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
@ -8,7 +8,16 @@ import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mikepenz.iconics.IconicsColor
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.IconicsSize
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.materialdrawer.Drawer
|
||||
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
||||
import kotlinx.android.synthetic.main.sample_nav_view.*
|
||||
import pl.szczodrzynski.navlib.SystemBarsUtil
|
||||
import pl.szczodrzynski.navlib.SystemBarsUtil.Companion.COLOR_DO_NOT_CHANGE
|
||||
@ -18,8 +27,10 @@ import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
|
||||
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet.Companion.SORT_MODE_ASCENDING
|
||||
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet.Companion.SORT_MODE_DESCENDING
|
||||
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet.Companion.TOGGLE_GROUP_SORTING_ORDER
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.PrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.SeparatorItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import pl.szczodrzynski.navlib.drawer.IDrawerProfile
|
||||
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
||||
import pl.szczodrzynski.navlib.getColorFromAttr
|
||||
|
||||
|
||||
@ -38,6 +49,8 @@ class MainActivity : AppCompatActivity() {
|
||||
Log.d("MainActivity", "Dark theme $darkTheme")
|
||||
setTheme(if (darkTheme == true) R.style.AppTheme else R.style.AppTheme_Light)
|
||||
|
||||
Log.d("NavLib", "ACTIVITY created")
|
||||
|
||||
setContentView(R.layout.sample_nav_view)
|
||||
|
||||
appFullscreen.isChecked = getSharedPreferences("prefs", Context.MODE_PRIVATE).getBoolean("appFullscreen", true)
|
||||
@ -65,18 +78,21 @@ class MainActivity : AppCompatActivity() {
|
||||
else -> R.id.gradientDoNotChange
|
||||
})
|
||||
|
||||
button.setOnClickListener {
|
||||
themeButton.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()
|
||||
}
|
||||
|
||||
commitButton.setOnClickListener {
|
||||
navView.systemBarsUtil?.commit()
|
||||
}
|
||||
|
||||
//navView.init(this)
|
||||
|
||||
// init the drawer before SystemBarsUtil
|
||||
navView.addDrawer(activity = this)
|
||||
navView.drawer.init(this)
|
||||
|
||||
SystemBarsUtil(this).apply {
|
||||
paddingByKeyboard = navView
|
||||
@ -206,26 +222,150 @@ class MainActivity : AppCompatActivity() {
|
||||
navView.bottomBar.fabExtended = false
|
||||
|
||||
|
||||
navView.drawer.apply {
|
||||
|
||||
addUnreadCounterType(type = 10, drawerItem = 1)
|
||||
addUnreadCounterType(type = 20, drawerItem = 2)
|
||||
addUnreadCounterType(type = 30, drawerItem = 60)
|
||||
addUnreadCounterType(type = 40, drawerItem = 62)
|
||||
|
||||
appendItems(
|
||||
DrawerPrimaryItem()
|
||||
.withAppTitle("Navigation")
|
||||
.withName("Home")
|
||||
.withSelected(true)
|
||||
.withIdentifier(1)
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_google_home),
|
||||
|
||||
DrawerPrimaryItem()
|
||||
.withIdentifier(2)
|
||||
.withName("Settings")
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_settings),
|
||||
|
||||
DrawerPrimaryItem().withName("iOS")
|
||||
.withIdentifier(60)
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_apple),
|
||||
|
||||
DrawerPrimaryItem().withName("School bell")
|
||||
.withDescription("why not?")
|
||||
.withIdentifier(61)
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_alarm_bell),
|
||||
|
||||
DrawerPrimaryItem().withName("Lock screen")
|
||||
.withIdentifier(62)
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_fingerprint),
|
||||
|
||||
DrawerPrimaryItem().withName("HDR enable/disable")
|
||||
.withTag(0)
|
||||
.withIdentifier(63)
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withSelectable(false)
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_hdr),
|
||||
|
||||
DrawerPrimaryItem().withName("AdBlockPlus")
|
||||
.withDescription("Because we all hate ads")
|
||||
.withIdentifier(64)
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_adchoices),
|
||||
|
||||
DrawerPrimaryItem().withName("Wonderful browsing experience and this is a long string")
|
||||
.withIdentifier(65)
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_internet_explorer)
|
||||
)
|
||||
|
||||
setUnreadCount(2, 20, 30) // phil swift has 30 unreads on "Settings item"
|
||||
setUnreadCount(4, 40, 1000) // mark has 99+ unreads on "Lock screen item"
|
||||
|
||||
setAccountHeaderBackground("/sdcard/ban.gif")
|
||||
|
||||
appendProfiles(
|
||||
IDrawerProfile(1, "Think Pad", "think with a pad", "/sdcard/thinkpad.gif"),
|
||||
IDrawerProfile(2, "Phil Swift", "I sawed this boat in half!!!", "/sdcard/phil.jpg"),
|
||||
IDrawerProfile(3, "The meme bay", "Visit my amazing website", "/sdcard/loader.gif"),
|
||||
IDrawerProfile(4, "Mark Zuckerberg", "", null),
|
||||
IDrawerProfile(5, "I love GDPR", "spotify:user:popjustice:playlist:5Pe51v0sHLybSEkX0m0JRf", "/sdcard/tenor2.gif"),
|
||||
IDrawerProfile(6, "Gandalf", "http://sax.hol.es/", "/sdcard/facepalm.gif")
|
||||
)
|
||||
|
||||
addProfileSettings(
|
||||
ProfileSettingDrawerItem()
|
||||
.withName("Add Account")
|
||||
.withDescription("Add new GitHub Account")
|
||||
.withIcon(
|
||||
IconicsDrawable(context, CommunityMaterial.Icon2.cmd_plus)
|
||||
.actionBar()
|
||||
.padding(IconicsSize.dp(5))
|
||||
.color(IconicsColor.colorRes(pl.szczodrzynski.navlib.R.color.material_drawer_dark_primary_text))
|
||||
)
|
||||
.withOnDrawerItemClickListener(object : Drawer.OnDrawerItemClickListener {
|
||||
override fun onItemClick(view: View?, position: Int, drawerItem: IDrawerItem<*>): Boolean {
|
||||
Toast.makeText(context, "Add account", Toast.LENGTH_SHORT).show()
|
||||
return true
|
||||
}
|
||||
}),
|
||||
ProfileSettingDrawerItem()
|
||||
.withName("Manage Account")
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_settings)
|
||||
)
|
||||
|
||||
drawerItemSelectedListener = { id, position, drawerItem ->
|
||||
if (id == 1 || id == 2) {
|
||||
getItemById(id) {
|
||||
if (it is DrawerPrimaryItem) {
|
||||
if (it.tag !is Int) {
|
||||
it.tag = 0
|
||||
}
|
||||
it.tag = (it.tag as Int) + 1
|
||||
// TODO 2019-08-27 allow string to be passed as name
|
||||
it.name = StringHolder("Home ${it.tag as Int}")
|
||||
// do not set item.badge unless you're not using Unread Counters
|
||||
// because this *may* disappear/be overridden on profile change
|
||||
// (if UnreadCounterList have at least one counter with matching
|
||||
// drawer item ID)
|
||||
// See with "Settings" when it.badge AND UnreadCounter is present.
|
||||
//
|
||||
// just do not do this.
|
||||
it.badge = StringHolder("${it.tag as Int * 10}")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (id == 63) {
|
||||
getItemById(id) {
|
||||
if (it is DrawerPrimaryItem) {
|
||||
it.tag = if (it.tag as Int == 1) 0 else 1
|
||||
it.withIcon(if (it.tag as Int == 1) CommunityMaterial.Icon2.cmd_hdr_off else CommunityMaterial.Icon2.cmd_hdr)
|
||||
}
|
||||
}
|
||||
}
|
||||
// you cannot select apple
|
||||
id != 60
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
navView.bottomSheet.apply {
|
||||
this += PrimaryItem(true)
|
||||
this += BottomSheetPrimaryItem(true)
|
||||
.withId(1)
|
||||
.withTitle("Compose")
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_pencil)
|
||||
.withOnClickListener(View.OnClickListener {
|
||||
Toast.makeText(this@MainActivity, "Compose message", Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
this += SeparatorItem(false)
|
||||
this += PrimaryItem(false)
|
||||
this += BottomSheetSeparatorItem(false)
|
||||
this += BottomSheetPrimaryItem(false)
|
||||
.withId(3)
|
||||
.withTitle("Synchronise")
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_sync)
|
||||
.withOnClickListener(View.OnClickListener {
|
||||
Toast.makeText(this@MainActivity, "Synchronising...", Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
this += PrimaryItem(false)
|
||||
this += BottomSheetPrimaryItem(false)
|
||||
.withId(4)
|
||||
.withTitle("Help")
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_help)
|
||||
@ -233,6 +373,7 @@ class MainActivity : AppCompatActivity() {
|
||||
Toast.makeText(this@MainActivity, "Want some help?", Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
|
||||
toggleGroupEnabled = true
|
||||
toggleGroupTitle = "Sort by"
|
||||
toggleGroupRemoveItems()
|
||||
toggleGroupSelectionMode = TOGGLE_GROUP_SORTING_ORDER
|
||||
@ -240,16 +381,31 @@ class MainActivity : AppCompatActivity() {
|
||||
toggleGroupAddItem(1, "By subject", null, SORT_MODE_ASCENDING)
|
||||
toggleGroupAddItem(2, "By sender", null, SORT_MODE_ASCENDING)
|
||||
toggleGroupAddItem(3, "By android", null, SORT_MODE_ASCENDING)
|
||||
toggleGroupSortingOrderListener = object : NavBottomSheet.OnToggleGroupSortingListener {
|
||||
override fun onSortingOrder(id: Int, sortMode: Int) {
|
||||
Toast.makeText(
|
||||
this@MainActivity,
|
||||
"Sort mode $id ${if (sortMode == SORT_MODE_ASCENDING) "ascending" else "descending"}",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
toggleGroupSortingOrderListener = { id, sortMode ->
|
||||
Toast.makeText(
|
||||
this@MainActivity,
|
||||
"Sort mode $id ${if (sortMode == SORT_MODE_ASCENDING) "ascending" else "descending"}",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
toggleGroupCheck(1)
|
||||
|
||||
textInputEnabled = true
|
||||
textInputHint = "Search"
|
||||
textInputHelperText = "0 messages found"
|
||||
textInputIcon = CommunityMaterial.Icon2.cmd_magnify
|
||||
textInputChangedListener = object : NavBottomSheet.OnTextInputChangedListener {
|
||||
override fun onTextChanged(s: String, start: Int, before: Int, count: Int) {
|
||||
navView.toolbar.subtitle = s
|
||||
textInputError = if (s.length > 10) "Too many messages" else null
|
||||
textInputHelperText = "${s.length} messages found"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (!navView.onBackPressed())
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,9 @@
|
||||
android:id="@+id/navView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoTouch
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
@ -18,19 +21,25 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
tools:ignore="HardcodedText">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:id="@+id/themeButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:text="Switch theme" />
|
||||
<Button
|
||||
android:id="@+id/commitButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:text="Commit SystemBarsUtil" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="NavView config"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
android:textAppearance="@style/NavView.TextView.Large" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/switchToolbar"
|
||||
@ -71,7 +80,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="FAB config"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
android:textAppearance="@style/NavView.TextView.Large" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/fabPosition"
|
||||
@ -99,7 +108,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="BottomSheet config"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
android:textAppearance="@style/NavView.TextView.Large" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/bsEnable"
|
||||
@ -134,7 +143,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="System bars config"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
|
||||
android:textAppearance="@style/NavView.TextView.Large" />
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/appFullscreen"
|
||||
@ -147,12 +156,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Status bar color"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
android:textAppearance="@style/NavView.TextView.Medium" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="5.0+ with dark SB color, 6.0+" />
|
||||
android:text="5.0+ with dark SB color, 6.0+"
|
||||
android:textAppearance="@style/NavView.TextView.Small"/>
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/statusBarColor"
|
||||
@ -205,12 +215,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Status bar fallback if light"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
android:textAppearance="@style/NavView.TextView.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" />
|
||||
android:text="5.0 with SB color white, TouchWiz 4.1-4.3"
|
||||
android:textAppearance="@style/NavView.TextView.Small"/>
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/statusBarFallbackLight"
|
||||
@ -247,12 +258,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Status bar fallback if gradient"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
android:textAppearance="@style/NavView.TextView.Medium" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="4.4, 5.0 Huawei" />
|
||||
android:text="4.4, 5.0 Huawei"
|
||||
android:textAppearance="@style/NavView.TextView.Small"/>
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/statusBarFallbackGradient"
|
||||
@ -290,12 +302,13 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:text="SB color mode - translucent (not transparent)" />
|
||||
android:text="SB color mode - translucent (not transparent)"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="(used for Huawei with EMUI Lollipop)"/>
|
||||
android:text="(used for Huawei with EMUI Lollipop)"
|
||||
android:textAppearance="@style/NavView.TextView.Small"/>
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/navigationBarTransparent"
|
||||
@ -304,10 +317,255 @@
|
||||
android:checked="false"
|
||||
android:text="Nav bar fully transparent" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="NavView text appearances"
|
||||
android:textAppearance="@style/NavView.TextView.Large"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Default text appearance"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="NavView.TextView.Title"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/NavView.TextView.Title"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="NavView.TextView.Subtitle"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/NavView.TextView.Subtitle"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="NavView.TextView.Large"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/NavView.TextView.Large"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="NavView.TextView.Medium"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/NavView.TextView.Medium"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="NavView.TextView.Small"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/NavView.TextView.Small"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="This is a list of predefined text appearances"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large"/>
|
||||
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.AppCompat:"
|
||||
android:textAppearance="?textAppearanceHeadline6"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.AppCompat.Title"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Title"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.AppCompat.Subhead"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.AppCompat.Large"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.AppCompat.Medium"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.AppCompat.Small"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents:"
|
||||
android:textAppearance="?textAppearanceHeadline6"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Subtitle1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Subtitle2"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Body1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Body2"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Button"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Button" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Caption"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Headline1"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline1" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Headline2"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline2" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Headline3"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline3" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Headline4"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline4" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Headline5"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Headline6"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Overline"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Overline" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.Design.Error"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Design.Error" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.Design.Tab"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Design.Tab" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.Design.HelperText"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Design.HelperText" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.Design.Hint"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Design.Hint" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.Design.Counter"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Design.Counter" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.Design.Counter.Overflow"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Design.Counter.Overflow" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="TextAppearance.MaterialComponents.Badge"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Badge" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoTouch>
|
||||
|
||||
</pl.szczodrzynski.navlib.NavView>
|
||||
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
<item name="colorPrimary">#64b5f6</item>
|
||||
<item name="colorPrimaryDark">#1976d2</item>
|
||||
<item name="colorPrimaryVariant">#2196f3</item>
|
||||
<!--<item name="colorAccent">#ffb300</item>-->
|
||||
<item name="colorAccent">#2962ff</item>
|
||||
<item name="colorSecondary">?colorAccent</item>
|
||||
|
||||
@ -20,7 +19,6 @@
|
||||
<item name="colorPrimary">#2196f3</item>
|
||||
<item name="colorPrimaryDark">#1976d2</item>
|
||||
<item name="colorPrimaryVariant">#2196f3</item>
|
||||
<!--<item name="colorAccent">#ffb300</item>-->
|
||||
<item name="colorAccent">#2962ff</item>
|
||||
<item name="colorSecondary">?colorAccent</item>
|
||||
|
||||
|
@ -44,6 +44,7 @@ dependencies {
|
||||
implementation "com.mikepenz:materialdrawer:7.0.0-rc05"
|
||||
implementation "com.mikepenz:iconics-core:4.0.1-b01"
|
||||
implementation 'com.mikepenz:community-material-typeface:3.5.95.1-kotlin@aar'
|
||||
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.15'
|
||||
|
||||
implementation "androidx.appcompat:appcompat:${androidXAppCompat}"
|
||||
implementation "androidx.recyclerview:recyclerview:${androidXRecyclerView}"
|
||||
|
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
/**
|
||||
* The SwipeRefreshLayout should be used whenever the user can refresh the
|
||||
* contents of a view via a vertical swipe gesture. The activity that
|
||||
* instantiates this view should add an OnRefreshListener to be notified
|
||||
* whenever the swipe to refresh gesture is completed. The SwipeRefreshLayout
|
||||
* will notify the listener each and every time the gesture is completed again;
|
||||
* the listener is responsible for correctly determining when to actually
|
||||
* initiate a refresh of its content. If the listener determines there should
|
||||
* not be a refresh, it must call setRefreshing(false) to cancel any visual
|
||||
* indication of a refresh. If an activity wishes to show just the progress
|
||||
* animation, it should call setRefreshing(true). To disable the gesture and
|
||||
* progress animation, call setEnabled(false) on the view.
|
||||
* <p>
|
||||
* This layout should be made the parent of the view that will be refreshed as a
|
||||
* result of the gesture and can only support one direct child. This view will
|
||||
* also be made the target of the gesture and will be forced to match both the
|
||||
* width and the height supplied in this layout. The SwipeRefreshLayout does not
|
||||
* provide accessibility events; instead, a menu item must be provided to allow
|
||||
* refresh of the content wherever this gesture is used.
|
||||
* </p>
|
||||
*/
|
||||
public class SwipeRefreshLayoutNoIndicator extends SwipeRefreshLayout {
|
||||
|
||||
private SwipeRefreshLayoutNoTouch parent;
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
if (parent == null)
|
||||
return;
|
||||
parent.setEnabled(enabled);
|
||||
super.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public void setParent(SwipeRefreshLayoutNoTouch parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple constructor to use when creating a SwipeRefreshLayout from code.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public SwipeRefreshLayoutNoIndicator(@NonNull Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that is called when inflating SwipeRefreshLayout from XML.
|
||||
*
|
||||
* @param context
|
||||
* @param attrs
|
||||
*/
|
||||
public SwipeRefreshLayoutNoIndicator(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
ev.setSource(0x10000000);
|
||||
boolean parentConsumed = parent.onInterceptTouchEvent(ev);
|
||||
boolean superConsumed = super.onInterceptTouchEvent(ev);
|
||||
return parentConsumed && superConsumed;
|
||||
/*if (super.onInterceptTouchEvent(ev))
|
||||
return parent.onInterceptTouchEvent(ev);
|
||||
return false;*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestDisallowInterceptTouchEvent(boolean b) {
|
||||
parent.requestDisallowInterceptTouchEvent(b);
|
||||
}
|
||||
|
||||
// NestedScrollingParent
|
||||
|
||||
@Override
|
||||
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
|
||||
parent.onStartNestedScroll(child, target, nestedScrollAxes);
|
||||
return !parent.isRefreshing() && super.onStartNestedScroll(child, target, nestedScrollAxes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNestedScrollAccepted(View child, View target, int axes) {
|
||||
parent.onNestedScrollAccepted(child, target, axes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
|
||||
parent.onNestedPreScroll(target, dx, dy, consumed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNestedScrollAxes() {
|
||||
return parent.getNestedScrollAxes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopNestedScroll(View target) {
|
||||
parent.onStopNestedScroll(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNestedScroll(final View target, final int dxConsumed, final int dyConsumed,
|
||||
final int dxUnconsumed, final int dyUnconsumed) {
|
||||
parent.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
|
||||
}
|
||||
|
||||
// NestedScrollingChild
|
||||
|
||||
@Override
|
||||
public void setNestedScrollingEnabled(boolean enabled) {
|
||||
if (parent == null)
|
||||
return;
|
||||
//parent.setNestedScrollingEnabled(enabled);
|
||||
super.setNestedScrollingEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNestedScrollingEnabled() {
|
||||
return parent.isNestedScrollingEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startNestedScroll(int axes) {
|
||||
return parent.startNestedScroll(axes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopNestedScroll() {
|
||||
parent.stopNestedScroll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNestedScrollingParent() {
|
||||
return parent.hasNestedScrollingParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
|
||||
int dyUnconsumed, int[] offsetInWindow) {
|
||||
return super.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
|
||||
return super.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNestedPreFling(View target, float velocityX,
|
||||
float velocityY) {
|
||||
return parent.onNestedPreFling(target, velocityX, velocityY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNestedFling(View target, float velocityX, float velocityY,
|
||||
boolean consumed) {
|
||||
return parent.onNestedFling(target, velocityX, velocityY, consumed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
|
||||
return parent.dispatchNestedFling(velocityX, velocityY, consumed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
|
||||
return parent.dispatchNestedPreFling(velocityX, velocityY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
ev.setSource(0x10000000);
|
||||
/*boolean consumed = super.onTouchEvent(ev);
|
||||
if (consumed) {
|
||||
return false;
|
||||
}*/
|
||||
return parent.onTouchEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -7,7 +7,6 @@ import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
|
@ -0,0 +1,279 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewOutlineProvider
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.mikepenz.materialdrawer.R
|
||||
import com.mikepenz.materialdrawer.util.DrawerImageLoader
|
||||
import pl.droidsonroids.gif.GifImageView
|
||||
|
||||
|
||||
/**
|
||||
* An [android.widget.ImageView] that draws its contents inside a mask and draws a border
|
||||
* drawable on top. This is useful for applying a beveled look to image contents, but is also
|
||||
* flexible enough for use with other desired aesthetics.
|
||||
*/
|
||||
open class BezelGifImageView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : GifImageView(context, attrs, defStyle) {
|
||||
private val mBlackPaint: Paint
|
||||
private val mMaskedPaint: Paint
|
||||
|
||||
private var mBounds: Rect? = null
|
||||
private var mBoundsF: RectF? = null
|
||||
|
||||
private val mMaskDrawable: Drawable?
|
||||
private var mDrawCircularShadow = true
|
||||
|
||||
private var mDesaturateColorFilter: ColorMatrixColorFilter? = null
|
||||
|
||||
private val mSelectorAlpha = 150
|
||||
private var mSelectorColor: Int = 0
|
||||
private var mSelectorFilter: ColorFilter? = null
|
||||
|
||||
private var mCacheValid = false
|
||||
private var mCacheBitmap: Bitmap
|
||||
private var mCachedWidth: Int = 0
|
||||
private var mCachedHeight: Int = 0
|
||||
|
||||
private var mIsPressed = false
|
||||
private var mIsSelected: Boolean = false
|
||||
|
||||
private var mTempDesaturateColorFilter: ColorMatrixColorFilter? = null
|
||||
private var mTempSelectorFilter: ColorFilter? = null
|
||||
|
||||
init {
|
||||
|
||||
// Attribute initialization
|
||||
val a = context.obtainStyledAttributes(attrs, R.styleable.BezelImageView, defStyle, R.style.BezelImageView)
|
||||
|
||||
mMaskDrawable = a.getDrawable(R.styleable.BezelImageView_biv_maskDrawable)
|
||||
if (mMaskDrawable != null) {
|
||||
mMaskDrawable.callback = this
|
||||
}
|
||||
|
||||
mDrawCircularShadow = a.getBoolean(R.styleable.BezelImageView_biv_drawCircularShadow, true)
|
||||
|
||||
mSelectorColor = a.getColor(R.styleable.BezelImageView_biv_selectorOnPress, 0)
|
||||
|
||||
a.recycle()
|
||||
|
||||
// Other initialization
|
||||
mBlackPaint = Paint()
|
||||
mBlackPaint.color = -0x1000000
|
||||
|
||||
mMaskedPaint = Paint()
|
||||
mMaskedPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
|
||||
|
||||
// Always want a cache allocated.
|
||||
mCacheBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
|
||||
|
||||
// Create a desaturate color filter for pressed state.
|
||||
val cm = ColorMatrix()
|
||||
cm.setSaturation(0f)
|
||||
mDesaturateColorFilter = ColorMatrixColorFilter(cm)
|
||||
|
||||
//create a selectorFilter if we already have a color
|
||||
if (mSelectorColor != 0) {
|
||||
this.mSelectorFilter = PorterDuffColorFilter(Color.argb(mSelectorAlpha, Color.red(mSelectorColor), Color.green(mSelectorColor), Color.blue(mSelectorColor)), PorterDuff.Mode.SRC_ATOP)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, old_w: Int, old_h: Int) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (mDrawCircularShadow) {
|
||||
outlineProvider = CustomOutline(w, h)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(21)
|
||||
private inner class CustomOutline internal constructor(internal var width: Int, internal var height: Int) : ViewOutlineProvider() {
|
||||
|
||||
override fun getOutline(view: View, outline: Outline) {
|
||||
outline.setOval(0, 0, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setFrame(l: Int, t: Int, r: Int, b: Int): Boolean {
|
||||
val changed = super.setFrame(l, t, r, b)
|
||||
mBounds = Rect(0, 0, r - l, b - t).also {
|
||||
mBoundsF = RectF(it)
|
||||
|
||||
if (mMaskDrawable != null) {
|
||||
mMaskDrawable.bounds = it
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
mCacheValid = false
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
val bounds = mBounds ?: return
|
||||
|
||||
val width = bounds.width()
|
||||
val height = bounds.height()
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!mCacheValid || width != mCachedWidth || height != mCachedHeight || mIsSelected != mIsPressed) {
|
||||
// Need to redraw the cache
|
||||
if (width == mCachedWidth && height == mCachedHeight) {
|
||||
// Have a correct-sized bitmap cache already allocated. Just erase it.
|
||||
mCacheBitmap.eraseColor(0)
|
||||
} else {
|
||||
// Allocate a new bitmap with the correct dimensions.
|
||||
mCacheBitmap.recycle()
|
||||
|
||||
mCacheBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
mCachedWidth = width
|
||||
mCachedHeight = height
|
||||
}
|
||||
|
||||
val cacheCanvas = Canvas(mCacheBitmap)
|
||||
|
||||
when {
|
||||
mMaskDrawable != null -> {
|
||||
val sc = cacheCanvas.save()
|
||||
mMaskDrawable.draw(cacheCanvas)
|
||||
if (mIsSelected) {
|
||||
if (mSelectorFilter != null) {
|
||||
mMaskedPaint.colorFilter = mSelectorFilter
|
||||
} else {
|
||||
mMaskedPaint.colorFilter = mDesaturateColorFilter
|
||||
|
||||
}
|
||||
} else {
|
||||
mMaskedPaint.colorFilter = null
|
||||
}
|
||||
cacheCanvas.saveLayer(mBoundsF, mMaskedPaint, Canvas.ALL_SAVE_FLAG)
|
||||
super.onDraw(cacheCanvas)
|
||||
cacheCanvas.restoreToCount(sc)
|
||||
}
|
||||
mIsSelected -> {
|
||||
val sc = cacheCanvas.save()
|
||||
cacheCanvas.drawRect(0f, 0f, mCachedWidth.toFloat(), mCachedHeight.toFloat(), mBlackPaint)
|
||||
if (mSelectorFilter != null) {
|
||||
mMaskedPaint.colorFilter = mSelectorFilter
|
||||
} else {
|
||||
mMaskedPaint.colorFilter = mDesaturateColorFilter
|
||||
}
|
||||
cacheCanvas.saveLayer(mBoundsF, mMaskedPaint, Canvas.ALL_SAVE_FLAG)
|
||||
super.onDraw(cacheCanvas)
|
||||
cacheCanvas.restoreToCount(sc)
|
||||
}
|
||||
else -> super.onDraw(cacheCanvas)
|
||||
}
|
||||
}
|
||||
|
||||
// Draw from cache
|
||||
canvas.drawBitmap(mCacheBitmap, bounds.left.toFloat(), bounds.top.toFloat(), null)
|
||||
|
||||
//remember the previous press state
|
||||
mIsPressed = isPressed
|
||||
}
|
||||
|
||||
|
||||
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
|
||||
// Check for clickable state and do nothing if disabled
|
||||
if (!this.isClickable) {
|
||||
this.mIsSelected = false
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
|
||||
// Set selected state based on Motion Event
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> this.mIsSelected = true
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_SCROLL, MotionEvent.ACTION_OUTSIDE, MotionEvent.ACTION_CANCEL -> this.mIsSelected = false
|
||||
}
|
||||
|
||||
// Redraw image and return super type
|
||||
this.invalidate()
|
||||
return super.dispatchTouchEvent(event)
|
||||
}
|
||||
|
||||
override fun drawableStateChanged() {
|
||||
super.drawableStateChanged()
|
||||
if (mMaskDrawable != null && mMaskDrawable.isStateful) {
|
||||
mMaskDrawable.state = drawableState
|
||||
}
|
||||
if (isDuplicateParentStateEnabled) {
|
||||
ViewCompat.postInvalidateOnAnimation(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun invalidateDrawable(who: Drawable) {
|
||||
if (who === mMaskDrawable) {
|
||||
invalidate()
|
||||
} else {
|
||||
super.invalidateDrawable(who)
|
||||
}
|
||||
}
|
||||
|
||||
override fun verifyDrawable(who: Drawable): Boolean {
|
||||
return who === mMaskDrawable || super.verifyDrawable(who)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the color of the selector to be draw over the
|
||||
* CircularImageView. Be sure to provide some opacity.
|
||||
*
|
||||
* @param selectorColor The color (including alpha) to set for the selector overlay.
|
||||
*/
|
||||
fun setSelectorColor(selectorColor: Int) {
|
||||
this.mSelectorColor = selectorColor
|
||||
this.mSelectorFilter = PorterDuffColorFilter(Color.argb(mSelectorAlpha, Color.red(mSelectorColor), Color.green(mSelectorColor), Color.blue(mSelectorColor)), PorterDuff.Mode.SRC_ATOP)
|
||||
this.invalidate()
|
||||
}
|
||||
|
||||
|
||||
override fun setImageDrawable(drawable: Drawable?) {
|
||||
super.setImageDrawable(drawable)
|
||||
}
|
||||
|
||||
override fun setImageResource(resId: Int) {
|
||||
super.setImageResource(resId)
|
||||
}
|
||||
|
||||
override fun setImageBitmap(bm: Bitmap) {
|
||||
super.setImageBitmap(bm)
|
||||
}
|
||||
|
||||
override fun setImageURI(uri: Uri?) {
|
||||
if ("http" == uri?.scheme || "https" == uri?.scheme) {
|
||||
DrawerImageLoader.instance.setImage(this, uri, null)
|
||||
} else {
|
||||
super.setImageURI(uri)
|
||||
}
|
||||
}
|
||||
|
||||
fun disableTouchFeedback(disable: Boolean) {
|
||||
if (disable) {
|
||||
mTempDesaturateColorFilter = this.mDesaturateColorFilter
|
||||
mTempSelectorFilter = this.mSelectorFilter
|
||||
this.mSelectorFilter = null
|
||||
this.mDesaturateColorFilter = null
|
||||
} else {
|
||||
if (mTempDesaturateColorFilter != null) {
|
||||
this.mDesaturateColorFilter = mTempDesaturateColorFilter
|
||||
}
|
||||
if (mTempSelectorFilter != null) {
|
||||
this.mSelectorFilter = mTempSelectorFilter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.view.View
|
||||
import com.mikepenz.materialdrawer.*
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
||||
|
||||
fun DrawerBuilder.withOnDrawerItemClickListener(listener: (view: View?, position: Int, drawerItem: IDrawerItem<*>) -> Boolean): DrawerBuilder {
|
||||
return this.withOnDrawerItemClickListener(object : Drawer.OnDrawerItemClickListener {
|
||||
override fun onItemClick(view: View?, position: Int, drawerItem: IDrawerItem<*>): Boolean {
|
||||
return listener(view, position, drawerItem)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun DrawerBuilder.withOnDrawerItemLongClickListener(listener: (view: View, position: Int, drawerItem: IDrawerItem<*>) -> Boolean): DrawerBuilder {
|
||||
return this.withOnDrawerItemLongClickListener(object : Drawer.OnDrawerItemLongClickListener {
|
||||
override fun onItemLongClick(view: View, position: Int, drawerItem: IDrawerItem<*>): Boolean {
|
||||
return listener(view, position, drawerItem)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun AccountHeaderBuilder.withOnAccountHeaderListener(listener: (view: View?, profile: IProfile<*>, current: Boolean) -> Boolean): AccountHeaderBuilder {
|
||||
return this.withOnAccountHeaderListener(object : AccountHeader.OnAccountHeaderListener {
|
||||
override fun onProfileChanged(view: View?, profile: IProfile<*>, current: Boolean): Boolean {
|
||||
return listener(view, profile, current)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun AccountHeaderBuilder.withOnAccountHeaderItemLongClickListener(listener: (view: View, profile: IProfile<*>, current: Boolean) -> Boolean): AccountHeaderBuilder {
|
||||
return this.withOnAccountHeaderItemLongClickListener(object : AccountHeader.OnAccountHeaderItemLongClickListener {
|
||||
override fun onProfileLongClick(view: View, profile: IProfile<*>, current: Boolean): Boolean {
|
||||
return listener(view, profile, current)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun AccountHeaderBuilder.withOnAccountHeaderProfileImageListener(
|
||||
onClick: (
|
||||
view: View,
|
||||
profile: IProfile<*>,
|
||||
current: Boolean
|
||||
) -> Boolean,
|
||||
onLongClick: (
|
||||
view: View,
|
||||
profile: IProfile<*>,
|
||||
current: Boolean
|
||||
) -> Boolean
|
||||
): AccountHeaderBuilder {
|
||||
return this.withOnAccountHeaderProfileImageListener(object : AccountHeader.OnAccountHeaderProfileImageListener {
|
||||
override fun onProfileImageClick(view: View, profile: IProfile<*>, current: Boolean): Boolean {
|
||||
return onClick(view, profile, current)
|
||||
}
|
||||
override fun onProfileImageLongClick(view: View, profile: IProfile<*>, current: Boolean): Boolean {
|
||||
return onLongClick(view, profile, current)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun MiniDrawer.withOnMiniDrawerItemClickListener(listener: (view: View?, position: Int, drawerItem: IDrawerItem<*>, type: Int) -> Boolean): MiniDrawer {
|
||||
return this.withOnMiniDrawerItemClickListener(object : MiniDrawer.OnMiniDrawerItemClickListener {
|
||||
override fun onItemClick(view: View?, position: Int, drawerItem: IDrawerItem<*>, type: Int): Boolean {
|
||||
return listener(view, position, drawerItem, type)
|
||||
}
|
||||
})
|
||||
}
|
74
navlib/src/main/java/pl/szczodrzynski/navlib/ImageHolder.kt
Normal file
74
navlib/src/main/java/pl/szczodrzynski/navlib/ImageHolder.kt
Normal file
@ -0,0 +1,74 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import com.mikepenz.iconics.IconicsColor
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.IconicsSize
|
||||
import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.mikepenz.materialdrawer.util.DrawerImageLoader
|
||||
import pl.droidsonroids.gif.GifDrawable
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
/**
|
||||
* Created by mikepenz on 13.07.15.
|
||||
*/
|
||||
|
||||
open class ImageHolder : com.mikepenz.materialdrawer.holder.ImageHolder {
|
||||
|
||||
constructor(url: String) : super(url) {}
|
||||
|
||||
constructor(uri: Uri) : super(uri) {}
|
||||
|
||||
constructor(icon: Drawable?) : super(icon) {}
|
||||
|
||||
constructor(bitmap: Bitmap?) : super(bitmap) {}
|
||||
|
||||
constructor(@DrawableRes iconRes: Int) : super(iconRes) {}
|
||||
|
||||
constructor(iicon: IIcon) : super(null as Bitmap?) {
|
||||
this.iIcon = iicon
|
||||
}
|
||||
|
||||
/**
|
||||
* sets an existing image to the imageView
|
||||
*
|
||||
* @param imageView
|
||||
* @param tag used to identify imageViews and define different placeholders
|
||||
* @return true if an image was set
|
||||
*/
|
||||
override fun applyTo(imageView: ImageView, tag: String?): Boolean {
|
||||
val ii = iIcon
|
||||
|
||||
if (uri != null) {
|
||||
if (uri.toString().endsWith(".gif", true)) {
|
||||
imageView.setImageDrawable(GifDrawable(uri.toString()))
|
||||
}
|
||||
else {
|
||||
val consumed = DrawerImageLoader.instance.setImage(imageView, uri, tag)
|
||||
if (!consumed) {
|
||||
imageView.setImageURI(uri)
|
||||
}
|
||||
}
|
||||
} else if (icon != null) {
|
||||
imageView.setImageDrawable(icon)
|
||||
} else if (bitmap != null) {
|
||||
imageView.setImageBitmap(bitmap)
|
||||
} else if (iconRes != -1) {
|
||||
imageView.setImageResource(iconRes)
|
||||
} else if (ii != null) {
|
||||
imageView.setImageDrawable(IconicsDrawable(imageView.context, ii).actionBar())
|
||||
} else {
|
||||
imageView.setImageBitmap(null)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
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
|
||||
@ -15,8 +14,8 @@ import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import com.mikepenz.materialdrawer.Drawer
|
||||
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
|
||||
import pl.szczodrzynski.navlib.drawer.NavDrawer
|
||||
|
||||
class NavBottomBar : BottomAppBar {
|
||||
constructor(context: Context) : super(context) {
|
||||
@ -31,7 +30,7 @@ class NavBottomBar : BottomAppBar {
|
||||
create(attrs, defStyle)
|
||||
}
|
||||
|
||||
var drawer: Drawer? = null
|
||||
var drawer: NavDrawer? = null
|
||||
var bottomSheet: NavBottomSheet? = null
|
||||
var fabView: FloatingActionButton? = null
|
||||
var fabExtendedView: ExtendedFloatingActionButton? = null
|
||||
@ -127,10 +126,7 @@ class NavBottomBar : BottomAppBar {
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
|
||||
setNavigationOnClickListener {
|
||||
if (drawer?.isDrawerOpen == true)
|
||||
drawer?.closeDrawer()
|
||||
else
|
||||
drawer?.openDrawer()
|
||||
drawer?.toggle()
|
||||
}
|
||||
|
||||
super.setOnMenuItemClickListener {
|
||||
|
@ -1,44 +1,46 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Configuration.ORIENTATION_PORTRAIT
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.SeekBar
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
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.edziennik.utils.SwipeRefreshLayoutNoTouch
|
||||
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
|
||||
import pl.szczodrzynski.navlib.drawer.NavDrawer
|
||||
|
||||
|
||||
class NavView : FrameLayout {
|
||||
companion object {
|
||||
const val SOURCE_OTHER = 0
|
||||
const val SOURCE_DRAWER = 1
|
||||
const val SOURCE_BOTTOM_SHEET = 1
|
||||
}
|
||||
|
||||
private var contentView: LinearLayout? = null
|
||||
|
||||
private lateinit var statusBarBackground: View
|
||||
private lateinit var navigationBarBackground: View
|
||||
private lateinit var mainView: CoordinatorLayout
|
||||
private lateinit var mainView: LinearLayout
|
||||
private lateinit var floatingActionButton: FloatingActionButton
|
||||
private lateinit var extendedFloatingActionButton: ExtendedFloatingActionButton
|
||||
|
||||
var drawer: Drawer? = null
|
||||
lateinit var topBar: NavToolbar
|
||||
lateinit var drawer: NavDrawer
|
||||
lateinit var toolbar: NavToolbar
|
||||
lateinit var bottomBar: NavBottomBar
|
||||
lateinit var bottomSheet: NavBottomSheet
|
||||
|
||||
|
||||
var navigationLoader: NavigationLoader? = null
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
create(null, 0)
|
||||
@ -71,33 +73,36 @@ class NavView : FrameLayout {
|
||||
floatingActionButton = findViewById(R.id.nv_floatingActionButton)
|
||||
extendedFloatingActionButton = findViewById(R.id.nv_extendedFloatingActionButton)
|
||||
|
||||
topBar = findViewById(R.id.nv_toolbar)
|
||||
drawer = NavDrawer(
|
||||
context,
|
||||
findViewById(R.id.nv_drawerContainer),
|
||||
findViewById(R.id.nv_fixedDrawerContainer),
|
||||
findViewById(R.id.nv_miniDrawerContainerLandscape),
|
||||
findViewById(R.id.nv_miniDrawerContainerPortrait)
|
||||
)
|
||||
toolbar = findViewById(R.id.nv_toolbar)
|
||||
bottomBar = findViewById(R.id.nv_bottomBar)
|
||||
bottomSheet = findViewById(R.id.nv_bottomSheet)
|
||||
|
||||
drawer.toolbar = toolbar
|
||||
drawer.bottomBar = bottomBar
|
||||
|
||||
bottomBar.drawer = drawer
|
||||
bottomBar.bottomSheet = bottomSheet
|
||||
bottomBar.fabView = floatingActionButton
|
||||
bottomBar.fabExtendedView = extendedFloatingActionButton
|
||||
|
||||
//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 * context.resources.displayMetrics.density
|
||||
}
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
|
||||
})
|
||||
}
|
||||
|
||||
fun configSystemBarsUtil(systemBarsUtil: SystemBarsUtil) {
|
||||
this.systemBarsUtil = systemBarsUtil
|
||||
systemBarsUtil.statusBarBgView = statusBarBackground
|
||||
systemBarsUtil.navigationBarBgView = navigationBarBackground
|
||||
systemBarsUtil.statusBarDarkView = nv_statusBarDarker
|
||||
//systemBarsUtil.navigationBarDarkView = navigationBarBackground
|
||||
systemBarsUtil.paddingBySystemBars = mainView
|
||||
systemBarsUtil.insetsListener = nv_drawerContainer
|
||||
systemBarsUtil.marginBySystemBars = mainView
|
||||
systemBarsUtil.paddingByNavigationBar = bottomSheet.getContentView()
|
||||
}
|
||||
|
||||
@ -118,7 +123,7 @@ class NavView : FrameLayout {
|
||||
* below the toolbar.
|
||||
*/
|
||||
var showToolbar = true; set(value) {
|
||||
topBar.visibility = if (value) View.VISIBLE else View.GONE
|
||||
toolbar.visibility = if (value) View.VISIBLE else View.GONE
|
||||
field = value
|
||||
setContentMargins()
|
||||
}
|
||||
@ -131,13 +136,7 @@ class NavView : FrameLayout {
|
||||
extendedFloatingActionButton.setOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
fun init(activity: Activity) {
|
||||
|
||||
}
|
||||
var systemBarsUtil: SystemBarsUtil? = null
|
||||
|
||||
private fun setContentMargins() {
|
||||
val layoutParams = CoordinatorLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||
@ -147,33 +146,37 @@ class NavView : FrameLayout {
|
||||
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").withIcon(CommunityMaterial.Icon.cmd_google_home)
|
||||
val item2 = SecondaryDrawerItem().withIdentifier(2).withName("Settings").withIcon(CommunityMaterial.Icon2.cmd_settings)
|
||||
override fun onConfigurationChanged(newConfig: Configuration?) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
|
||||
drawer = DrawerBuilder(activity)
|
||||
.withDrawerLayout(R.layout.material_drawer_fits_not)
|
||||
.withRootView(R.id.nv_drawerContainer)
|
||||
.withFullscreen(true)
|
||||
.withTranslucentStatusBar(false)
|
||||
.withTranslucentNavigationBar(false)
|
||||
.withTranslucentNavigationBarProgrammatically(false)
|
||||
.withToolbar(bottomBar)
|
||||
.withDisplayBelowStatusBar(true)
|
||||
.withActionBarDrawerToggleAnimated(true)
|
||||
.addDrawerItems(
|
||||
item1,
|
||||
DividerDrawerItem(),
|
||||
item2,
|
||||
SecondaryDrawerItem().withName("Settings")
|
||||
)
|
||||
/*.withOnDrawerItemClickListener { view, position, drawerItem ->
|
||||
true
|
||||
}*/
|
||||
.build()
|
||||
Log.d(
|
||||
"NavLib",
|
||||
"CONFIGURATION CHANGED: ${newConfig?.screenWidthDp}x${newConfig?.screenHeightDp} "+if (newConfig?.orientation == ORIENTATION_PORTRAIT) "portrait" else "landscape"
|
||||
)
|
||||
|
||||
bottomBar.drawer = drawer
|
||||
systemBarsUtil?.commit()
|
||||
|
||||
drawer.decideDrawerMode(
|
||||
newConfig?.orientation ?: ORIENTATION_PORTRAIT,
|
||||
newConfig?.screenWidthDp ?: 0,
|
||||
newConfig?.screenHeightDp ?: 0
|
||||
)
|
||||
}
|
||||
|
||||
fun onBackPressed(): Boolean {
|
||||
if (drawer.isOpen) {
|
||||
if (drawer.profileSelectionIsOpen) {
|
||||
drawer.profileSelectionClose()
|
||||
return true
|
||||
}
|
||||
drawer.close()
|
||||
return true
|
||||
}
|
||||
if (bottomSheet.isOpen) {
|
||||
bottomSheet.close()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
|
||||
|
@ -0,0 +1,5 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
interface NavigationLoader {
|
||||
fun load(itemId: Int, callerId: Int, source: Int, args: Map<String, Any?>)
|
||||
}
|
@ -11,6 +11,7 @@ import android.view.View
|
||||
import android.view.View.*
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import android.widget.Toast
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.mikepenz.materialize.util.KeyboardUtil
|
||||
@ -36,8 +37,6 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
*/
|
||||
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
|
||||
@ -59,7 +58,7 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
*
|
||||
* This means it will display under the system bars
|
||||
* and you should probably provide [statusBarBgView],
|
||||
* [navigationBarBgView] and [paddingBySystemBars].
|
||||
* [navigationBarBgView] and [marginBySystemBars].
|
||||
*/
|
||||
var appFullscreen = false
|
||||
|
||||
@ -126,13 +125,17 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
var navigationBarDarkView: View? = null
|
||||
|
||||
/**
|
||||
* A view which will have the padding added not to overlap with the status/nav bar.
|
||||
* A view which will have the margin added not to overlap with the status/nav bar.
|
||||
*/
|
||||
var paddingBySystemBars: View? = null
|
||||
var marginBySystemBars: View? = null
|
||||
/**
|
||||
* A view which will listen to the inset applying.
|
||||
*/
|
||||
var insetsListener: View? = null
|
||||
/**
|
||||
* A view which will have the padding added not to overlap with the nav bar.
|
||||
* Useful for persistent bottom sheets.
|
||||
* Requires [paddingBySystemBars].
|
||||
* Requires [marginBySystemBars].
|
||||
*/
|
||||
var paddingByNavigationBar: View? = null
|
||||
|
||||
@ -140,6 +143,8 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
private var insetsApplied = false
|
||||
|
||||
fun commit() {
|
||||
Log.d("NavLib", "SystemBarsUtil applying")
|
||||
insetsApplied = false
|
||||
if (paddingByKeyboard != null) {
|
||||
// thanks mikepenz for this life-saving class
|
||||
keyboardUtil = KeyboardUtil(activity, paddingByKeyboard)
|
||||
@ -289,11 +294,14 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
}
|
||||
|
||||
// PADDING
|
||||
if (paddingBySystemBars != null) {
|
||||
if (insetsListener != null) {
|
||||
if (SDK_INT >= LOLLIPOP) {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(paddingBySystemBars!!) { _, insets ->
|
||||
ViewCompat.setOnApplyWindowInsetsListener(insetsListener!!) { _, insets ->
|
||||
Toast.makeText(activity, "Insets applied ", Toast.LENGTH_SHORT).show()
|
||||
Log.d("NavLib", "Got insets left = ${insets.systemWindowInsetLeft}, top = ${insets.systemWindowInsetTop}, right = ${insets.systemWindowInsetRight}, bottom = ${insets.systemWindowInsetBottom}")
|
||||
if (insetsApplied)
|
||||
return@setOnApplyWindowInsetsListener insets.consumeSystemWindowInsets()
|
||||
Log.d("NavLib", "Applied insets left = ${insets.systemWindowInsetLeft}, top = ${insets.systemWindowInsetTop}, right = ${insets.systemWindowInsetRight}, bottom = ${insets.systemWindowInsetBottom}")
|
||||
insetsApplied = true
|
||||
applyPadding(
|
||||
insets.systemWindowInsetLeft,
|
||||
@ -313,7 +321,7 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
|
||||
|
||||
var navigationBarSize = 0
|
||||
if (hasNavigationBar(resources) && targetAppFullscreen) {
|
||||
if (hasNavigationBar(activity) && targetAppFullscreen) {
|
||||
val orientation = resources.configuration.orientation
|
||||
|
||||
val navigationBarRes = when {
|
||||
@ -346,7 +354,7 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
}
|
||||
|
||||
private fun applyPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||
paddingBySystemBars?.setPadding(left, top, right, bottom)
|
||||
marginBySystemBars?.setPadding(left, top, right, bottom)
|
||||
|
||||
statusBarBgView?.layoutParams?.height = top
|
||||
navigationBarBgView?.layoutParams?.height = bottom
|
||||
|
@ -13,6 +13,18 @@ import androidx.annotation.DrawableRes
|
||||
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||
import com.mikepenz.iconics.IconicsColor
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.Display
|
||||
import android.view.WindowManager
|
||||
import android.R.attr.y
|
||||
import android.R.attr.x
|
||||
import android.graphics.Point
|
||||
import com.mikepenz.materialdrawer.Drawer
|
||||
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||
import com.mikepenz.materialdrawer.model.BaseDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.Badgeable
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
||||
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
||||
|
||||
|
||||
/*private val displayMetrics by lazy {
|
||||
@ -90,9 +102,27 @@ fun isTablet(c: Context): Boolean {
|
||||
return (c.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
|
||||
}
|
||||
|
||||
fun hasNavigationBar(resources: Resources): Boolean {
|
||||
val id = resources.getIdentifier("config_showNavigationBar", "bool", "android")
|
||||
var hasNavigationBar = id > 0 && resources.getBoolean(id)
|
||||
fun hasNavigationBar(context: Context): Boolean {
|
||||
val id = context.resources.getIdentifier("config_showNavigationBar", "bool", "android")
|
||||
var hasNavigationBar = id > 0 && context.resources.getBoolean(id)
|
||||
|
||||
if (!hasNavigationBar && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
val d = (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay
|
||||
|
||||
val realDisplayMetrics = DisplayMetrics()
|
||||
d.getRealMetrics(realDisplayMetrics)
|
||||
|
||||
val realHeight = realDisplayMetrics.heightPixels
|
||||
val realWidth = realDisplayMetrics.widthPixels
|
||||
|
||||
val displayMetrics = DisplayMetrics()
|
||||
d.getMetrics(displayMetrics)
|
||||
|
||||
val displayHeight = displayMetrics.heightPixels
|
||||
val displayWidth = displayMetrics.widthPixels
|
||||
|
||||
hasNavigationBar = realWidth - displayWidth > 0 || realHeight - displayHeight > 0
|
||||
}
|
||||
|
||||
// Allow a system property to override this. Used by the emulator.
|
||||
// See also hasNavigationBar().
|
||||
@ -113,4 +143,12 @@ fun Context.getDrawableFromRes(@DrawableRes id: Int): Drawable {
|
||||
else {
|
||||
resources.getDrawable(id)
|
||||
}
|
||||
}
|
||||
|
||||
fun Drawer.updateBadge(identifier: Long, badge: StringHolder?) {
|
||||
val drawerItem = getDrawerItem(identifier)
|
||||
if (drawerItem is Badgeable<*>) {
|
||||
drawerItem.withBadge(badge)
|
||||
updateItem(drawerItem)
|
||||
}
|
||||
}
|
@ -3,10 +3,9 @@ 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
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
|
||||
class BottomSheetAdapter(val items: List<IBottomSheetItem<*>>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
@ -14,13 +13,10 @@ class BottomSheetAdapter(val items: List<IBottomSheetItem<*>>) : RecyclerView.Ad
|
||||
|
||||
init {
|
||||
viewHolderProvider.registerViewHolderFactory(1, R.layout.nav_bs_item_primary) { itemView ->
|
||||
PrimaryItem.ViewHolder(itemView)
|
||||
BottomSheetPrimaryItem.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)
|
||||
BottomSheetSeparatorItem.ViewHolder(itemView)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,9 @@ import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.system.Os.close
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
@ -21,17 +24,17 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.button.MaterialButtonToggleGroup
|
||||
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.paddingDp
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import pl.szczodrzynski.navlib.Anim
|
||||
import pl.szczodrzynski.navlib.R
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
||||
import pl.szczodrzynski.navlib.*
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.IBottomSheetItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.SeparatorItem
|
||||
import pl.szczodrzynski.navlib.elevateSurface
|
||||
import pl.szczodrzynski.navlib.getDrawableFromRes
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
|
||||
|
||||
class NavBottomSheet : CoordinatorLayout {
|
||||
@ -60,6 +63,8 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
private lateinit var bottomSheet: NestedScrollView
|
||||
private lateinit var content: LinearLayout
|
||||
private lateinit var dragBar: View
|
||||
private lateinit var textInputLayout: TextInputLayout
|
||||
private lateinit var textInputEditText: TextInputEditText
|
||||
private lateinit var toggleGroupContainer: LinearLayout
|
||||
private lateinit var toggleGroup: MaterialButtonToggleGroup
|
||||
private lateinit var toggleGroupTitleView: TextView
|
||||
@ -68,7 +73,7 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
private lateinit var bottomSheetBehavior: BottomSheetBehavior<View>
|
||||
private var bottomSheetVisible = false
|
||||
|
||||
val items = ArrayList<IBottomSheetItem<*>>()
|
||||
private val items = ArrayList<IBottomSheetItem<*>>()
|
||||
private val adapter = BottomSheetAdapter(items)
|
||||
|
||||
/**
|
||||
@ -116,6 +121,8 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
bottomSheet = findViewById(R.id.bs_view)
|
||||
content = findViewById(R.id.bs_content)
|
||||
dragBar = findViewById(R.id.bs_dragBar)
|
||||
textInputLayout = findViewById(R.id.bs_textInputLayout)
|
||||
textInputEditText = findViewById(R.id.bs_textInputEditText)
|
||||
toggleGroupContainer = findViewById(R.id.bs_toggleGroupContainer)
|
||||
toggleGroup = findViewById(R.id.bs_toggleGroup)
|
||||
toggleGroupTitleView = findViewById(R.id.bs_toggleGroupTitle)
|
||||
@ -169,15 +176,15 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
}
|
||||
|
||||
toggleGroup.addOnButtonCheckedListener(toggleGroupCheckedListener)
|
||||
textInputEditText.addTextChangedListener(textInputWatcher)
|
||||
}
|
||||
|
||||
/* _____ _ _ _
|
||||
|_ _| | ___ | | | |
|
||||
| | | |_ ___ _ __ ___ ___ ( _ ) __| | __ _| |_ __ _
|
||||
| | | __/ _ \ '_ ` _ \/ __| / _ \/\ / _` |/ _` | __/ _` |
|
||||
_| |_| || __/ | | | | \__ \ | (_> < | (_| | (_| | || (_| |
|
||||
|_____|\__\___|_| |_| |_|___/ \___/\/ \__,_|\__,_|\__\__,*/
|
||||
|
||||
/* _____ _
|
||||
|_ _| |
|
||||
| | | |_ ___ _ __ ___ ___
|
||||
| | | __/ _ \ '_ ` _ \/ __|
|
||||
_| |_| || __/ | | | | \__ \
|
||||
|_____|\__\___|_| |_| |_|__*/
|
||||
operator fun plusAssign(item: IBottomSheetItem<*>) {
|
||||
appendItem(item)
|
||||
}
|
||||
@ -193,6 +200,9 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
items.add(index, item)
|
||||
adapter.notifyItemInserted(index)
|
||||
}
|
||||
fun removeItemById(id: Int) {
|
||||
items.filterNot { it.id == id }
|
||||
}
|
||||
fun removeItemAt(index: Int) {
|
||||
items.removeAt(index)
|
||||
adapter.notifyItemRemoved(index)
|
||||
@ -210,10 +220,37 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
fun removeSeparators() {
|
||||
items.filterNot { it is SeparatorItem }
|
||||
items.filterNot { it is BottomSheetSeparatorItem }
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun getItemById(id: Int, run: (it: IBottomSheetItem<*>?) -> Unit) {
|
||||
items.singleOrNull { it.id == id }.also {
|
||||
run(it)
|
||||
if (it != null)
|
||||
adapter.notifyItemChanged(items.indexOf(it))
|
||||
}
|
||||
}
|
||||
fun getItemByIndex(index: Int, run: (it: IBottomSheetItem<*>?) -> Unit) {
|
||||
items.getOrNull(index).also {
|
||||
run(it)
|
||||
if (it != null)
|
||||
adapter.notifyItemChanged(index)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _______ _
|
||||
|__ __| | |
|
||||
| | ___ __ _ __ _| | ___ __ _ _ __ ___ _ _ _ __
|
||||
| |/ _ \ / _` |/ _` | |/ _ \ / _` | '__/ _ \| | | | '_ \
|
||||
| | (_) | (_| | (_| | | __/ | (_| | | | (_) | |_| | |_) |
|
||||
|_|\___/ \__, |\__, |_|\___| \__, |_| \___/ \__,_| .__/
|
||||
__/ | __/ | __/ | | |
|
||||
|___/ |___/ |___/ |*/
|
||||
var toggleGroupEnabled
|
||||
get() = toggleGroupContainer.visibility == View.VISIBLE
|
||||
set(value) { toggleGroupContainer.visibility = if (value) View.VISIBLE else View.GONE }
|
||||
var toggleGroupTitle
|
||||
get() = toggleGroupTitleView.text.toString()
|
||||
set(value) { toggleGroupTitleView.text = value }
|
||||
@ -288,33 +325,68 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
else -> null
|
||||
})
|
||||
if (sortingMode != null) {
|
||||
toggleGroupSortingOrderListener?.onSortingOrder(checkedId, sortingMode)
|
||||
toggleGroupSortingOrderListener?.invoke(checkedId, sortingMode)
|
||||
}
|
||||
}
|
||||
else if (toggleGroup.isSingleSelection && isChecked) {
|
||||
toggleGroupSingleSelectionListener?.onSingleSelection(checkedId - 1)
|
||||
toggleGroupSingleSelectionListener?.invoke(checkedId - 1)
|
||||
}
|
||||
else {
|
||||
toggleGroupMultipleSelectionListener?.onMultipleSelection(checkedId - 1, isChecked)
|
||||
toggleGroupMultipleSelectionListener?.invoke(checkedId - 1, isChecked)
|
||||
}
|
||||
}
|
||||
|
||||
interface OnToggleGroupChangeListener {
|
||||
fun onSingleSelection(id: Int)
|
||||
var toggleGroupSingleSelectionListener: ((id: Int) -> Unit)? = null
|
||||
var toggleGroupMultipleSelectionListener: ((id: Int, checked: Boolean) -> Unit)? = null
|
||||
var toggleGroupSortingOrderListener: ((id: Int, sortMode: Int) -> Unit)? = null
|
||||
|
||||
|
||||
/* _______ _ _ _
|
||||
|__ __| | | (_) | |
|
||||
| | _____ _| |_ _ _ __ _ __ _ _| |_
|
||||
| |/ _ \ \/ / __| | | '_ \| '_ \| | | | __|
|
||||
| | __/> <| |_ | | | | | |_) | |_| | |_
|
||||
|_|\___/_/\_\\__| |_|_| |_| .__/ \__,_|\__|
|
||||
| |
|
||||
|*/
|
||||
var textInputEnabled
|
||||
get() = textInputLayout.visibility == View.VISIBLE
|
||||
set(value) { textInputLayout.visibility = if (value) View.VISIBLE else View.GONE }
|
||||
var textInputText
|
||||
get() = textInputEditText.text.toString()
|
||||
set(value) { textInputEditText.setText(value) }
|
||||
var textInputHint
|
||||
get() = textInputLayout.hint.toString()
|
||||
set(value) { textInputLayout.hint = value }
|
||||
var textInputHelperText
|
||||
get() = textInputLayout.helperText.toString()
|
||||
set(value) { textInputLayout.helperText = value }
|
||||
var textInputError
|
||||
get() = textInputLayout.error
|
||||
set(value) { textInputLayout.error = value }
|
||||
var textInputIcon: Any?
|
||||
get() = textInputLayout.startIconDrawable
|
||||
set(value) {
|
||||
textInputLayout.startIconDrawable = when (value) {
|
||||
is Drawable -> value
|
||||
is IIcon -> IconicsDrawable(context, value).sizeDp(24)/*.colorInt(Color.BLACK)*/
|
||||
is Int -> context.getDrawableFromRes(value)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private var textInputWatcher = 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) {
|
||||
textInputChangedListener?.onTextChanged(s?.toString() ?: "", start, before, count)
|
||||
}
|
||||
}
|
||||
var toggleGroupSingleSelectionListener: OnToggleGroupChangeListener? = null
|
||||
|
||||
interface OnToggleGroupCheckedListener {
|
||||
fun onMultipleSelection(id: Int, checked: Boolean)
|
||||
interface OnTextInputChangedListener {
|
||||
fun onTextChanged(s: String, start: Int, before: Int, count: Int)
|
||||
}
|
||||
var toggleGroupMultipleSelectionListener: OnToggleGroupCheckedListener? = null
|
||||
|
||||
interface OnToggleGroupSortingListener {
|
||||
fun onSortingOrder(id: Int, sortMode: Int)
|
||||
}
|
||||
var toggleGroupSortingOrderListener: OnToggleGroupSortingListener? = null
|
||||
|
||||
|
||||
var textInputChangedListener: OnTextInputChangedListener? = null
|
||||
|
||||
|
||||
|
||||
@ -336,7 +408,7 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
bottomSheetBehavior.state = if (value) BottomSheetBehavior.STATE_EXPANDED else BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
fun open() { isOpen = true }
|
||||
fun close() { isOpen = true }
|
||||
fun close() { isOpen = false }
|
||||
fun toggle() {
|
||||
if (!enable)
|
||||
return
|
||||
|
@ -15,7 +15,7 @@ import pl.szczodrzynski.navlib.R
|
||||
import pl.szczodrzynski.navlib.colorAttr
|
||||
import pl.szczodrzynski.navlib.getColorFromAttr
|
||||
|
||||
data class PrimaryItem(override val isContextual: Boolean = true) : IBottomSheetItem<PrimaryItem.ViewHolder> {
|
||||
data class BottomSheetPrimaryItem(override val isContextual: Boolean = true) : IBottomSheetItem<BottomSheetPrimaryItem.ViewHolder> {
|
||||
|
||||
/*_ _
|
||||
| | | |
|
||||
@ -67,47 +67,47 @@ data class PrimaryItem(override val isContextual: Boolean = true) : IBottomSheet
|
||||
var iconicsIcon: IIcon? = null
|
||||
var onClickListener: View.OnClickListener? = null
|
||||
|
||||
fun withId(id: Int): PrimaryItem {
|
||||
fun withId(id: Int): BottomSheetPrimaryItem {
|
||||
this.id = id
|
||||
return this
|
||||
}
|
||||
|
||||
fun withTitle(title: CharSequence): PrimaryItem {
|
||||
fun withTitle(title: CharSequence): BottomSheetPrimaryItem {
|
||||
this.title = title
|
||||
this.titleRes = null
|
||||
return this
|
||||
}
|
||||
fun withTitle(@StringRes title: Int): PrimaryItem {
|
||||
fun withTitle(@StringRes title: Int): BottomSheetPrimaryItem {
|
||||
this.title = null
|
||||
this.titleRes = title
|
||||
return this
|
||||
}
|
||||
|
||||
fun withDescription(description: CharSequence): PrimaryItem {
|
||||
fun withDescription(description: CharSequence): BottomSheetPrimaryItem {
|
||||
this.description = description
|
||||
this.descriptionRes = null
|
||||
return this
|
||||
}
|
||||
fun withDescription(@StringRes description: Int): PrimaryItem {
|
||||
fun withDescription(@StringRes description: Int): BottomSheetPrimaryItem {
|
||||
this.description = null
|
||||
this.descriptionRes = description
|
||||
return this
|
||||
}
|
||||
|
||||
fun withIcon(icon: Drawable): PrimaryItem {
|
||||
fun withIcon(icon: Drawable): BottomSheetPrimaryItem {
|
||||
this.icon = ImageHolder(icon)
|
||||
return this
|
||||
}
|
||||
fun withIcon(@DrawableRes icon: Int): PrimaryItem {
|
||||
fun withIcon(@DrawableRes icon: Int): BottomSheetPrimaryItem {
|
||||
this.icon = ImageHolder(icon)
|
||||
return this
|
||||
}
|
||||
fun withIcon(icon: IIcon): PrimaryItem {
|
||||
fun withIcon(icon: IIcon): BottomSheetPrimaryItem {
|
||||
this.iconicsIcon = icon
|
||||
return this
|
||||
}
|
||||
|
||||
fun withOnClickListener(onClickListener: View.OnClickListener): PrimaryItem {
|
||||
fun withOnClickListener(onClickListener: View.OnClickListener): BottomSheetPrimaryItem {
|
||||
this.onClickListener = onClickListener
|
||||
return this
|
||||
}
|
@ -4,7 +4,7 @@ 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> {
|
||||
data class BottomSheetSeparatorItem(override val isContextual: Boolean = true) : IBottomSheetItem<BottomSheetSeparatorItem.ViewHolder> {
|
||||
|
||||
/*_ _
|
||||
| | | |
|
@ -1,84 +0,0 @@
|
||||
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?:"")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet.listeners
|
||||
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.EditTextFilledItem
|
||||
|
||||
interface OnItemInputListener {
|
||||
fun onItemInput(itemId: Int, item: EditTextFilledItem, text: CharSequence)
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package pl.szczodrzynski.navlib.drawer
|
||||
|
||||
data class IDrawerProfile(var id: Int,
|
||||
var name: String,
|
||||
var subname: String?,
|
||||
var image: String?)
|
@ -0,0 +1,6 @@
|
||||
package pl.szczodrzynski.navlib.drawer
|
||||
|
||||
data class IUnreadCounter(val profileId: Int,
|
||||
val type: Int,
|
||||
var drawerItemId: Int? = null,
|
||||
var count: Int)
|
616
navlib/src/main/java/pl/szczodrzynski/navlib/drawer/NavDrawer.kt
Normal file
616
navlib/src/main/java/pl/szczodrzynski/navlib/drawer/NavDrawer.kt
Normal file
@ -0,0 +1,616 @@
|
||||
package pl.szczodrzynski.navlib.drawer
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.customview.widget.ViewDragHelper
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import com.mikepenz.iconics.IconicsColor
|
||||
import com.mikepenz.iconics.IconicsColor.Companion.colorRes
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.IconicsSize
|
||||
import com.mikepenz.iconics.IconicsSize.Companion.dp
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.materialdrawer.*
|
||||
import com.mikepenz.materialdrawer.holder.BadgeStyle
|
||||
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||
import com.mikepenz.materialdrawer.model.BaseDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
||||
import pl.droidsonroids.gif.GifDrawable
|
||||
import pl.droidsonroids.gif.MultiCallback
|
||||
import pl.szczodrzynski.navlib.*
|
||||
import pl.szczodrzynski.navlib.R
|
||||
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
||||
|
||||
class NavDrawer(
|
||||
val context: Context,
|
||||
val drawerContainer: LinearLayout,
|
||||
val fixedDrawerContainer: FrameLayout,
|
||||
val miniDrawerContainerLandscape: FrameLayout,
|
||||
val miniDrawerContainerPortrait: FrameLayout
|
||||
) {
|
||||
companion object {
|
||||
private const val DRAWER_MODE_NORMAL = 0
|
||||
private const val DRAWER_MODE_MINI = 1
|
||||
private const val DRAWER_MODE_FIXED = 2
|
||||
}
|
||||
|
||||
private lateinit var activity: Activity
|
||||
private val resources: Resources
|
||||
get() = context.resources
|
||||
|
||||
internal lateinit var toolbar: NavToolbar
|
||||
internal lateinit var bottomBar: NavBottomBar
|
||||
|
||||
private var drawer: Drawer? = null
|
||||
private var drawerView: View? = null
|
||||
private var accountHeader: AccountHeader? = null
|
||||
private var miniDrawer: MiniDrawer? = null
|
||||
private var miniDrawerView: View? = null
|
||||
|
||||
private var drawerMode: Int = DRAWER_MODE_NORMAL
|
||||
private var selection: Int = -1
|
||||
|
||||
lateinit var badgeStyle: BadgeStyle
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
fun init(activity: Activity) {
|
||||
this.activity = activity
|
||||
|
||||
/*badgeStyle = BadgeStyle(
|
||||
R.drawable.material_drawer_badge,
|
||||
getColorFromAttr(context, R.attr.colorError),
|
||||
getColorFromAttr(context, R.attr.colorError),
|
||||
getColorFromAttr(context, R.attr.colorOnError)
|
||||
)*/
|
||||
|
||||
badgeStyle = BadgeStyle()
|
||||
.withTextColor(Color.WHITE)
|
||||
.withColorRes(R.color.md_red_700)
|
||||
|
||||
val drawerBuilder = DrawerBuilder()
|
||||
.withActivity(activity)
|
||||
.withDrawerLayout(R.layout.material_drawer_fits_not)
|
||||
.withRootView(drawerContainer)
|
||||
.withFullscreen(true)
|
||||
.withTranslucentStatusBar(false)
|
||||
.withTranslucentNavigationBar(true)
|
||||
.withTranslucentNavigationBarProgrammatically(false)
|
||||
.withToolbar(bottomBar)
|
||||
.withDisplayBelowStatusBar(true)
|
||||
.withActionBarDrawerToggleAnimated(true)
|
||||
.withGenerateMiniDrawer(true /* if it is not showing on screen, clicking items throws an exception */)
|
||||
.withOnDrawerListener(object : Drawer.OnDrawerListener {
|
||||
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
|
||||
override fun onDrawerOpened(drawerView: View) {
|
||||
drawerOpenedListener?.invoke()
|
||||
}
|
||||
override fun onDrawerClosed(drawerView: View) {
|
||||
drawerClosedListener?.invoke()
|
||||
profileSelectionClose()
|
||||
}
|
||||
})
|
||||
.withOnDrawerItemClickListener { _, position, drawerItem ->
|
||||
if (drawerItem.identifier.toInt() == selection) {
|
||||
return@withOnDrawerItemClickListener false
|
||||
}
|
||||
when (drawerItemSelectedListener?.invoke(drawerItem.identifier.toInt(), position, drawerItem)) {
|
||||
true -> {
|
||||
when {
|
||||
!drawerItem.isSelectable -> {
|
||||
setSelection(selection, false)
|
||||
return@withOnDrawerItemClickListener false
|
||||
}
|
||||
drawerItem is DrawerPrimaryItem -> toolbar.title = drawerItem.appTitle ?: drawerItem.name?.text ?: ""
|
||||
drawerItem is BaseDrawerItem<*, *> -> toolbar.title = drawerItem.name?.text ?: ""
|
||||
}
|
||||
setSelection(drawerItem.identifier.toInt(), false)
|
||||
return@withOnDrawerItemClickListener false
|
||||
}
|
||||
false -> {
|
||||
setSelection(selection, false)
|
||||
return@withOnDrawerItemClickListener true
|
||||
}
|
||||
else -> {
|
||||
return@withOnDrawerItemClickListener false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.withOnDrawerItemLongClickListener { _, position, drawerItem ->
|
||||
drawerItemLongClickListener?.invoke(drawerItem.identifier.toInt(), position, drawerItem) ?: true
|
||||
}
|
||||
|
||||
|
||||
val accountHeaderBuilder = AccountHeaderBuilder()
|
||||
.withActivity(activity)
|
||||
.withTranslucentStatusBar(true)
|
||||
.withOnAccountHeaderListener { view, profile, current ->
|
||||
if (profile is ProfileSettingDrawerItem) {
|
||||
return@withOnAccountHeaderListener drawerProfileSettingClickListener?.invoke(profile.identifier.toInt(), view) ?: false
|
||||
}
|
||||
updateBadges()
|
||||
if (current) {
|
||||
profileSelectionClose()
|
||||
close()
|
||||
return@withOnAccountHeaderListener true
|
||||
}
|
||||
drawerProfileSelectedListener?.invoke(profile.identifier.toInt(), profile, current, view) ?: false
|
||||
}
|
||||
.withOnAccountHeaderItemLongClickListener { view, profile, current ->
|
||||
if (profile is ProfileSettingDrawerItem) {
|
||||
return@withOnAccountHeaderItemLongClickListener drawerProfileSettingLongClickListener?.invoke(profile.identifier.toInt(), view) ?: true
|
||||
}
|
||||
drawerProfileLongClickListener?.invoke(profile.identifier.toInt(), profile, current, view) ?: false
|
||||
}
|
||||
.withOnAccountHeaderProfileImageListener(
|
||||
onClick = { view, profile, current ->
|
||||
drawerProfileImageClickListener?.invoke(profile.identifier.toInt(), profile, current, view) ?: false
|
||||
},
|
||||
onLongClick = { view, profile, current ->
|
||||
drawerProfileImageLongClickListener?.invoke(profile.identifier.toInt(), profile, current, view) ?: false
|
||||
}
|
||||
)
|
||||
.withHeaderBackground(R.drawable.header)
|
||||
.withTextColor(ContextCompat.getColor(context, R.color.material_drawer_dark_primary_text))
|
||||
|
||||
accountHeader = accountHeaderBuilder.build()
|
||||
drawerBuilder.withAccountHeader(accountHeader!!)
|
||||
drawer = drawerBuilder.build()
|
||||
|
||||
drawerView = drawer?.slider
|
||||
|
||||
miniDrawer = drawer?.miniDrawer
|
||||
miniDrawer?.withOnMiniDrawerItemClickListener { _, _, _, type ->
|
||||
if (type == MiniDrawer.PROFILE) {
|
||||
profileSelectionOpen()
|
||||
open()
|
||||
return@withOnMiniDrawerItemClickListener true
|
||||
}
|
||||
return@withOnMiniDrawerItemClickListener false
|
||||
}
|
||||
|
||||
// TODO 2019-08-27 build miniDrawerView only if needed
|
||||
// building in decideDrawerMode causes an exception when clicking drawer items
|
||||
// also update method updateMiniDrawer...
|
||||
miniDrawerView = miniDrawer?.build(context)
|
||||
updateMiniDrawer()
|
||||
|
||||
val configuration = context.resources.configuration
|
||||
decideDrawerMode(
|
||||
configuration.orientation,
|
||||
configuration.screenWidthDp,
|
||||
configuration.screenHeightDp
|
||||
)
|
||||
}
|
||||
|
||||
/* _____ _
|
||||
|_ _| |
|
||||
| | | |_ ___ _ __ ___ ___
|
||||
| | | __/ _ \ '_ ` _ \/ __|
|
||||
_| |_| || __/ | | | | \__ \
|
||||
|_____|\__\___|_| |_| |_|__*/
|
||||
operator fun plusAssign(item: IDrawerItem<*>) {
|
||||
appendItem(item)
|
||||
}
|
||||
fun appendItem(item: IDrawerItem<*>) {
|
||||
drawer?.addItem(item)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun appendItems(vararg items: IDrawerItem<*>) {
|
||||
drawer?.addItems(*items)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun prependItem(item: IDrawerItem<*>) {
|
||||
drawer?.addItemAtPosition(item, 0)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun prependItems(vararg items: IDrawerItem<*>) {
|
||||
drawer?.addItemsAtPosition(0, *items)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun addItemAt(index: Int, item: IDrawerItem<*>) {
|
||||
drawer?.addItemAtPosition(item, index)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun addItemsAt(index: Int, vararg items: IDrawerItem<*>) {
|
||||
drawer?.addItemsAtPosition(index, *items)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun removeItemById(id: Int) {
|
||||
drawer?.removeItem(id.toLong())
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun removeItemAt(index: Int) {
|
||||
drawer?.removeItemByPosition(index)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun removeAllItems() {
|
||||
drawer?.removeAllItems()
|
||||
updateMiniDrawer()
|
||||
}
|
||||
|
||||
fun getItemById(id: Int, run: (it: IDrawerItem<*>?) -> Unit) {
|
||||
drawer?.getDrawerItem(id.toLong()).also {
|
||||
run(it)
|
||||
if (it != null)
|
||||
drawer?.updateItem(it)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
}
|
||||
fun getItemByIndex(index: Int, run: (it: IDrawerItem<*>?) -> Unit) {
|
||||
drawer?.drawerItems?.getOrNull(index).also {
|
||||
run(it)
|
||||
if (it != null)
|
||||
drawer?.updateItem(it)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
}
|
||||
|
||||
/* _____ _ _ _ _ _
|
||||
| __ \ (_) | | | | | | | |
|
||||
| |__) | __ ___ ____ _| |_ ___ _ __ ___ ___| |_| |__ ___ __| |___
|
||||
| ___/ '__| \ \ / / _` | __/ _ \ | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
|
||||
| | | | | |\ V / (_| | || __/ | | | | | | __/ |_| | | | (_) | (_| \__ \
|
||||
|_| |_| |_| \_/ \__,_|\__\___| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|__*/
|
||||
private fun drawerSetDragMargin(size: Float) {
|
||||
val mDrawerLayout = drawer?.drawerLayout
|
||||
val mDragger = mDrawerLayout?.javaClass?.getDeclaredField(
|
||||
"mLeftDragger"
|
||||
)//mRightDragger for right obviously
|
||||
mDragger?.isAccessible = true
|
||||
val draggerObj = mDragger?.get(mDrawerLayout) as ViewDragHelper?
|
||||
|
||||
val mEdgeSize = draggerObj?.javaClass?.getDeclaredField(
|
||||
"mEdgeSize"
|
||||
)
|
||||
mEdgeSize?.isAccessible = true
|
||||
|
||||
mEdgeSize?.setInt(
|
||||
draggerObj,
|
||||
size.toInt()
|
||||
) //optimal value as for me, you may set any constant in dp
|
||||
}
|
||||
|
||||
internal fun decideDrawerMode(orientation: Int, widthDp: Int, heightDp: Int) {
|
||||
Log.d("NavLib", "Deciding drawer mode:")
|
||||
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
if (fixedDrawerContainer.childCount > 0) {
|
||||
fixedDrawerContainer.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- fixed container disabled")
|
||||
drawer?.drawerLayout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||
if (drawer?.drawerLayout?.indexOfChild(drawerView) == -1) {
|
||||
drawer?.drawerLayout?.addView(drawerView)
|
||||
}
|
||||
Log.d("NavLib", "- slider enabled")
|
||||
|
||||
if (miniDrawerContainerLandscape.childCount > 0) {
|
||||
miniDrawerContainerLandscape.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- mini drawer land disabled")
|
||||
|
||||
if (widthDp >= 480) {
|
||||
if (miniDrawerView == null)
|
||||
miniDrawerView = miniDrawer?.build(context)
|
||||
if (miniDrawerContainerPortrait.indexOfChild(miniDrawerView) == -1)
|
||||
miniDrawerContainerPortrait.addView(miniDrawerView)
|
||||
Log.d("NavLib", "- mini drawer port enabled")
|
||||
drawerSetDragMargin(72 * resources.displayMetrics.density)
|
||||
drawerMode = DRAWER_MODE_MINI
|
||||
updateMiniDrawer()
|
||||
}
|
||||
else {
|
||||
if (miniDrawerContainerPortrait.childCount > 0) {
|
||||
miniDrawerContainerPortrait.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- mini drawer port disabled")
|
||||
drawerSetDragMargin(20 * resources.displayMetrics.density)
|
||||
drawerMode = DRAWER_MODE_NORMAL
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (miniDrawerContainerPortrait.childCount > 0) {
|
||||
miniDrawerContainerPortrait.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- mini drawer port disabled")
|
||||
|
||||
if (widthDp in 480 until 9000) {
|
||||
if (miniDrawerView == null)
|
||||
miniDrawerView = miniDrawer?.build(context)
|
||||
if (miniDrawerContainerLandscape.indexOfChild(miniDrawerView) == -1)
|
||||
miniDrawerContainerLandscape.addView(miniDrawerView)
|
||||
Log.d("NavLib", "- mini drawer land enabled")
|
||||
drawerSetDragMargin(72 * resources.displayMetrics.density)
|
||||
drawerMode = DRAWER_MODE_MINI
|
||||
updateMiniDrawer()
|
||||
}
|
||||
else {
|
||||
if (miniDrawerContainerLandscape.childCount > 0) {
|
||||
miniDrawerContainerLandscape.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- mini drawer land disabled")
|
||||
drawerSetDragMargin(20 * resources.displayMetrics.density)
|
||||
drawerMode = DRAWER_MODE_NORMAL
|
||||
}
|
||||
if (widthDp >= 9000) {
|
||||
// screen is big enough to show fixed drawer
|
||||
if (drawer?.drawerLayout?.indexOfChild(drawerView) != -1) {
|
||||
// remove from slider
|
||||
drawer?.drawerLayout?.removeView(drawerView)
|
||||
}
|
||||
// lock the slider
|
||||
drawer?.drawerLayout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||
Log.d("NavLib", "- slider disabled")
|
||||
// add to fixed container
|
||||
if (fixedDrawerContainer.indexOfChild(drawerView) == -1)
|
||||
fixedDrawerContainer.addView(drawerView)
|
||||
Log.d("NavLib", "- fixed container enabled")
|
||||
drawerMode = DRAWER_MODE_FIXED
|
||||
}
|
||||
else {
|
||||
// screen is too small for the fixed drawer
|
||||
if (fixedDrawerContainer.childCount > 0) {
|
||||
// remove from fixed container
|
||||
fixedDrawerContainer.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- fixed container disabled")
|
||||
// unlock the slider
|
||||
drawer?.drawerLayout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||
if (drawer?.drawerLayout?.indexOfChild(drawerView) == -1) {
|
||||
// add to slider
|
||||
drawer?.drawerLayout?.addView(drawerView)
|
||||
}
|
||||
Log.d("NavLib", "- slider enabled")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateMiniDrawer() {
|
||||
selection = drawer?.currentSelection?.toInt() ?: -1
|
||||
//if (drawerMode == DRAWER_MODE_MINI)
|
||||
miniDrawer?.createItems()
|
||||
}
|
||||
|
||||
/* _____ _ _ _ _ _ _
|
||||
| __ \ | | | (_) | | | | | |
|
||||
| |__) | _| |__ | |_ ___ _ __ ___ ___| |_| |__ ___ __| |___
|
||||
| ___/ | | | '_ \| | |/ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
|
||||
| | | |_| | |_) | | | (__ | | | | | | __/ |_| | | | (_) | (_| \__ \
|
||||
|_| \__,_|_.__/|_|_|\___| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|__*/
|
||||
var isOpen
|
||||
get() = drawer?.isDrawerOpen ?: false || drawerMode == DRAWER_MODE_FIXED
|
||||
set(value) {
|
||||
if (drawerMode == DRAWER_MODE_FIXED)
|
||||
return
|
||||
if (value && !isOpen) drawer?.openDrawer() else if (!value && isOpen) drawer?.closeDrawer()
|
||||
}
|
||||
fun open() { isOpen = true }
|
||||
fun close() { isOpen = false }
|
||||
fun toggle() {
|
||||
if (drawer == null)
|
||||
return
|
||||
isOpen = !isOpen
|
||||
}
|
||||
|
||||
var profileSelectionIsOpen
|
||||
get() = accountHeader?.isSelectionListShown == true
|
||||
set(value) {
|
||||
if (value != profileSelectionIsOpen)
|
||||
profileSelectionToggle()
|
||||
}
|
||||
fun profileSelectionOpen() { profileSelectionIsOpen = true }
|
||||
fun profileSelectionClose() { profileSelectionIsOpen = false }
|
||||
fun profileSelectionToggle() {
|
||||
accountHeader?.let {
|
||||
it.toggleSelectionList(it.view.context)
|
||||
}
|
||||
}
|
||||
|
||||
var drawerOpenedListener: (() -> Unit)? = null
|
||||
var drawerClosedListener: (() -> Unit)? = null
|
||||
var drawerItemSelectedListener: ((id: Int, position: Int, drawerItem: IDrawerItem<*>) -> Boolean)? = null
|
||||
var drawerItemLongClickListener: ((id: Int, position: Int, drawerItem: IDrawerItem<*>) -> Boolean)? = null
|
||||
var drawerProfileSelectedListener: ((id: Int, profile: IProfile<*>, current: Boolean, view: View?) -> Boolean)? = null
|
||||
var drawerProfileLongClickListener: ((id: Int, profile: IProfile<*>, current: Boolean, view: View) -> Boolean)? = null
|
||||
var drawerProfileImageClickListener: ((id: Int, profile: IProfile<*>, current: Boolean, view: View) -> Boolean)? = null
|
||||
var drawerProfileImageLongClickListener: ((id: Int, profile: IProfile<*>, current: Boolean, view: View) -> Boolean)? = null
|
||||
var drawerProfileListEmptyListener: (() -> Unit)? = null
|
||||
var drawerProfileSettingClickListener: ((id: Int, view: View?) -> Boolean)? = null
|
||||
var drawerProfileSettingLongClickListener: ((id: Int, view: View) -> Boolean)? = null
|
||||
|
||||
fun miniDrawerEnabled(): Boolean = drawerMode == DRAWER_MODE_MINI
|
||||
fun fixedDrawerEnabled(): Boolean = drawerMode == DRAWER_MODE_FIXED
|
||||
fun setSelection(id: Int, fireOnClick: Boolean = true) {
|
||||
selection = id
|
||||
if (drawer?.currentSelection != id.toLong())
|
||||
drawer?.setSelection(id.toLong(), fireOnClick)
|
||||
if (drawerMode == DRAWER_MODE_MINI)
|
||||
miniDrawer?.setSelection(id.toLong())
|
||||
}
|
||||
|
||||
// TODO 2019-08-27 add methods for Drawable, @DrawableRes
|
||||
fun setAccountHeaderBackground(path: String?) {
|
||||
if (path == null) {
|
||||
accountHeader?.setBackgroundRes(R.drawable.header)
|
||||
return
|
||||
}
|
||||
accountHeader?.setHeaderBackground(ImageHolder(path))
|
||||
}
|
||||
|
||||
/* _____ __ _ _
|
||||
| __ \ / _(_) |
|
||||
| |__) | __ ___ | |_ _| | ___ ___
|
||||
| ___/ '__/ _ \| _| | |/ _ \/ __|
|
||||
| | | | | (_) | | | | | __/\__ \
|
||||
|_| |_| \___/|_| |_|_|\___||__*/
|
||||
private var profileList = arrayListOf<IDrawerProfile>()
|
||||
|
||||
fun addProfileSettings(vararg items: ProfileSettingDrawerItem) {
|
||||
accountHeader?.profiles?.addAll(items)
|
||||
}
|
||||
|
||||
private fun updateProfileList() {
|
||||
// remove all profile items
|
||||
accountHeader?.profiles?.filterNot { it is ProfileDrawerItem }
|
||||
|
||||
if (profileList.isEmpty())
|
||||
drawerProfileListEmptyListener?.invoke()
|
||||
|
||||
profileList.forEachIndexed { index, profile ->
|
||||
val image = if (profile.image != null) {
|
||||
try {
|
||||
ImageHolder(profile.image ?: "")
|
||||
}
|
||||
catch (_: Exception) {
|
||||
ImageHolder(R.drawable.profile4)
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImageHolder(R.drawable.profile4)
|
||||
}
|
||||
ProfileDrawerItem()
|
||||
.withIdentifier(profile.id.toLong())
|
||||
.withName(profile.name)
|
||||
.withEmail(profile.subname)
|
||||
.also { it.icon = image }
|
||||
.withNameShown(true)
|
||||
.also { accountHeader?.profiles?.add(index, it) }
|
||||
}
|
||||
|
||||
accountHeader?.profiles = accountHeader?.profiles
|
||||
|
||||
updateMiniDrawer()
|
||||
}
|
||||
|
||||
fun setProfileList(profiles: ArrayList<IDrawerProfile>) {
|
||||
profileList = profiles
|
||||
updateProfileList()
|
||||
/*profileList.clear()
|
||||
profileList.addAll(profiles)*/
|
||||
}
|
||||
var currentProfile: Int
|
||||
get() = accountHeader?.activeProfile?.identifier?.toInt() ?: -1
|
||||
set(value) {
|
||||
accountHeader?.setActiveProfile(value.toLong(), true)
|
||||
}
|
||||
fun appendProfile(profile: IDrawerProfile) {
|
||||
profileList.add(profile)
|
||||
updateProfileList()
|
||||
}
|
||||
fun appendProfiles(vararg profiles: IDrawerProfile) {
|
||||
profileList.addAll(profiles)
|
||||
updateProfileList()
|
||||
}
|
||||
fun prependProfile(profile: IDrawerProfile) {
|
||||
profileList.add(0, profile)
|
||||
updateProfileList()
|
||||
}
|
||||
fun prependProfiles(vararg profiles: IDrawerProfile) {
|
||||
profileList.addAll(0, profiles.asList())
|
||||
updateProfileList()
|
||||
}
|
||||
fun addProfileAt(index: Int, profile: IDrawerProfile) {
|
||||
profileList.add(index, profile)
|
||||
updateProfileList()
|
||||
}
|
||||
fun addProfilesAt(index: Int, vararg profiles: IDrawerProfile) {
|
||||
profileList.addAll(index, profiles.asList())
|
||||
updateProfileList()
|
||||
}
|
||||
fun removeProfileById(id: Int) {
|
||||
profileList.filterNot { it.id == id }
|
||||
updateProfileList()
|
||||
}
|
||||
fun removeProfileAt(index: Int) {
|
||||
profileList.removeAt(index)
|
||||
updateProfileList()
|
||||
}
|
||||
fun removeAllProfile() {
|
||||
profileList.clear()
|
||||
updateProfileList()
|
||||
}
|
||||
|
||||
fun getProfileById(id: Int, run: (it: IDrawerProfile?) -> Unit) {
|
||||
profileList.singleOrNull { it.id == id }.also {
|
||||
run(it)
|
||||
updateProfileList()
|
||||
}
|
||||
}
|
||||
fun getProfileByIndex(index: Int, run: (it: IDrawerProfile?) -> Unit) {
|
||||
profileList.getOrNull(index).also {
|
||||
run(it)
|
||||
updateProfileList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ____ _
|
||||
| _ \ | |
|
||||
| |_) | __ _ __| | __ _ ___ ___
|
||||
| _ < / _` |/ _` |/ _` |/ _ \/ __|
|
||||
| |_) | (_| | (_| | (_| | __/\__ \
|
||||
|____/ \__,_|\__,_|\__, |\___||___/
|
||||
__/ |
|
||||
|__*/
|
||||
private var unreadCounterList = arrayListOf<IUnreadCounter>()
|
||||
private val unreadCounterTypeMap = mutableMapOf<Int, Int>()
|
||||
|
||||
fun updateBadges() {
|
||||
unreadCounterList.map {
|
||||
it.drawerItemId = unreadCounterTypeMap[it.type]
|
||||
}
|
||||
unreadCounterList.forEach {
|
||||
if (it.drawerItemId == null)
|
||||
return@forEach
|
||||
if (it.profileId != currentProfile) {
|
||||
drawer?.updateBadge(it.drawerItemId?.toLong() ?: 0, null)
|
||||
return@forEach
|
||||
}
|
||||
drawer?.updateBadge(
|
||||
it.drawerItemId?.toLong() ?: 0,
|
||||
when {
|
||||
it.count == 0 -> null
|
||||
it.count >= 99 -> StringHolder("99+")
|
||||
else -> StringHolder(it.count.toString())
|
||||
}
|
||||
)
|
||||
}
|
||||
updateMiniDrawer()
|
||||
}
|
||||
|
||||
fun setUnreadCounterList(unreadCounterList: ArrayList<IUnreadCounter>) {
|
||||
this.unreadCounterList = unreadCounterList
|
||||
updateBadges()
|
||||
}
|
||||
|
||||
fun addUnreadCounterType(type: Int, drawerItem: Int) {
|
||||
unreadCounterTypeMap[type] = drawerItem
|
||||
}
|
||||
|
||||
fun setUnreadCount(profileId: Int, type: Int, count: Int) {
|
||||
val item = unreadCounterList.singleOrNull {
|
||||
it.type == type && it.profileId == profileId
|
||||
}
|
||||
if (item != null) {
|
||||
item.count = count
|
||||
updateBadges()
|
||||
}
|
||||
else {
|
||||
unreadCounterList.add(IUnreadCounter(profileId, type, null, count))
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package pl.szczodrzynski.navlib.drawer.items
|
||||
|
||||
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
|
||||
|
||||
class DrawerPrimaryItem : PrimaryDrawerItem() {
|
||||
var appTitle: String? = null
|
||||
fun withAppTitle(appTitle: String?): PrimaryDrawerItem {
|
||||
this.appTitle = appTitle
|
||||
return this
|
||||
}
|
||||
}
|
21
navlib/src/main/res/color/mtrl_filled_background_color.xml
Normal file
21
navlib/src/main/res/color/mtrl_filled_background_color.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:alpha="0.16" android:color="?attr/colorOnSurface" android:state_hovered="true"/>
|
||||
<item android:alpha="0.04" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
|
||||
<item android:alpha="0.12" android:color="?attr/colorOnSurface"/>
|
||||
</selector>
|
22
navlib/src/main/res/color/text_input_layout_background.xml
Normal file
22
navlib/src/main/res/color/text_input_layout_background.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- increased alpha by 1/2 -->
|
||||
<item android:alpha="0.24" android:color="?attr/colorOnSurface" android:state_hovered="true"/>
|
||||
<item android:alpha="0.06" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
|
||||
<item android:alpha="0.18" android:color="?attr/colorOnSurface"/>
|
||||
</selector>
|
8
navlib/src/main/res/drawable/shadow_bottom.xml
Normal file
8
navlib/src/main/res/drawable/shadow_bottom.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:endColor="#00000000"
|
||||
android:startColor="#40000000"
|
||||
android:type="linear" />
|
||||
</shape>
|
8
navlib/src/main/res/drawable/shadow_right.xml
Normal file
8
navlib/src/main/res/drawable/shadow_right.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="0"
|
||||
android:endColor="#00000000"
|
||||
android:startColor="#40000000"
|
||||
android:type="linear" />
|
||||
</shape>
|
@ -43,19 +43,41 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
app:srcCompat="@drawable/bottom_sheet_control_bar"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/bs_textInputLayout"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.Dense"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:boxBackgroundColor="?boxBackgroundColor"
|
||||
app:endIconMode="clear_text"
|
||||
tools:startIconDrawable="@drawable/ic_android"
|
||||
tools:helperText="0 messages found"
|
||||
tools:hint="Search">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/bs_textInputEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
tools:text="John" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bs_toggleGroupContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical">
|
||||
android:layout_marginBottom="16dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bs_toggleGroupTitle"
|
||||
@ -64,56 +86,11 @@
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Sorting order" />
|
||||
|
||||
<androidx.gridlayout.widget.GridLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="?materialButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="By date"
|
||||
app:icon="@drawable/ic_android" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="?materialButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="By subject" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="?materialButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="By sender" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="?materialButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="By date"
|
||||
app:icon="@drawable/ic_android" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="?materialButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="By subject" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
style="?materialButtonOutlinedStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="By sender" />
|
||||
|
||||
</androidx.gridlayout.widget.GridLayout>
|
||||
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
android:id="@+id/bs_toggleGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:singleSelection="true"/>
|
||||
app:singleSelection="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?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>
|
@ -4,122 +4,170 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:orientation="horizontal"
|
||||
tools:parentTag="FrameLayout">
|
||||
|
||||
<View
|
||||
android:id="@+id/nv_statusBarBackground"
|
||||
android:layout_width="match_parent"
|
||||
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="0dp"
|
||||
tools:layout_height="48dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?colorPrimaryVariant"
|
||||
tools:background="?colorPrimaryVariant" />
|
||||
|
||||
<FrameLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/nv_drawerContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/nv_main"
|
||||
android:layout_width="match_parent"
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
tools:paddingTop="24dp"
|
||||
tools:paddingBottom="48dp">
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<pl.szczodrzynski.navlib.NavToolbar
|
||||
android:id="@+id/nv_toolbar"
|
||||
<View
|
||||
android:id="@+id/nv_statusBarBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?nv_actionBarBackground"
|
||||
android:elevation="4dp"
|
||||
app:title="@string/app_name"
|
||||
tools:targetApi="lollipop" />
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="top"
|
||||
android:background="?android:windowBackground"
|
||||
tools:layout_height="25dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/nv_content"
|
||||
android:id="@+id/nv_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="?actionBarSize"
|
||||
android:layout_marginBottom="?actionBarSize"
|
||||
android:orientation="vertical">
|
||||
android:orientation="horizontal"
|
||||
tools:paddingTop="24dp"
|
||||
tools:paddingBottom="48dp">
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/nv_elevation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:max="20"
|
||||
android:progress="4"
|
||||
android:visibility="gone" />
|
||||
<FrameLayout
|
||||
android:id="@+id/nv_miniDrawerContainerLandscape"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
tools:background="#2196f3" /><!--tools:layout_width="72dp"-->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Set toolbar elevation"
|
||||
android:visibility="gone" />
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<pl.szczodrzynski.navlib.NavToolbar
|
||||
android:id="@+id/nv_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?actionBarBackground"
|
||||
android:elevation="4dp"
|
||||
app:title="@string/app_name"
|
||||
tools:targetApi="lollipop" />
|
||||
|
||||
<View
|
||||
android:id="@+id/nv_toolbarElevation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="4dp"
|
||||
android:layout_marginTop="?actionBarSize"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/shadow_bottom" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/nv_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="?actionBarSize"
|
||||
android:layout_marginBottom="?actionBarSize"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/nv_miniDrawerContainerPortrait"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
tools:background="#ffb300" /><!--tools:layout_width="72dp"-->
|
||||
|
||||
<View
|
||||
android:id="@+id/nv_miniDrawerElevation"
|
||||
android:layout_width="4dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/shadow_right" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<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"
|
||||
android:visibility="visible"
|
||||
app:fabAlignmentMode="center"
|
||||
app:fabAnimationMode="scale" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/nv_extendedFloatingActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:text=""
|
||||
android:visibility="visible"
|
||||
app:backgroundTint="?colorFab"
|
||||
app:layout_anchor="@+id/nv_bottomBar"
|
||||
app:layout_anchorGravity="center|top"
|
||||
tools:icon="@android:drawable/ic_menu_edit" />
|
||||
|
||||
<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:backgroundTint="?colorFab"
|
||||
app:layout_anchor="@id/nv_bottomBar"
|
||||
tools:srcCompat="@android:drawable/ic_menu_edit" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<pl.szczodrzynski.navlib.NavBottomBar
|
||||
android:id="@+id/nv_bottomBar"
|
||||
style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
|
||||
<View
|
||||
android:id="@+id/nv_navigationBarBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:visibility="visible"
|
||||
app:fabAlignmentMode="center"
|
||||
app:fabAnimationMode="scale" />
|
||||
android:background="?navigationBarBackground"
|
||||
tools:layout_height="48dp" />
|
||||
|
||||
<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="?colorFab"
|
||||
tools:srcCompat="@android:drawable/ic_menu_edit"/>
|
||||
</FrameLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/nv_extendedFloatingActionButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:visibility="visible"
|
||||
android:text=""
|
||||
app:backgroundTint="?colorFab"
|
||||
tools:icon="@android:drawable/ic_menu_edit"
|
||||
app:layout_anchor="@+id/nv_bottomBar"
|
||||
app:layout_anchorGravity="center|top"/>
|
||||
<FrameLayout
|
||||
android:id="@+id/nv_fixedDrawerContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
tools:background="#4caf50"/><!--tools:layout_width="300dp"-->
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
<View
|
||||
android:id="@+id/nv_statusBarDarker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="top"
|
||||
android:background="#44000000"
|
||||
android:visibility="gone"
|
||||
tools:layout_height="25dp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<View
|
||||
android:id="@+id/nv_navigationBarDarker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="#44000000"
|
||||
android:visibility="gone"
|
||||
tools:layout_height="48dp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<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>
|
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<attr name="nv_actionBarBackground" format="color" />
|
||||
<attr name="actionBarBackground" format="color" />
|
||||
<attr name="navigationBarBackground" format="color" />
|
||||
<attr name="colorFab" format="color" />
|
||||
<attr name="colorFabIcon" format="color" />
|
||||
<attr name="colorOnFab" format="color" />
|
||||
|
@ -12,26 +12,72 @@
|
||||
<item name="backgroundTint">?colorFab</item>
|
||||
<item name="android:textColor">?colorOnFab</item>
|
||||
</style>
|
||||
<!-- default body text -->
|
||||
<style name="NavView.TextView" parent="Widget.MaterialComponents.TextView">
|
||||
<item name="android:textAppearance">?attr/textAppearanceBody2</item>
|
||||
</style>
|
||||
<!-- title text -->
|
||||
<style name="NavView.TextView.Title" parent="TextAppearance.AppCompat.Title">
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
<!-- subtitle text, smaller than medium -->
|
||||
<style name="NavView.TextView.Subtitle" parent="TextAppearance.AppCompat.Subhead">
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
<!-- large body text -->
|
||||
<style name="NavView.TextView.Large" parent="TextAppearance.AppCompat.Large">
|
||||
</style>
|
||||
<!-- medium body text -->
|
||||
<style name="NavView.TextView.Medium" parent="TextAppearance.AppCompat.Medium">
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
<!-- small (helper) body text -->
|
||||
<style name="NavView.TextView.Small" parent="TextAppearance.AppCompat.Small">
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
<!--<item name="colorAccent">#ffb300</item>-->
|
||||
|
||||
<style name="NavView.Light" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
<!-- primary styling -->
|
||||
<item name="colorPrimary">#6200EE</item>
|
||||
<item name="colorPrimaryDark">#3700B3</item>
|
||||
<item name="colorPrimaryVariant">#6200EE</item>
|
||||
<item name="colorAccent">#03DAC6</item>
|
||||
<item name="colorSecondary">?colorAccent</item>
|
||||
<item name="colorSecondaryVariant">#018786</item>
|
||||
|
||||
<!-- window colors -->
|
||||
<item name="android:colorBackground">@color/background_light</item>
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
<item name="colorSurface">#ffffff</item>
|
||||
<item name="elevationOverlayColor">#ffffff</item>
|
||||
|
||||
<!-- FAB styling -->
|
||||
<item name="colorFab">?colorAccent</item>
|
||||
<item name="colorFabIcon">?colorOnSecondary</item>
|
||||
<item name="colorOnFab">?colorOnSecondary</item>
|
||||
|
||||
<!-- text colors -->
|
||||
<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="elevationOverlayColor">#ffffff</item>
|
||||
|
||||
<!-- system bars config -->
|
||||
<item name="actionBarBackground">?colorSurface</item>
|
||||
<item name="navigationBarBackground">?colorPrimaryVariant</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
|
||||
<!-- component styling -->
|
||||
<item name="floatingActionButtonStyle">@style/NavView.Widget.FloatingActionButton</item>
|
||||
<item name="extendedFloatingActionButtonStyle">@style/NavView.Widget.ExtendedFloatingActionButton</item>
|
||||
<item name="boxBackgroundColor" tools:ignore="PrivateResource">@color/mtrl_filled_background_color</item>
|
||||
<item name="android:textViewStyle">@style/NavView.TextView</item>
|
||||
|
||||
<!-- drawer & bottom sheet styling -->
|
||||
<item name="material_drawer_background">?android:colorBackground</item>
|
||||
<item name="material_drawer_primary_text">#242424</item>
|
||||
<item name="material_drawer_primary_icon">#5F6368</item>
|
||||
@ -45,20 +91,43 @@
|
||||
</style>
|
||||
|
||||
<style name="NavView.Dark" parent="Theme.MaterialComponents.NoActionBar">
|
||||
<!-- primary styling -->
|
||||
<item name="colorPrimary">#BB86FC</item>
|
||||
<item name="colorPrimaryDark">#3700B3</item>
|
||||
<item name="colorPrimaryVariant">#6200EE</item>
|
||||
<item name="colorAccent">#03DAC6</item>
|
||||
<item name="colorSecondary">?colorAccent</item>
|
||||
<item name="colorSecondaryVariant">?colorAccent</item>
|
||||
|
||||
<!-- window colors -->
|
||||
<item name="android:colorBackground">@color/background_dark</item>
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
<item name="colorSurface">#303030</item>
|
||||
|
||||
<!-- FAB styling -->
|
||||
<item name="colorFab">?colorAccent</item>
|
||||
<item name="colorFabIcon">?colorOnSecondary</item>
|
||||
<item name="colorOnFab">?colorOnSecondary</item>
|
||||
|
||||
<!-- text colors -->
|
||||
<item name="colorOnPrimary">#ffffff</item>
|
||||
<item name="colorOnSecondary">#ffffff</item>
|
||||
<item name="colorOnBackground">#ffffff</item>
|
||||
<item name="colorOnSurface">#ffffff</item>
|
||||
|
||||
<item name="nv_actionBarBackground">?colorSurface</item>
|
||||
<!-- system bars config -->
|
||||
<item name="actionBarBackground">?colorSurface</item>
|
||||
<item name="navigationBarBackground">?colorPrimaryVariant</item>
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
|
||||
<!-- component styling -->
|
||||
<item name="floatingActionButtonStyle">@style/NavView.Widget.FloatingActionButton</item>
|
||||
<item name="extendedFloatingActionButtonStyle">@style/NavView.Widget.ExtendedFloatingActionButton</item>
|
||||
<item name="boxBackgroundColor">@color/text_input_layout_background</item>
|
||||
<item name="android:textViewStyle">@style/NavView.TextView</item>
|
||||
|
||||
<!-- drawer & bottom sheet styling -->
|
||||
<item name="material_drawer_background">?android:colorBackground</item>
|
||||
<item name="material_drawer_primary_text">#FFFFFF</item>
|
||||
<item name="material_drawer_primary_icon">#9AA0A6</item>
|
||||
@ -75,6 +144,8 @@
|
||||
<item name="android:colorBackground">@color/background_black</item>
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
<item name="colorSurface">#121212</item>
|
||||
|
||||
<item name="colorBackgroundFloating">#2D2D2D</item>
|
||||
</style>
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user