mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-06-13 06:00:46 +02:00
[UI] Reformat layout XMLs, cleanup NavLib code (#207)
* Remove Themes and getColorFromAttr() usage * Reformat all layout XML files * Remove <layout> from non-data binding XMLs * Cleanup unused NavLib code * Migrate NavBottomSheet to view binding, remove unused components * Add IIcon.toDrawable() extension * Make BottomSheet scrim opacity linear * Support touch events on BottomSheet scrim
This commit is contained in:

committed by
GitHub

parent
10043cc62c
commit
09f0c986e0
@ -1,278 +0,0 @@
|
||||
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.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 BezelImageView @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_materialDrawerMaskDrawable)
|
||||
if (mMaskDrawable != null) {
|
||||
mMaskDrawable.callback = this
|
||||
}
|
||||
|
||||
mDrawCircularShadow = a.getBoolean(R.styleable.BezelImageView_materialDrawerDrawCircularShadow, true)
|
||||
|
||||
mSelectorColor = a.getColor(R.styleable.BezelImageView_materialDrawerSelectorOnPress, 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.mikepenz.materialdrawer.*
|
||||
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||
import com.mikepenz.materialdrawer.model.AbstractDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.BaseDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.*
|
||||
import com.mikepenz.materialdrawer.util.getDrawerItem
|
||||
import com.mikepenz.materialdrawer.util.updateItem
|
||||
import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
|
||||
|
||||
/*inline fun DrawerBuilder.withOnDrawerItemClickListener(crossinline 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
inline fun DrawerBuilder.withOnDrawerItemLongClickListener(crossinline 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
inline fun AccountHeaderBuilder.withOnAccountHeaderListener(crossinline 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
inline fun AccountHeaderBuilder.withOnAccountHeaderItemLongClickListener(crossinline 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
inline fun AccountHeaderBuilder.withOnAccountHeaderProfileImageListener(
|
||||
crossinline onClick: (
|
||||
view: View,
|
||||
profile: IProfile<*>,
|
||||
current: Boolean
|
||||
) -> Boolean,
|
||||
crossinline 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
inline fun MiniDrawer.withOnMiniDrawerItemClickListener(crossinline 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)
|
||||
}
|
||||
})
|
||||
}*/
|
||||
|
||||
fun MaterialDrawerSliderView.updateBadge(identifier: Long, badge: StringHolder?) {
|
||||
val drawerItem = getDrawerItem(identifier)
|
||||
if (drawerItem is Badgeable) {
|
||||
drawerItem.withBadge(badge)
|
||||
updateItem(drawerItem)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Iconable> T.withIcon(icon: IIcon) = withIcon(pl.szczodrzynski.navlib.ImageHolder(icon))
|
@ -2,24 +2,20 @@ package pl.szczodrzynski.navlib
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.google.android.material.bottomappbar.BottomAppBar
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.mikepenz.iconics.typeface.library.navlibfont.NavLibFont
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
|
||||
import pl.szczodrzynski.navlib.drawer.NavDrawer
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
class NavBottomBar @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
@ -27,8 +23,6 @@ class NavBottomBar @JvmOverloads constructor(
|
||||
) : BottomAppBar(context, attrs, defStyle), NavMenuBarBase {
|
||||
|
||||
internal lateinit var navView: NavView
|
||||
override lateinit var bottomSheet: NavBottomSheet
|
||||
internal lateinit var fabView: FloatingActionButton
|
||||
internal lateinit var fabExtendedView: ExtendedFloatingActionButton
|
||||
|
||||
/**
|
||||
@ -42,6 +36,7 @@ class NavBottomBar @JvmOverloads constructor(
|
||||
setFabParams()
|
||||
navView.setContentMargins()
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the FAB should be visible.
|
||||
*/
|
||||
@ -50,17 +45,7 @@ class NavBottomBar @JvmOverloads constructor(
|
||||
field = value
|
||||
setFabVisibility()
|
||||
}
|
||||
/**
|
||||
* Whether an ExtendableFloatingActionButton should be used
|
||||
* instead of a normal FloatingActionButton.
|
||||
* Note that the extendable button does not support end alignment/gravity
|
||||
* when used together with the bottom app bar.
|
||||
*/
|
||||
var fabExtendable = true
|
||||
set(value) {
|
||||
field = value
|
||||
setFabParams()
|
||||
}
|
||||
|
||||
/**
|
||||
* If BottomAppBar is enabled, sets its fabAlignmentMode.
|
||||
* Else, sets the actual FAB's gravity.
|
||||
@ -70,6 +55,7 @@ class NavBottomBar @JvmOverloads constructor(
|
||||
field = value
|
||||
setFabParams()
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the FAB should be extended and its text visible.
|
||||
*/
|
||||
@ -81,23 +67,20 @@ class NavBottomBar @JvmOverloads constructor(
|
||||
else
|
||||
fabExtendedView.shrink()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the FAB's icon.
|
||||
*/
|
||||
var fabIcon: IIcon? = null
|
||||
set(value) {
|
||||
field = value
|
||||
fabView.setImageDrawable(IconicsDrawable(context).apply {
|
||||
icon = value
|
||||
colorAttr(context, R.attr.colorOnPrimaryContainer)
|
||||
sizeDp = 24
|
||||
})
|
||||
fabExtendedView.icon = IconicsDrawable(context).apply {
|
||||
icon = value
|
||||
colorAttr(context, R.attr.colorOnPrimaryContainer)
|
||||
sizeDp = 24
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ExtendedFAB's text.
|
||||
*/
|
||||
@ -111,7 +94,6 @@ class NavBottomBar @JvmOverloads constructor(
|
||||
* Set the FAB's on click listener
|
||||
*/
|
||||
fun setFabOnClickListener(onClickListener: OnClickListener?) {
|
||||
fabView.setOnClickListener(onClickListener)
|
||||
fabExtendedView.setOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
@ -119,51 +101,32 @@ class NavBottomBar @JvmOverloads constructor(
|
||||
override var menuClickListener: (() -> Unit)? = null
|
||||
|
||||
init {
|
||||
setOnTouchListener { _, event ->
|
||||
if (bottomSheet?.enable != true || bottomSheet?.enableDragToOpen != true)
|
||||
return@setOnTouchListener false
|
||||
bottomSheet?.dispatchBottomBarEvent(event)
|
||||
true
|
||||
}
|
||||
|
||||
elevation = 0f
|
||||
}
|
||||
|
||||
private fun setFabParams() {
|
||||
val layoutParams =
|
||||
((if (fabExtendable) fabExtendedView.layoutParams else fabView.layoutParams) ?: return) as CoordinatorLayout.LayoutParams
|
||||
|
||||
if (enable) {
|
||||
layoutParams.anchorId = this.id
|
||||
if (fabExtendable)
|
||||
layoutParams.anchorGravity = if (fabExtendable) fabGravity or Gravity.TOP else Gravity.NO_GRAVITY
|
||||
layoutParams.gravity = Gravity.NO_GRAVITY
|
||||
fabExtendedView.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
||||
if (enable) {
|
||||
anchorId = this@NavBottomBar.id
|
||||
anchorGravity = fabGravity or Gravity.TOP
|
||||
gravity = Gravity.NO_GRAVITY
|
||||
} else {
|
||||
anchorId = View.NO_ID
|
||||
anchorGravity = Gravity.NO_GRAVITY
|
||||
gravity = fabGravity or Gravity.BOTTOM
|
||||
}
|
||||
fabAlignmentMode =
|
||||
if (fabGravity == Gravity.END)
|
||||
FAB_ALIGNMENT_MODE_END
|
||||
else
|
||||
FAB_ALIGNMENT_MODE_CENTER
|
||||
}
|
||||
else {
|
||||
layoutParams.anchorId = View.NO_ID
|
||||
if (fabExtendable)
|
||||
layoutParams.anchorGravity = Gravity.NO_GRAVITY
|
||||
layoutParams.gravity = fabGravity or Gravity.BOTTOM
|
||||
}
|
||||
fabAlignmentMode = if (fabGravity == Gravity.END) FAB_ALIGNMENT_MODE_END else FAB_ALIGNMENT_MODE_CENTER
|
||||
if (fabExtendable)
|
||||
fabExtendedView.layoutParams = layoutParams
|
||||
else
|
||||
fabView.layoutParams = layoutParams
|
||||
setFabVisibility()
|
||||
}
|
||||
private fun setFabVisibility() {
|
||||
if (fabEnable && fabExtendable) {
|
||||
fabView.hide()
|
||||
|
||||
private fun setFabVisibility() =
|
||||
if (fabEnable)
|
||||
fabExtendedView.show()
|
||||
}
|
||||
else if (fabEnable) {
|
||||
fabView.show()
|
||||
else
|
||||
fabExtendedView.hide()
|
||||
}
|
||||
else {
|
||||
fabView.hide()
|
||||
fabExtendedView.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ import pl.szczodrzynski.navlib.bottomsheet.NavBottomSheet
|
||||
|
||||
interface NavMenuBarBase {
|
||||
|
||||
var bottomSheet: NavBottomSheet
|
||||
var drawerClickListener: (() -> Unit)?
|
||||
var menuClickListener: (() -> Unit)?
|
||||
|
||||
@ -54,11 +53,7 @@ interface NavMenuBarBase {
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
|
||||
setOnMenuItemClickListener {
|
||||
if (it.itemId == -1 && bottomSheet.enable) {
|
||||
bottomSheet.toggle()
|
||||
} else {
|
||||
menuClickListener?.invoke()
|
||||
}
|
||||
menuClickListener?.invoke()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ class NavToolbar @JvmOverloads constructor(
|
||||
) : MaterialToolbar(context, attrs, defStyle), NavMenuBarBase {
|
||||
|
||||
internal lateinit var navView: NavView
|
||||
override lateinit var bottomSheet: NavBottomSheet
|
||||
|
||||
/**
|
||||
* Shows the toolbar and sets the contentView's margin to be
|
||||
|
@ -33,11 +33,11 @@ class NavView @JvmOverloads constructor(
|
||||
get() = b.nvCoordinator
|
||||
val toolbar
|
||||
get() = b.nvToolbar
|
||||
val bottomBar: NavBottomBar
|
||||
val bottomBar
|
||||
get() = b.nvBottomBar
|
||||
val nightlyText: TextView
|
||||
val nightlyText
|
||||
get() = b.nvNightlyText
|
||||
val bottomSheet: NavBottomSheet
|
||||
val bottomSheet
|
||||
get() = b.nvBottomSheet
|
||||
|
||||
init {
|
||||
@ -55,13 +55,18 @@ class NavView @JvmOverloads constructor(
|
||||
drawer.bottomBar = b.nvBottomBar
|
||||
|
||||
b.nvToolbar.navView = this
|
||||
b.nvToolbar.bottomSheet = b.nvBottomSheet
|
||||
b.nvToolbar.toolbarImage = b.nvToolbarImage
|
||||
|
||||
b.nvBottomBar.navView = this
|
||||
b.nvBottomBar.bottomSheet = b.nvBottomSheet
|
||||
b.nvBottomBar.fabView = b.nvFloatingActionButton
|
||||
b.nvBottomBar.fabExtendedView = b.nvExtendedFloatingActionButton
|
||||
|
||||
toolbar.drawerClickListener = drawer::open
|
||||
toolbar.menuClickListener = bottomSheet::open
|
||||
bottomBar.drawerClickListener = drawer::open
|
||||
bottomBar.menuClickListener = bottomSheet::open
|
||||
|
||||
b.nvBottomBar.setOnTouchListener(bottomSheet::dispatchBottomSheetEvent)
|
||||
b.nvBottomSheet.scrimView.setOnTouchListener(bottomSheet::dispatchBottomSheetEvent)
|
||||
}
|
||||
|
||||
fun configSystemBarsUtil(systemBarsUtil: SystemBarsUtil) {
|
||||
|
@ -1,11 +1,15 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Configuration.ORIENTATION_PORTRAIT
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.os.Build.VERSION_CODES
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.View.*
|
||||
@ -351,6 +355,42 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun isTablet(c: Context): Boolean {
|
||||
return (c.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
|
||||
}
|
||||
|
||||
private 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().
|
||||
val navBarOverride = System.getProperty("qemu.hw.mainkeys")
|
||||
if (navBarOverride == "1")
|
||||
hasNavigationBar = true
|
||||
else if (navBarOverride == "0") hasNavigationBar = false
|
||||
|
||||
return hasNavigationBar
|
||||
}
|
||||
|
||||
private fun applyPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||
marginBySystemBars?.setPadding(left, top, right, bottom)
|
||||
|
||||
|
@ -1,65 +1,20 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.os.Build
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||
import com.mikepenz.iconics.IconicsColor
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
|
||||
|
||||
/*private val displayMetrics by lazy {
|
||||
context.resources.displayMetrics
|
||||
}*/
|
||||
/*private val configuration by lazy { context.resources.configuration }
|
||||
private val displayWidth: Int by lazy { configuration.screenWidthDp }
|
||||
private val displayHeight: Int by lazy { configuration.screenHeightDp }*/
|
||||
|
||||
fun getTopInset(context: Context, view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetTop ?: 24)
|
||||
} else {
|
||||
24
|
||||
} * context.resources.displayMetrics.density
|
||||
}
|
||||
fun getLeftInset(context: Context, view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetLeft ?: 0)
|
||||
} else {
|
||||
0
|
||||
} * context.resources.displayMetrics.density
|
||||
}
|
||||
fun getRightInset(context: Context, view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetRight ?: 0)
|
||||
} else {
|
||||
0
|
||||
} * context.resources.displayMetrics.density
|
||||
}
|
||||
fun getBottomInset(context: Context, view: View): Float {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
(view.rootWindowInsets?.systemWindowInsetBottom ?: 48)
|
||||
} else {
|
||||
48
|
||||
} * context.resources.displayMetrics.density
|
||||
}
|
||||
|
||||
fun View.getActivity(): Activity {
|
||||
return findViewById<View>(android.R.id.content).context as Activity
|
||||
}
|
||||
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||
import com.mikepenz.materialdrawer.model.interfaces.Badgeable
|
||||
import com.mikepenz.materialdrawer.model.interfaces.withBadge
|
||||
import com.mikepenz.materialdrawer.util.getDrawerItem
|
||||
import com.mikepenz.materialdrawer.util.updateItem
|
||||
import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
|
||||
|
||||
fun blendColors(background: Int, foreground: Int): Int {
|
||||
val r1 = (background shr 16 and 0xff)
|
||||
@ -70,7 +25,6 @@ fun blendColors(background: Int, foreground: Int): Int {
|
||||
val g2 = (foreground shr 8 and 0xff)
|
||||
val b2 = (foreground and 0xff)
|
||||
val a2 = (foreground shr 24 and 0xff)
|
||||
//ColorUtils.compositeColors()
|
||||
|
||||
val factor = a2.toFloat() / 255f
|
||||
val red = (r1 * (1 - factor) + r2 * factor)
|
||||
@ -86,42 +40,6 @@ fun elevateSurface(context: Context, dp: Int): Int {
|
||||
}
|
||||
}
|
||||
|
||||
fun isTablet(c: Context): Boolean {
|
||||
return (c.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
|
||||
}
|
||||
|
||||
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().
|
||||
val navBarOverride = System.getProperty("qemu.hw.mainkeys")
|
||||
if (navBarOverride == "1")
|
||||
hasNavigationBar = true
|
||||
else if (navBarOverride == "0") hasNavigationBar = false
|
||||
|
||||
return hasNavigationBar
|
||||
}
|
||||
|
||||
fun IconicsDrawable.colorAttr(context: Context, @AttrRes attrRes: Int) {
|
||||
colorInt = getColorFromAttr(context, attrRes)
|
||||
}
|
||||
@ -135,25 +53,6 @@ fun getColorFromAttr(context: Context, @AttrRes color: Int): Int {
|
||||
return typedValue.data
|
||||
}
|
||||
|
||||
fun Context.getDrawableFromRes(@DrawableRes id: Int): Drawable {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
resources.getDrawable(id, theme)
|
||||
}
|
||||
else {
|
||||
resources.getDrawable(id)
|
||||
}
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
fun Context.getColorFromRes(@ColorRes id: Int): Int {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
resources.getColor(id, theme)
|
||||
}
|
||||
else {
|
||||
resources.getColor(id)
|
||||
}
|
||||
}
|
||||
|
||||
fun Drawable.setBadgeCount(count: Int) {
|
||||
if (this is LayerDrawable) {
|
||||
(this as LayerDrawable?)?.apply {
|
||||
@ -168,16 +67,10 @@ fun Drawable.setBadgeCount(count: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
fun crc16(buffer: String): Int {
|
||||
/* Note the change here */
|
||||
var crc = 0x1D0F
|
||||
for (j in buffer) {
|
||||
crc = crc.ushr(8) or (crc shl 8) and 0xffff
|
||||
crc = crc xor (j.toInt() and 0xff)//byte to int, trunc sign
|
||||
crc = crc xor (crc and 0xff shr 4)
|
||||
crc = crc xor (crc shl 12 and 0xffff)
|
||||
crc = crc xor (crc and 0xFF shl 5 and 0xffff)
|
||||
fun MaterialDrawerSliderView.updateBadge(identifier: Long, badge: StringHolder?) {
|
||||
val drawerItem = getDrawerItem(identifier)
|
||||
if (drawerItem is Badgeable) {
|
||||
drawerItem.withBadge(badge)
|
||||
updateItem(drawerItem)
|
||||
}
|
||||
crc = crc and 0xffff
|
||||
return crc
|
||||
}
|
||||
|
@ -1,135 +1,49 @@
|
||||
package pl.szczodrzynski.navlib.bottomsheet
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
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.navlibfont.NavLibFont
|
||||
import com.mikepenz.iconics.utils.paddingDp
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import pl.szczodrzynski.navlib.*
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.IBottomSheetItem
|
||||
import pl.szczodrzynski.navlib.databinding.NavBottomSheetBinding
|
||||
import pl.szczodrzynski.navlib.elevateSurface
|
||||
|
||||
class NavBottomSheet @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0,
|
||||
) : CoordinatorLayout(context, attrs, defStyle) {
|
||||
|
||||
class NavBottomSheet : CoordinatorLayout {
|
||||
companion object {
|
||||
const val TOGGLE_GROUP_SINGLE_SELECTION = 0
|
||||
const val TOGGLE_GROUP_MULTIPLE_SELECTION = 1
|
||||
const val TOGGLE_GROUP_SORTING_ORDER = 2
|
||||
private val b = NavBottomSheetBinding.inflate(LayoutInflater.from(context), this, true)
|
||||
|
||||
const val SORT_MODE_ASCENDING = 0
|
||||
const val SORT_MODE_DESCENDING = 1
|
||||
}
|
||||
val scrimView
|
||||
get() = b.bsScrim
|
||||
private val bottomSheet
|
||||
get() = b.bsView
|
||||
private val content
|
||||
get() = b.bsContent
|
||||
private val dragBar
|
||||
get() = b.bsDragBar
|
||||
private val list
|
||||
get() = b.bsList
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
create(null, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
create(attrs, 0)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
|
||||
create(attrs, defStyle)
|
||||
}
|
||||
|
||||
private lateinit var scrimView: View
|
||||
private lateinit var bottomSheet: NestedScrollView
|
||||
private lateinit var 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
|
||||
private lateinit var list: RecyclerView
|
||||
|
||||
private lateinit var bottomSheetBehavior: BottomSheetBehavior<View>
|
||||
private var bottomSheetVisible = false
|
||||
private var bottomSheetBehavior = BottomSheetBehavior.from<View>(bottomSheet)
|
||||
|
||||
private val items = ArrayList<IBottomSheetItem<*>>()
|
||||
private val adapter = BottomSheetAdapter(items)
|
||||
|
||||
/**
|
||||
* Enable the bottom sheet.
|
||||
* This value is mostly relevant to the [pl.szczodrzynski.navlib.NavBottomBar].
|
||||
*/
|
||||
var enable = true
|
||||
set(value) {
|
||||
field = value
|
||||
if (!value && bottomSheetVisible)
|
||||
close()
|
||||
}
|
||||
/**
|
||||
* Whether the [pl.szczodrzynski.navlib.NavBottomBar] should open this BottomSheet
|
||||
* when the user drags the bottom bar.
|
||||
*/
|
||||
var enableDragToOpen = true
|
||||
|
||||
/**
|
||||
* Control the scrim view visibility, shown when BottomSheet
|
||||
* is expanded.
|
||||
*/
|
||||
var scrimViewEnabled = true
|
||||
set(value) {
|
||||
scrimView.visibility = if (value) View.INVISIBLE else View.GONE // INVISIBLE
|
||||
field = value
|
||||
}
|
||||
/**
|
||||
* Whether tapping the Scrim view should hide the BottomSheet.
|
||||
*/
|
||||
var scrimViewTapToClose = true
|
||||
|
||||
|
||||
fun hideKeyboard() {
|
||||
val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(rootView.windowToken, 0)
|
||||
}
|
||||
|
||||
|
||||
private fun create(attrs: AttributeSet?, defStyle: Int) {
|
||||
val layoutInflater = LayoutInflater.from(context)
|
||||
layoutInflater.inflate(R.layout.nav_bottom_sheet, this)
|
||||
|
||||
scrimView = findViewById(R.id.bs_scrim)
|
||||
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)
|
||||
list = findViewById(R.id.bs_list)
|
||||
|
||||
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
|
||||
|
||||
init {
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(list) { view, windowInsets ->
|
||||
@ -144,32 +58,29 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
WindowInsetsCompat.CONSUMED
|
||||
}
|
||||
|
||||
scrimView.setOnTouchListener { _, event ->
|
||||
if (!scrimViewTapToClose)
|
||||
return@setOnTouchListener true
|
||||
if (event.action == MotionEvent.ACTION_UP && bottomSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN) {
|
||||
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
true
|
||||
scrimView.setOnClickListener {
|
||||
isOpen = false
|
||||
}
|
||||
|
||||
bottomSheetBehavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(v: View, p1: Float) {}
|
||||
override fun onStateChanged(v: View, newState: Int) {
|
||||
var bottomSheetVisible = false
|
||||
bottomSheetBehavior.addBottomSheetCallback(object :
|
||||
BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(view: View, slideOffset: Float) {
|
||||
val alpha = (1.0f + slideOffset).coerceIn(0.0f, 1.0f)
|
||||
scrimView.alpha = alpha
|
||||
scrimView.isInvisible = alpha == 0.0f
|
||||
}
|
||||
|
||||
override fun onStateChanged(view: View, newState: Int) {
|
||||
if (newState == BottomSheetBehavior.STATE_HIDDEN && bottomSheetVisible) {
|
||||
bottomSheetVisible = false
|
||||
bottomSheet.scrollTo(0, 0)
|
||||
if (scrimViewEnabled)
|
||||
Anim.fadeOut(scrimView, 300, null)
|
||||
// steal the focus from any EditTexts
|
||||
dragBar.requestFocus()
|
||||
hideKeyboard()
|
||||
onCloseListener?.invoke()
|
||||
}
|
||||
else if (!bottomSheetVisible) {
|
||||
} else if (!bottomSheetVisible) {
|
||||
bottomSheetVisible = true
|
||||
if (scrimViewEnabled)
|
||||
Anim.fadeIn(scrimView, 300, null)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -187,11 +98,11 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = this@NavBottomSheet.adapter
|
||||
}
|
||||
|
||||
toggleGroup.addOnButtonCheckedListener(toggleGroupCheckedListener)
|
||||
textInputEditText.addTextChangedListener(textInputWatcher)
|
||||
}
|
||||
|
||||
fun hideKeyboard() = context.getSystemService<InputMethodManager>()
|
||||
?.hideSoftInputFromWindow(rootView.windowToken, 0)
|
||||
|
||||
var onCloseListener: (() -> Unit)? = null
|
||||
|
||||
/* _____ _
|
||||
@ -203,55 +114,61 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
operator fun plusAssign(item: IBottomSheetItem<*>) {
|
||||
appendItem(item)
|
||||
}
|
||||
|
||||
fun appendItem(item: IBottomSheetItem<*>) {
|
||||
items.add(item)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemInserted(items.size - 1)
|
||||
}
|
||||
|
||||
fun appendItems(vararg items: IBottomSheetItem<*>) {
|
||||
this.items.addAll(items)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemRangeInserted(this.items.size - items.size, items.size)
|
||||
}
|
||||
|
||||
fun prependItem(item: IBottomSheetItem<*>) {
|
||||
items.add(0, item)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemInserted(0)
|
||||
}
|
||||
|
||||
fun prependItems(vararg items: IBottomSheetItem<*>) {
|
||||
this.items.addAll(0, items.toList())
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemRangeInserted(0, items.size)
|
||||
}
|
||||
|
||||
fun addItemAt(index: Int, item: IBottomSheetItem<*>) {
|
||||
items.add(index, item)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemInserted(index)
|
||||
}
|
||||
|
||||
fun removeItemById(id: Int) {
|
||||
items.filterNot { it.id == id }
|
||||
}
|
||||
|
||||
fun removeItemAt(index: Int) {
|
||||
items.removeAt(index)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemRemoved(index)
|
||||
}
|
||||
|
||||
fun removeAllItems() {
|
||||
items.clear()
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun removeAllStatic() {
|
||||
items.removeAll { !it.isContextual }
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun removeAllContextual() {
|
||||
items.removeAll { it.isContextual }
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
fun removeSeparators() {
|
||||
items.removeAll { it is BottomSheetSeparatorItem }
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun getItemById(id: Int, run: (it: IBottomSheetItem<*>?) -> Unit) {
|
||||
items.singleOrNull { it.id == id }.also {
|
||||
@ -260,6 +177,7 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
adapter.notifyItemChanged(items.indexOf(it))
|
||||
}
|
||||
}
|
||||
|
||||
fun getItemByIndex(index: Int, run: (it: IBottomSheetItem<*>?) -> Unit) {
|
||||
items.getOrNull(index).also {
|
||||
run(it)
|
||||
@ -268,185 +186,33 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* _______ _
|
||||
|__ __| | |
|
||||
| | ___ __ _ __ _| | ___ __ _ _ __ ___ _ _ _ __
|
||||
| |/ _ \ / _` |/ _` | |/ _ \ / _` | '__/ _ \| | | | '_ \
|
||||
| | (_) | (_| | (_| | | __/ | (_| | | | (_) | |_| | |_) |
|
||||
|_|\___/ \__, |\__, |_|\___| \__, |_| \___/ \__,_| .__/
|
||||
__/ | __/ | __/ | | |
|
||||
|___/ |___/ |___/ |*/
|
||||
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 }
|
||||
var toggleGroupSelectionMode: Int = TOGGLE_GROUP_SORTING_ORDER
|
||||
set(value) {
|
||||
field = value
|
||||
toggleGroup.isSingleSelection = value != TOGGLE_GROUP_MULTIPLE_SELECTION
|
||||
}
|
||||
|
||||
private fun toggleGroupGetIconicsDrawable(context: Context, icon: IIcon?): Drawable? {
|
||||
if (icon == null)
|
||||
return null
|
||||
return IconicsDrawable(context, icon).apply {
|
||||
sizeDp = 24
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleGroupAddItem(id: Int, text: String, @DrawableRes icon: Int, defaultSortOrder: Int = SORT_MODE_ASCENDING) {
|
||||
toggleGroupAddItem(id, text, context.getDrawableFromRes(icon), defaultSortOrder)
|
||||
}
|
||||
fun toggleGroupAddItem(id: Int, text: String, icon: IIcon, defaultSortOrder: Int = SORT_MODE_ASCENDING) {
|
||||
toggleGroupAddItem(id, text, toggleGroupGetIconicsDrawable(context, icon), defaultSortOrder)
|
||||
}
|
||||
fun toggleGroupAddItem(id: Int, text: String, icon: Drawable?, defaultSortOrder: Int = SORT_MODE_ASCENDING) {
|
||||
if (id < 0)
|
||||
throw IllegalArgumentException("ID cannot be less than 0")
|
||||
toggleGroup.addView(MaterialButton(context, null, R.attr.materialButtonOutlinedStyle).apply {
|
||||
this.id = id + 1
|
||||
this.tag = defaultSortOrder
|
||||
this.text = text
|
||||
this.icon = icon
|
||||
}, WRAP_CONTENT, WRAP_CONTENT)
|
||||
}
|
||||
fun toggleGroupCheck(id: Int) {
|
||||
toggleGroup.check(id)
|
||||
}
|
||||
fun toggleGroupRemoveItems() {
|
||||
toggleGroup.removeAllViews()
|
||||
}
|
||||
|
||||
private val toggleGroupCheckedListener = MaterialButtonToggleGroup.OnButtonCheckedListener { group, checkedId, isChecked ->
|
||||
if (group.checkedButtonId == View.NO_ID) {
|
||||
group.check(checkedId)
|
||||
return@OnButtonCheckedListener
|
||||
}
|
||||
/* TAG bit order
|
||||
* bit 0 = default sorting mode
|
||||
* bit 1 = is checked
|
||||
* bit 2 = current sorting mode
|
||||
*/
|
||||
if (toggleGroupSelectionMode == TOGGLE_GROUP_SORTING_ORDER) {
|
||||
val button = group.findViewById<MaterialButton>(checkedId) ?: return@OnButtonCheckedListener
|
||||
var tag = button.tag as Int
|
||||
var sortingMode: Int? = null
|
||||
if (isChecked) {
|
||||
sortingMode = if (tag and 0b010 == 1 shl 1) {
|
||||
/* the view is checked and clicked once again */
|
||||
if (tag and 0b100 == SORT_MODE_ASCENDING shl 2) SORT_MODE_DESCENDING else SORT_MODE_ASCENDING
|
||||
} else {
|
||||
/* the view is first clicked so use the default sorting mode */
|
||||
if (tag and 0b001 == SORT_MODE_ASCENDING) SORT_MODE_ASCENDING else SORT_MODE_DESCENDING
|
||||
}
|
||||
tag = tag and 0b001 /* retain only default sorting mode */
|
||||
tag = tag or 0b010 /* set as checked */
|
||||
tag = tag or (sortingMode shl 2) /* set new sorting mode */
|
||||
}
|
||||
else {
|
||||
tag = tag and 0b001 /* retain only default sorting mode */
|
||||
}
|
||||
button.tag = tag
|
||||
button.icon = toggleGroupGetIconicsDrawable(context, when (sortingMode) {
|
||||
SORT_MODE_ASCENDING -> NavLibFont.Icon.nav_sort_ascending
|
||||
SORT_MODE_DESCENDING -> NavLibFont.Icon.nav_sort_descending
|
||||
else -> null
|
||||
})
|
||||
if (sortingMode != null) {
|
||||
toggleGroupSortingOrderListener?.invoke(checkedId, sortingMode)
|
||||
}
|
||||
}
|
||||
else if (toggleGroup.isSingleSelection && isChecked) {
|
||||
toggleGroupSingleSelectionListener?.invoke(checkedId - 1)
|
||||
}
|
||||
else {
|
||||
toggleGroupMultipleSelectionListener?.invoke(checkedId - 1, isChecked)
|
||||
}
|
||||
}
|
||||
|
||||
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).apply {
|
||||
icon = 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)
|
||||
}
|
||||
}
|
||||
|
||||
interface OnTextInputChangedListener {
|
||||
fun onTextChanged(s: String, start: Int, before: Int, count: Int)
|
||||
}
|
||||
var textInputChangedListener: OnTextInputChangedListener? = null
|
||||
|
||||
|
||||
|
||||
fun dispatchBottomBarEvent(event: MotionEvent) {
|
||||
fun dispatchBottomSheetEvent(view: View, event: MotionEvent): Boolean {
|
||||
val location = IntArray(2)
|
||||
bottomSheet.getLocationOnScreen(location)
|
||||
event.setLocation(event.rawX - location[0], event.rawY - location[1])
|
||||
bottomSheet.dispatchTouchEvent(event)
|
||||
return false
|
||||
}
|
||||
|
||||
fun setContentPadding(left: Int, top: Int, right: Int, bottom: Int) {
|
||||
content.setPadding(left, top, right, bottom)
|
||||
}
|
||||
fun getContentView() = content
|
||||
|
||||
var isOpen
|
||||
get() = bottomSheetBehavior.state != BottomSheetBehavior.STATE_HIDDEN
|
||||
set(value) {
|
||||
bottomSheetBehavior.state = if (value) BottomSheetBehavior.STATE_EXPANDED else BottomSheetBehavior.STATE_HIDDEN
|
||||
bottomSheetBehavior.state =
|
||||
if (value)
|
||||
BottomSheetBehavior.STATE_EXPANDED
|
||||
else
|
||||
BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
fun open() { isOpen = true }
|
||||
fun close() { isOpen = false }
|
||||
|
||||
fun open() {
|
||||
isOpen = true
|
||||
}
|
||||
|
||||
fun close() {
|
||||
isOpen = false
|
||||
}
|
||||
|
||||
fun toggle() {
|
||||
if (!enable)
|
||||
return
|
||||
isOpen = !isOpen
|
||||
}
|
||||
}
|
||||
|
@ -212,12 +212,6 @@ class NavDrawer(
|
||||
profileSelectionOpen()
|
||||
open()
|
||||
}
|
||||
toolbar.drawerClickListener = {
|
||||
open()
|
||||
}
|
||||
bottomBar.drawerClickListener = {
|
||||
open()
|
||||
}
|
||||
|
||||
val configuration = context.resources.configuration
|
||||
decideDrawerMode(
|
||||
@ -227,69 +221,6 @@ class NavDrawer(
|
||||
)
|
||||
}
|
||||
|
||||
/* _____ _
|
||||
|_ _| |
|
||||
| | | |_ ___ _ __ ___ ___
|
||||
| | | __/ _ \ '_ ` _ \/ __|
|
||||
_| |_| || __/ | | | | \__ \
|
||||
|_____|\__\___|_| |_| |_|__*/
|
||||
operator fun plusAssign(item: IDrawerItem<*>) {
|
||||
appendItem(item)
|
||||
}
|
||||
fun appendItem(item: IDrawerItem<*>) {
|
||||
drawer.addItems(item)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun appendItems(vararg items: IDrawerItem<*>) {
|
||||
drawer.addItems(*items)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun prependItem(item: IDrawerItem<*>) {
|
||||
drawer.addItemAtPosition(0, item)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun prependItems(vararg items: IDrawerItem<*>) {
|
||||
drawer.addItemsAtPosition(0, *items)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun addItemAt(index: Int, item: IDrawerItem<*>) {
|
||||
drawer.addItemAtPosition(index, item)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun addItemsAt(index: Int, vararg items: IDrawerItem<*>) {
|
||||
drawer.addItemsAtPosition(index, *items)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
fun removeItemById(id: Int) {
|
||||
drawer.removeItems(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.itemAdapter.itemList.get(index).also {
|
||||
run(it)
|
||||
if (it != null)
|
||||
drawer.updateItem(it)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
}
|
||||
|
||||
fun setItems(vararg items: IDrawerItem<*>) {
|
||||
drawer.removeAllItems()
|
||||
drawer.addItems(*items)
|
||||
|
@ -4,15 +4,5 @@ import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
|
||||
|
||||
class DrawerPrimaryItem : PrimaryDrawerItem() {
|
||||
var appTitle: String? = null
|
||||
fun withAppTitle(appTitle: String?): PrimaryDrawerItem {
|
||||
this.appTitle = appTitle
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
fun PrimaryDrawerItem.withAppTitle(appTitle: String?): PrimaryDrawerItem {
|
||||
if (this !is DrawerPrimaryItem)
|
||||
return this
|
||||
this.appTitle = appTitle
|
||||
return this
|
||||
}
|
@ -1,109 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:translationZ="10dp"
|
||||
tools:targetApi="lollipop">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
<View
|
||||
android:id="@+id/bs_scrim"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:translationZ="10dp"
|
||||
tools:targetApi="lollipop">
|
||||
android:background="#99000000"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bs_scrim"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#99000000"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="gone" />
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/bs_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:maxWidth="600dp"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="auto"
|
||||
app:layout_behavior="@string/bottom_sheet_behavior"
|
||||
tools:visibility="visible">
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/bs_view"
|
||||
<LinearLayout
|
||||
android:id="@+id/bs_content"
|
||||
android:layout_width="match_parent"
|
||||
android:maxWidth="600dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="auto"
|
||||
app:layout_behavior="@string/bottom_sheet_behavior"
|
||||
tools:visibility="visible">
|
||||
android:background="@drawable/bottom_sheet_background"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="8dp"
|
||||
tools:paddingBottom="48dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bs_content"
|
||||
<ImageView
|
||||
android:id="@+id/bs_dragBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
app:srcCompat="@drawable/bottom_sheet_control_bar"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/bs_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bottom_sheet_background"
|
||||
android:paddingHorizontal="8dp"
|
||||
tools:paddingBottom="48dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/bs_dragBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="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="?textInputFilledDenseStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
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:layout_marginBottom="16dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bs_toggleGroupTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Sorting order" />
|
||||
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
android:id="@+id/bs_toggleGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:singleSelection="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/bs_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="never"
|
||||
tools:minHeight="50dp"
|
||||
tools:listitem="@layout/nav_bs_item_primary"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</layout>
|
||||
android:overScrollMode="never"
|
||||
tools:listitem="@layout/nav_bs_item_primary"
|
||||
tools:minHeight="50dp" />
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
@ -1,18 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<merge
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
tools:background="#202020"
|
||||
tools:parentTag="FrameLayout">
|
||||
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
android:id="@+id/nv_drawerLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:baselineAligned="false">
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
@ -33,8 +35,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
tools:paddingTop="24dp"
|
||||
tools:paddingBottom="48dp">
|
||||
tools:paddingBottom="48dp"
|
||||
tools:paddingTop="24dp">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/nv_drawerContainerLandscape"
|
||||
@ -50,22 +52,17 @@
|
||||
|
||||
<pl.szczodrzynski.navlib.NavToolbar
|
||||
android:id="@+id/nv_toolbar"
|
||||
style="?toolbarSurfaceStyle"
|
||||
style="?toolbarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?nvActionBarBackground"
|
||||
android:clipToPadding="false"
|
||||
android:elevation="4dp"
|
||||
app:title="@string/app_name"
|
||||
app:titleMargin="0dp"
|
||||
tools:targetApi="lollipop">
|
||||
android:clipToPadding="false">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nv_nightlyText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:layout_margin="8dp"
|
||||
android:background="@drawable/nightly_text_rounded"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:padding="4dp"
|
||||
@ -85,7 +82,6 @@
|
||||
android:scaleType="centerCrop"
|
||||
app:materialDrawerSelectorOnPress="#80ffffff"
|
||||
tools:src="@tools:sample/backgrounds/scenic" />
|
||||
|
||||
</pl.szczodrzynski.navlib.NavToolbar>
|
||||
|
||||
<View
|
||||
@ -103,7 +99,7 @@
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="?actionBarSize"
|
||||
android:layout_marginBottom="?actionBarSize"
|
||||
android:orientation="horizontal" >
|
||||
android:orientation="horizontal">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/nv_miniDrawerContainerPortrait"
|
||||
@ -111,13 +107,11 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/colorSurface_4dp"
|
||||
tools:layout_width="72dp" /><!--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
|
||||
@ -126,9 +120,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?nvBottomBarBackground"
|
||||
android:gravity="start"
|
||||
android:visibility="visible"
|
||||
app:fabAlignmentMode="center"
|
||||
app:fabAnimationMode="scale" />
|
||||
|
||||
@ -143,19 +134,7 @@
|
||||
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:clickable="true"
|
||||
android:focusable="true"
|
||||
android:visibility="gone"
|
||||
app:layout_anchor="@id/nv_bottomBar"
|
||||
tools:srcCompat="@android:drawable/ic_menu_edit" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
@ -165,9 +144,7 @@
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?nvNavigationBarBackground"
|
||||
tools:layout_height="48dp" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
|
||||
<View
|
||||
@ -194,6 +171,4 @@
|
||||
android:id="@+id/nv_bottomSheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
|
||||
</merge>
|
||||
|
Reference in New Issue
Block a user