mirror of
https://github.com/kuba2k2/NavLib.git
synced 2025-04-03 07:14:28 +02:00
Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a5a1597e40 | ||
![]() |
60cc1171f9 | ||
![]() |
8f10321820 | ||
![]() |
30d86d9618 | ||
![]() |
556d568228 | ||
![]() |
8a0e0438a5 | ||
![]() |
578306480b | ||
![]() |
7430169359 | ||
![]() |
4f08f171d6 | ||
![]() |
15c95baa6a | ||
![]() |
43fc2f10df | ||
![]() |
642d297cd0 | ||
![]() |
28cdab3414 | ||
![]() |
43f5ecdef5 | ||
![]() |
1d0e98a90e | ||
![]() |
3873fa4b04 | ||
![]() |
fd757f4228 | ||
![]() |
5c8b13c0d9 | ||
![]() |
9002237a02 | ||
![]() |
9c8fb47c52 | ||
![]() |
8b31921697 | ||
![]() |
8ae5e2b87a | ||
![]() |
e4ad01dc87 | ||
![]() |
84d6447887 | ||
![]() |
01c787405e | ||
![]() |
8a707ebec7 | ||
![]() |
3ed34a4705 | ||
![]() |
345cf00311 | ||
![]() |
9e2e4f6057 | ||
![]() |
c26753fdc6 | ||
![]() |
2efa7f4947 | ||
![]() |
e8a64a7c9b | ||
![]() |
ab7211e85c |
4
.gitignore
vendored
4
.gitignore
vendored
@ -11,4 +11,6 @@
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
/_hakerskie
|
||||
/_hakerskie
|
||||
*.apk
|
||||
app/release/
|
4
.idea/gradle.xml
generated
4
.idea/gradle.xml
generated
@ -1,8 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="PLATFORM" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
@ -10,10 +12,10 @@
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/navlib" />
|
||||
<option value="$PROJECT_DIR$/navlib-font" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
<option name="testRunner" value="PLATFORM" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
30
.idea/jarRepositories.xml
generated
Normal file
30
.idea/jarRepositories.xml
generated
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="BintrayJCenter" />
|
||||
<option name="name" value="BintrayJCenter" />
|
||||
<option name="url" value="https://jcenter.bintray.com/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="https://jitpack.io" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="Google" />
|
||||
<option name="name" value="Google" />
|
||||
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -5,7 +5,7 @@
|
||||
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
|
||||
</configurations>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="false" project-jdk-name="JDK" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
1
.idea/runConfigurations.xml
generated
1
.idea/runConfigurations.xml
generated
@ -3,6 +3,7 @@
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||
|
@ -1,21 +1,22 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
compileSdkVersion setup.compileSdk
|
||||
|
||||
defaultConfig {
|
||||
applicationId "pl.szczodrzynski.navigation"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
versionCode 200
|
||||
versionName "0.2.0"
|
||||
minSdkVersion setup.minSdk
|
||||
targetSdkVersion setup.targetSdk
|
||||
versionCode release.versionCode
|
||||
versionName release.versionName
|
||||
|
||||
multiDexEnabled true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
@ -32,16 +33,18 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.0.2'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation "androidx.appcompat:appcompat:1.2.0"
|
||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
//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
|
||||
implementation "com.mikepenz:community-material-typeface:3.5.95.1-kotlin@aar"
|
||||
implementation 'androidx.core:core-ktx:1.0.2'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation "com.google.android.material:material:$material_version"
|
||||
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
|
||||
implementation "androidx.core:core-ktx:1.3.2"
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||
implementation "com.google.android.material:material:1.3.0"
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
|
||||
implementation "com.mikepenz:iconics-views:5.3.0-b01"
|
||||
implementation "com.mikepenz:community-material-typeface:5.8.55.0-kotlin@aar"
|
||||
|
||||
// implementation "pl.droidsonroids.gif:android-gif-drawable:1.2.15"
|
||||
implementation project(":navlib")
|
||||
}
|
||||
|
8
app/proguard-rules.pro
vendored
8
app/proguard-rules.pro
vendored
@ -19,3 +19,11 @@
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
-keep class .R
|
||||
-keep class **.R$* {
|
||||
<fields>;
|
||||
}
|
||||
|
||||
-keep class android.support.v7.** { *; }
|
||||
-keep interface android.support.v7.** { *; }
|
@ -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,11 @@
|
||||
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:name="androidx.multidex.MultiDexApplication"
|
||||
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" />
|
||||
|
||||
@ -21,4 +25,4 @@
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
@ -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,91 @@
|
||||
package pl.szczodrzynski.navigation
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.widget.ImageView
|
||||
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
|
||||
import pl.szczodrzynski.navlib.ImageHolder
|
||||
import pl.szczodrzynski.navlib.crc16
|
||||
import pl.szczodrzynski.navlib.drawer.IDrawerProfile
|
||||
import pl.szczodrzynski.navlib.getColorFromRes
|
||||
import pl.szczodrzynski.navlib.getDrawableFromRes
|
||||
|
||||
/*
|
||||
Example IDrawerProfile implementation
|
||||
*/
|
||||
class DrawerProfile(
|
||||
override val id: Int,
|
||||
override var name: String,
|
||||
override var subname: String?,
|
||||
override var image: String?
|
||||
) : IDrawerProfile {
|
||||
|
||||
private fun colorFromName(context: Context, name: String?): Int {
|
||||
var crc = crc16(name ?: "")
|
||||
crc = (crc and 0xff) or (crc shr 8)
|
||||
crc %= 16
|
||||
val color = when (crc) {
|
||||
13 -> R.color.md_red_500
|
||||
4 -> R.color.md_pink_A400
|
||||
2 -> R.color.md_purple_A400
|
||||
9 -> R.color.md_deep_purple_A700
|
||||
5 -> R.color.md_indigo_500
|
||||
1 -> R.color.md_indigo_A700
|
||||
6 -> R.color.md_cyan_A200
|
||||
14 -> R.color.md_teal_400
|
||||
15 -> R.color.md_green_500
|
||||
7 -> R.color.md_yellow_A700
|
||||
3 -> R.color.md_deep_orange_A400
|
||||
8 -> R.color.md_deep_orange_A700
|
||||
10 -> R.color.md_brown_500
|
||||
12 -> R.color.md_grey_400
|
||||
11 -> R.color.md_blue_grey_400
|
||||
else -> R.color.md_light_green_A700
|
||||
}
|
||||
return context.getColorFromRes(color)
|
||||
}
|
||||
|
||||
/* This method is not used in the drawer */
|
||||
/* return null if you do not want an image in the Toolbar */
|
||||
override fun getImageDrawable(context: Context): Drawable? {
|
||||
if (!image.isNullOrEmpty()) {
|
||||
try {
|
||||
if (image?.endsWith(".gif", true) == true) {
|
||||
/* if you want to use GIFs as profile drawables, add
|
||||
implementation "pl.droidsonroids.gif:android-gif-drawable:${versions.gifdrawable}"
|
||||
*/
|
||||
return null//GifDrawable(image ?: "")
|
||||
}
|
||||
else {
|
||||
return RoundedBitmapDrawableFactory.create(context.resources, image ?: "")
|
||||
//return Drawable.createFromPath(image ?: "") ?: throw Exception()
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
return context.getDrawableFromRes(R.drawable.profile).also {
|
||||
it.colorFilter = PorterDuffColorFilter(colorFromName(context, name), PorterDuff.Mode.DST_OVER)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getImageHolder(context: Context): ImageHolder {
|
||||
return if (!image.isNullOrEmpty()) {
|
||||
try {
|
||||
ImageHolder(image ?: "")
|
||||
} catch (_: Exception) {
|
||||
ImageHolder(R.drawable.profile, colorFromName(context, name))
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImageHolder(R.drawable.profile, colorFromName(context, name))
|
||||
}
|
||||
}
|
||||
override fun applyImageTo(imageView: ImageView) {
|
||||
getImageHolder(imageView.context).applyTo(imageView)
|
||||
}
|
||||
}
|
@ -8,7 +8,15 @@ import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.mikepenz.iconics.Iconics
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.iconics.utils.actionBar
|
||||
import com.mikepenz.iconics.utils.paddingDp
|
||||
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.*
|
||||
import com.mikepenz.materialdrawer.model.utils.withIsHiddenInMiniDrawer
|
||||
import kotlinx.android.synthetic.main.sample_nav_view.*
|
||||
import pl.szczodrzynski.navlib.SystemBarsUtil
|
||||
import pl.szczodrzynski.navlib.SystemBarsUtil.Companion.COLOR_DO_NOT_CHANGE
|
||||
@ -18,9 +26,12 @@ 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.colorAttr
|
||||
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
||||
import pl.szczodrzynski.navlib.getColorFromAttr
|
||||
import pl.szczodrzynski.navlib.withIcon
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
@ -32,12 +43,16 @@ class MainActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
Iconics.respectFontBoundsDefault = true
|
||||
|
||||
if (darkTheme == null)
|
||||
darkTheme = getSharedPreferences("prefs", Context.MODE_PRIVATE).getBoolean("darkTheme", false)
|
||||
|
||||
Log.d("MainActivity", "Dark theme $darkTheme")
|
||||
setTheme(if (darkTheme == true) R.style.AppTheme else R.style.AppTheme_Light)
|
||||
|
||||
Log.d("NavLib", "ACTIVITY created")
|
||||
|
||||
setContentView(R.layout.sample_nav_view)
|
||||
|
||||
appFullscreen.isChecked = getSharedPreferences("prefs", Context.MODE_PRIVATE).getBoolean("appFullscreen", true)
|
||||
@ -65,18 +80,17 @@ 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()
|
||||
}
|
||||
|
||||
|
||||
//navView.init(this)
|
||||
|
||||
// init the drawer before SystemBarsUtil
|
||||
navView.addDrawer(activity = this)
|
||||
navView.drawer.init(this)
|
||||
|
||||
SystemBarsUtil(this).apply {
|
||||
paddingByKeyboard = navView
|
||||
@ -201,31 +215,172 @@ class MainActivity : AppCompatActivity() {
|
||||
navView.bottomSheet.enableDragToOpen = isChecked
|
||||
}
|
||||
|
||||
navView.bottomBar.fabIcon = CommunityMaterial.Icon2.cmd_pencil
|
||||
navView.bottomBar.fabIcon = CommunityMaterial.Icon3.cmd_pencil
|
||||
navView.bottomBar.fabExtendedText = "Compose"
|
||||
navView.bottomBar.fabExtended = false
|
||||
|
||||
rippleButton.setOnClickListener {
|
||||
navView.gainAttentionOnBottomBar()
|
||||
}
|
||||
|
||||
navView.toolbar.subtitleFormat = R.string.toolbar_subtitle
|
||||
navView.toolbar.subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread
|
||||
|
||||
navView.drawer.apply {
|
||||
|
||||
miniDrawerVisiblePortrait = true
|
||||
miniDrawerVisibleLandscape = null
|
||||
|
||||
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.Icon2.cmd_google_home),
|
||||
|
||||
DrawerPrimaryItem()
|
||||
.withIdentifier(2)
|
||||
.withName("Settings")
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline),
|
||||
|
||||
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")
|
||||
.withDescription("aaand not visible in Mini Drawer")
|
||||
.withIdentifier(62)
|
||||
.withIsHiddenInMiniDrawer(true)
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon2.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.Icon2.cmd_google_ads),
|
||||
|
||||
DrawerPrimaryItem().withName("Wonderful browsing experience and this is a long string")
|
||||
.withIdentifier(65)
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withIcon(CommunityMaterial.Icon3.cmd_microsoft_internet_explorer)
|
||||
)
|
||||
|
||||
//setAccountHeaderBackground("/sdcard/ban.gif")
|
||||
|
||||
appendProfiles(
|
||||
DrawerProfile(1, "Think Pad", "think with a pad", null),
|
||||
DrawerProfile(2, "Phil Swift", "I sawed this boat in half!!!", null),
|
||||
DrawerProfile(3, "The meme bay", "Visit my amazing website", null),
|
||||
DrawerProfile(4, "Mark Zuckerberg", null, null),
|
||||
DrawerProfile(5, "I love GDPR", null, null),
|
||||
DrawerProfile(6, "Gandalf", "http://sax.hol.es/", null)
|
||||
)
|
||||
|
||||
setUnreadCount(2, 20, 30) // phil swift has 30 unreads on "Settings item"
|
||||
setUnreadCount(4, 40, 1000) // mark has 99+ unreads on "Lock screen item"
|
||||
|
||||
addProfileSettings(
|
||||
ProfileSettingDrawerItem()
|
||||
.withName("Add Account")
|
||||
.withDescription("Add new GitHub Account")
|
||||
.withIcon(
|
||||
IconicsDrawable(context, CommunityMaterial.Icon3.cmd_plus).apply {
|
||||
actionBar()
|
||||
paddingDp = 5
|
||||
colorAttr(context, R.attr.materialDrawerPrimaryText)
|
||||
}
|
||||
)
|
||||
.withOnDrawerItemClickListener { v, item, position ->
|
||||
Toast.makeText(context, "Add account", Toast.LENGTH_SHORT).show()
|
||||
true
|
||||
},
|
||||
ProfileSettingDrawerItem()
|
||||
.withName("Manage Account")
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
)
|
||||
|
||||
drawerItemSelectedListener = { id, position, drawerItem ->
|
||||
navView.gainAttentionOnBottomBar()
|
||||
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.
|
||||
//
|
||||
// and it of course does not update the badge
|
||||
//
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
setSelection.setOnClickListener {
|
||||
navView.drawer.setSelection(id = 1, fireOnClick = false)
|
||||
}
|
||||
|
||||
|
||||
navView.bottomSheet.apply {
|
||||
this += PrimaryItem(true)
|
||||
this += BottomSheetPrimaryItem(true)
|
||||
.withId(1)
|
||||
.withTitle("Compose")
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_pencil)
|
||||
.withIcon(CommunityMaterial.Icon3.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)
|
||||
.withIcon(CommunityMaterial.Icon3.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 +388,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 +396,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.Icon3.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,31 @@
|
||||
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/rippleButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:text="Ripple bottombar" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/setSelection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:text="Set selection" />
|
||||
|
||||
<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 +86,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 +114,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 +149,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 +162,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 +221,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 +264,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 +308,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 +323,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>
|
||||
|
||||
|
||||
|
8
app/src/main/res/values-pl/plurals.xml
Normal file
8
app/src/main/res/values-pl/plurals.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<plurals name="toolbar_subtitle_with_unread">
|
||||
<item quantity="one">%1$s - %2$d nieprzeczytane</item>
|
||||
<item quantity="few">%1$s - %2$d nieprzeczytane</item>
|
||||
<item quantity="many">%1$s - %2$d nieprzeczytanych</item>
|
||||
</plurals>
|
||||
</resources>
|
6
app/src/main/res/values/plurals.xml
Normal file
6
app/src/main/res/values/plurals.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<plurals name="toolbar_subtitle_with_unread">
|
||||
<item quantity="other">%1$s - %2$d unread</item>
|
||||
</plurals>
|
||||
</resources>
|
@ -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>
|
||||
|
||||
|
37
build.gradle
37
build.gradle
@ -1,14 +1,28 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.41'
|
||||
ext.material_version = '1.1.0-alpha09'
|
||||
ext {
|
||||
kotlin_version = '1.4.31'
|
||||
|
||||
release = [
|
||||
// major.minor.patch.rc.beta
|
||||
versionName: "0.8.0",
|
||||
versionCode: 80099
|
||||
]
|
||||
|
||||
setup = [
|
||||
compileSdk: 30,
|
||||
minSdk : 16,
|
||||
targetSdk : 30
|
||||
]
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0-rc03'
|
||||
classpath "com.android.tools.build:gradle:4.2.0-beta06"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
@ -24,23 +38,6 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ext {
|
||||
compileSdkVersion = 28
|
||||
buildToolsVersion = '28.0.3'
|
||||
targetSdkVersion = compileSdkVersion
|
||||
minSdkVersion = 16
|
||||
|
||||
androidXAppCompat = '1.1.0-beta01'
|
||||
androidXRecyclerView = '1.1.0-alpha06'
|
||||
androidXCardView = '1.0.0'
|
||||
androidXGridLayout = '1.0.0'
|
||||
androidXConstraintLayout = '1.1.3'
|
||||
googleMaterial = '1.1.0-alpha09'
|
||||
|
||||
iconics = '4.0.1-b01'
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
|
||||
|
1
navlib-font/.gitignore
vendored
Normal file
1
navlib-font/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
44
navlib-font/build.gradle
Normal file
44
navlib-font/build.gradle
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2019 Mike Penz
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion setup.compileSdk
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion setup.minSdk
|
||||
targetSdkVersion setup.targetSdk
|
||||
consumerProguardFiles 'consumer-proguard-rules.pro'
|
||||
versionCode 10
|
||||
versionName "1.0"
|
||||
|
||||
resValue "string", "NavLibFont_version", "${versionName}"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "com.mikepenz:iconics-typeface-api:5.3.0-b01"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
}
|
1
navlib-font/consumer-proguard-rules.pro
Normal file
1
navlib-font/consumer-proguard-rules.pro
Normal file
@ -0,0 +1 @@
|
||||
-keep class com.mikepenz.iconics.typeface.library.navlibfont.NavLibFont { *; }
|
18
navlib-font/gradle.properties
Normal file
18
navlib-font/gradle.properties
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright 2019 Mike Penz
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
POM_NAME=Android-Iconics NavLibFont Typeface Library
|
||||
POM_ARTIFACT_ID=navlibfont-typeface
|
||||
POM_PACKAGING=aar
|
18
navlib-font/src/main/AndroidManifest.xml
Normal file
18
navlib-font/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2019 Mike Penz
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<manifest package="com.mikepenz.iconics.typeface.library.navlibfont" />
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2019 Mike Penz
|
||||
*
|
||||
* 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 com.mikepenz.iconics.typeface.library.navlibfont
|
||||
|
||||
import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.mikepenz.iconics.typeface.ITypeface
|
||||
import java.util.LinkedList
|
||||
|
||||
@Suppress("EnumEntryName")
|
||||
object NavLibFont : ITypeface {
|
||||
|
||||
override val fontRes: Int
|
||||
get() = R.font.navlibfont_font_v1_0
|
||||
|
||||
override val characters: Map<String, Char> by lazy {
|
||||
Icon.values().associate { it.name to it.character }
|
||||
}
|
||||
|
||||
override val mappingPrefix: String
|
||||
get() = "nav"
|
||||
|
||||
override val fontName: String
|
||||
get() = "NavLibFont"
|
||||
|
||||
override val version: String
|
||||
get() = "1.0"
|
||||
|
||||
override val iconCount: Int
|
||||
get() = characters.size
|
||||
|
||||
override val icons: List<String>
|
||||
get() = characters.keys.toCollection(LinkedList())
|
||||
|
||||
override val author: String
|
||||
get() = "Kuba Szczodrzyński"
|
||||
|
||||
override val url: String
|
||||
get() = "https://github.com/kuba2k2/NavLib"
|
||||
|
||||
override val description: String
|
||||
get() = ""
|
||||
|
||||
override val license: String
|
||||
get() = ""
|
||||
|
||||
override val licenseUrl: String
|
||||
get() = ""
|
||||
|
||||
override fun getIcon(key: String): IIcon = Icon.valueOf(key)
|
||||
|
||||
enum class Icon constructor(override val character: Char) : IIcon {
|
||||
nav_dots_vertical('\ue801'),
|
||||
nav_menu('\ue800'),
|
||||
nav_sort_ascending('\ue803'),
|
||||
nav_sort_descending('\ue802');
|
||||
|
||||
override val typeface: ITypeface by lazy { NavLibFont }
|
||||
}
|
||||
}
|
BIN
navlib-font/src/main/res/font/navlibfont_font_v1_0.ttf
Normal file
BIN
navlib-font/src/main/res/font/navlibfont_font_v1_0.ttf
Normal file
Binary file not shown.
20
navlib-font/src/main/res/values/font_addon.xml
Normal file
20
navlib-font/src/main/res/values/font_addon.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2019 Mike Penz
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="define_font_NavLibFont">com.mikepenz.iconics.typeface.library.navlibfont.NavLibFont</string>
|
||||
</resources>
|
31
navlib-font/src/main/res/values/font_description.xml
Normal file
31
navlib-font/src/main/res/values/font_description.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2019 Mike Penz
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="define_FontAwesome">year;author;libraryName;libraryWebsite</string>
|
||||
<string name="library_FontAwesome_author">Kuba Szczodrzyński</string>
|
||||
<string name="library_FontAwesome_authorWebsite">https://github.com/kuba2k2/NavLib</string>
|
||||
<string name="library_FontAwesome_libraryName">NavLibFont</string>
|
||||
<string name="library_FontAwesome_libraryDescription"></string>
|
||||
<string name="library_FontAwesome_libraryWebsite">https://github.com/kuba2k2/NavLib</string>
|
||||
<string name="library_FontAwesome_libraryVersion">@string/NavLibFont_version</string>
|
||||
<string name="library_FontAwesome_licenseId"></string>
|
||||
<string name="library_FontAwesome_isOpenSource">true</string>
|
||||
<string name="library_FontAwesome_repositoryLink">https://github.com/kuba2k2/NavLib</string>
|
||||
<!-- Custom variables section -->
|
||||
<string name="library_FontAwesome_year">2018</string>
|
||||
</resources>
|
@ -2,15 +2,15 @@ apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
|
||||
android {
|
||||
compileSdkVersion setup.compileSdk
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
versionCode 200
|
||||
versionName "0.2.0"
|
||||
minSdkVersion setup.minSdk
|
||||
targetSdkVersion setup.targetSdk
|
||||
versionCode release.versionCode
|
||||
versionName release.versionName
|
||||
|
||||
consumerProguardFiles 'consumer-rules.pro'
|
||||
|
||||
@ -24,8 +24,8 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
dataBinding {
|
||||
enabled = true
|
||||
buildFeatures {
|
||||
dataBinding = true
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
@ -35,20 +35,21 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.0.2'
|
||||
implementation 'androidx.core:core-ktx:1.0.2'
|
||||
implementation 'com.google.android.material:material:1.1.0-alpha09'
|
||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
|
||||
implementation "com.mikepenz:materialdrawer:7.0.0-rc05"
|
||||
implementation "com.mikepenz:iconics-core:4.0.1-b01"
|
||||
implementation 'com.mikepenz:community-material-typeface:3.5.95.1-kotlin@aar'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation "androidx.appcompat:appcompat:1.2.0"
|
||||
implementation "androidx.core:core-ktx:1.3.2"
|
||||
implementation "androidx.recyclerview:recyclerview:1.1.0"
|
||||
implementation "com.google.android.material:material:1.3.0"
|
||||
|
||||
implementation "androidx.appcompat:appcompat:${androidXAppCompat}"
|
||||
implementation "androidx.recyclerview:recyclerview:${androidXRecyclerView}"
|
||||
implementation "androidx.annotation:annotation:1.1.0"
|
||||
implementation "com.google.android.material:material:${googleMaterial}"
|
||||
implementation "androidx.constraintlayout:constraintlayout:${androidXConstraintLayout}"
|
||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||
api "com.mikepenz:materialize:1.2.1"
|
||||
api "com.mikepenz:materialdrawer:8.3.3"
|
||||
api "com.mikepenz:iconics-core:5.3.0-b01"
|
||||
api "com.mikepenz:itemanimators:1.1.0"
|
||||
|
||||
compileOnly "pl.droidsonroids.gif:android-gif-drawable:1.2.15"
|
||||
|
||||
implementation "com.balysv:material-ripple:1.0.2"
|
||||
|
||||
implementation project(":navlib-font")
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
-keep class androidx.drawerlayout.widget.DrawerLayout { *; }
|
2
navlib/proguard-rules.pro
vendored
2
navlib/proguard-rules.pro
vendored
@ -19,3 +19,5 @@
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
-keep class androidx.drawerlayout.widget.DrawerLayout { *; }
|
||||
|
109
navlib/src/main/java/pl/szczodrzynski/navlib/BadgeDrawable.java
Normal file
109
navlib/src/main/java/pl/szczodrzynski/navlib/BadgeDrawable.java
Normal file
@ -0,0 +1,109 @@
|
||||
package pl.szczodrzynski.navlib;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
public class BadgeDrawable extends Drawable {
|
||||
|
||||
private Paint mBadgePaint;
|
||||
private Paint mBadgePaint1;
|
||||
private Paint mTextPaint;
|
||||
private Rect mTxtRect = new Rect();
|
||||
|
||||
private String mCount = "";
|
||||
private boolean mWillDraw = false;
|
||||
|
||||
public BadgeDrawable(Context context) {
|
||||
float mTextSize = context.getResources().getDimension(R.dimen.badge_text_size);
|
||||
|
||||
mBadgePaint = new Paint();
|
||||
mBadgePaint.setColor(0xffff3d00);
|
||||
mBadgePaint.setAntiAlias(true);
|
||||
mBadgePaint.setStyle(Paint.Style.FILL);
|
||||
/*mBadgePaint1 = new Paint();
|
||||
mBadgePaint1.setColor(ContextCompat.getColor(context.getApplicationContext(), R.color.grey_ivory5));
|
||||
mBadgePaint1.setAntiAlias(true);
|
||||
mBadgePaint1.setStyle(Paint.Style.FILL);*/
|
||||
|
||||
mTextPaint = new Paint();
|
||||
mTextPaint.setColor(Color.WHITE);
|
||||
mTextPaint.setTypeface(Typeface.DEFAULT);
|
||||
mTextPaint.setTextSize(mTextSize);
|
||||
mTextPaint.setAntiAlias(true);
|
||||
mTextPaint.setTextAlign(Paint.Align.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
|
||||
|
||||
|
||||
if (!mWillDraw) {
|
||||
return;
|
||||
}
|
||||
Rect bounds = getBounds();
|
||||
float width = bounds.right - bounds.left;
|
||||
float height = bounds.bottom - bounds.top;
|
||||
|
||||
// Position the badge in the top-right quadrant of the icon.
|
||||
|
||||
/*Using Math.max rather than Math.min */
|
||||
|
||||
float radius = ((Math.max(width, height) / 2)) / 2;
|
||||
float centerX = (width - radius - 1) +5;
|
||||
float centerY = radius -5;
|
||||
if(mCount.length() <= 2){
|
||||
// Draw badge circle.
|
||||
//canvas.drawCircle(centerX, centerY, (int)(radius+7.5), mBadgePaint1);
|
||||
canvas.drawCircle(centerX, centerY, (int)(radius+5.5), mBadgePaint);
|
||||
}
|
||||
else{
|
||||
//canvas.drawCircle(centerX, centerY, (int)(radius+8.5), mBadgePaint1);
|
||||
canvas.drawCircle(centerX, centerY, (int)(radius+6.5), mBadgePaint);
|
||||
// canvas.drawRoundRect(radius, radius, radius, radius, 10, 10, mBadgePaint);
|
||||
}
|
||||
// Draw badge count text inside the circle.
|
||||
mTextPaint.getTextBounds(mCount, 0, mCount.length(), mTxtRect);
|
||||
float textHeight = mTxtRect.bottom - mTxtRect.top;
|
||||
float textY = centerY + (textHeight / 2f);
|
||||
if(mCount.length() > 2)
|
||||
canvas.drawText("99+", centerX, textY, mTextPaint);
|
||||
else
|
||||
canvas.drawText(mCount, centerX, textY, mTextPaint);
|
||||
}
|
||||
|
||||
/*
|
||||
Sets the count (i.e notifications) to display.
|
||||
*/
|
||||
public void setCount(String count) {
|
||||
mCount = count;
|
||||
|
||||
// Only draw a badge if there are notifications.
|
||||
mWillDraw = !count.equalsIgnoreCase("0");
|
||||
invalidateSelf();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.UNKNOWN;
|
||||
}
|
||||
}
|
@ -0,0 +1,278 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
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))
|
121
navlib/src/main/java/pl/szczodrzynski/navlib/ImageHolder.kt
Normal file
121
navlib/src/main/java/pl/szczodrzynski/navlib/ImageHolder.kt
Normal file
@ -0,0 +1,121 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.mikepenz.iconics.utils.actionBar
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
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(@DrawableRes iconRes: Int, colorFilter: Int?) : super(iconRes) {
|
||||
this.colorFilter = colorFilter
|
||||
}
|
||||
constructor(iicon: IIcon) : super(null as Drawable?) {
|
||||
this.iicon = iicon
|
||||
}
|
||||
constructor() : super()
|
||||
constructor(url: String) : super(url)
|
||||
constructor(uri: Uri) : super(uri)
|
||||
constructor(icon: Drawable?) : super(icon)
|
||||
constructor(bitmap: Bitmap) : super(bitmap)
|
||||
constructor(iconRes: Int) : super(iconRes)
|
||||
|
||||
var iicon: IIcon? = null
|
||||
@ColorInt
|
||||
var colorFilter: Int? = null
|
||||
var colorFilterMode: PorterDuff.Mode = PorterDuff.Mode.DST_OVER
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
|
||||
if (colorFilter != null) {
|
||||
imageView.colorFilter = PorterDuffColorFilter(colorFilter!!, colorFilterMode)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* this only handles Drawables
|
||||
*
|
||||
* @param ctx
|
||||
* @param iconColor
|
||||
* @param tint
|
||||
* @return
|
||||
*/
|
||||
override fun decideIcon(ctx: Context, iconColor: ColorStateList, tint: Boolean, paddingDp: Int): Drawable? {
|
||||
var icon: Drawable? = icon
|
||||
val ii = iicon
|
||||
val uri = uri
|
||||
|
||||
when {
|
||||
ii != null -> icon = IconicsDrawable(ctx).apply {
|
||||
this.icon = ii
|
||||
colorList = iconColor
|
||||
sizeDp = 24
|
||||
}
|
||||
iconRes != -1 -> icon = AppCompatResources.getDrawable(ctx, iconRes)
|
||||
uri != null -> try {
|
||||
val inputStream = ctx.contentResolver.openInputStream(uri)
|
||||
icon = Drawable.createFromStream(inputStream, uri.toString())
|
||||
} catch (e: FileNotFoundException) {
|
||||
//no need to handle this
|
||||
}
|
||||
}
|
||||
//if we got an icon AND we have auto tinting enabled AND it is no IIcon, tint it ;)
|
||||
if (icon != null && tint && iicon == null) {
|
||||
icon = icon.mutate()
|
||||
icon.setColorFilter(iconColor.defaultColor, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
return icon
|
||||
}
|
||||
}
|
@ -1,22 +1,23 @@
|
||||
package pl.szczodrzynski.navlib
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.system.Os.close
|
||||
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 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.community.material.CommunityMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.typeface.library.navlibfont.NavLibFont
|
||||
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 +32,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
|
||||
@ -88,11 +89,19 @@ class NavBottomBar : BottomAppBar {
|
||||
/**
|
||||
* Set the FAB's icon.
|
||||
*/
|
||||
var fabIcon: IIcon = CommunityMaterial.Icon.cmd_android
|
||||
var fabIcon: IIcon? = null
|
||||
set(value) {
|
||||
field = value
|
||||
fabView?.setImageDrawable(IconicsDrawable(context, value).colorInt(R.attr.colorFabIcon).sizeDp(24))
|
||||
fabExtendedView?.icon = IconicsDrawable(context, value).colorInt(R.attr.colorFabIcon).sizeDp(24)
|
||||
fabView?.setImageDrawable(IconicsDrawable(context).apply {
|
||||
icon = value
|
||||
colorAttr(context, R.attr.colorFabIcon)
|
||||
sizeDp = 24
|
||||
})
|
||||
fabExtendedView?.icon = IconicsDrawable(context).apply {
|
||||
icon = value
|
||||
colorAttr(context, R.attr.colorFabIcon)
|
||||
sizeDp = 24
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set the ExtendedFAB's text.
|
||||
@ -103,6 +112,15 @@ class NavBottomBar : BottomAppBar {
|
||||
fabExtendedView?.text = value
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the FAB's on click listener
|
||||
*/
|
||||
fun setFabOnClickListener(onClickListener: OnClickListener?) {
|
||||
fabView?.setOnClickListener(onClickListener)
|
||||
fabExtendedView?.setOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun create(attrs: AttributeSet?, defStyle: Int) {
|
||||
setOnTouchListener { _, event ->
|
||||
if (bottomSheet?.enable != true || bottomSheet?.enableDragToOpen != true)
|
||||
@ -113,24 +131,28 @@ class NavBottomBar : BottomAppBar {
|
||||
|
||||
elevation = 0f
|
||||
|
||||
navigationIcon = IconicsDrawable(context)
|
||||
.icon(CommunityMaterial.Icon2.cmd_menu)
|
||||
.sizeDp(20)
|
||||
.colorInt(getColorFromAttr(context, R.attr.colorOnPrimary))
|
||||
val icon = ContextCompat.getDrawable(context, R.drawable.ic_menu_badge) as LayerDrawable?
|
||||
icon?.apply {
|
||||
mutate()
|
||||
setDrawableByLayerId(R.id.ic_menu, IconicsDrawable(context).apply {
|
||||
this.icon = NavLibFont.Icon.nav_menu
|
||||
sizeDp = 24
|
||||
colorAttr(context, R.attr.colorOnPrimary)
|
||||
})
|
||||
setDrawableByLayerId(R.id.ic_badge, BadgeDrawable(context))
|
||||
}
|
||||
navigationIcon = icon
|
||||
|
||||
menu.add(0, -1, 0, "Menu")
|
||||
.setIcon(
|
||||
IconicsDrawable(context)
|
||||
.icon(CommunityMaterial.Icon.cmd_dots_vertical)
|
||||
.sizeDp(20)
|
||||
.colorInt(getColorFromAttr(context, R.attr.colorOnPrimary)))
|
||||
.setIcon(IconicsDrawable(context).apply {
|
||||
this.icon = NavLibFont.Icon.nav_dots_vertical
|
||||
sizeDp = 24
|
||||
colorAttr(context, R.attr.colorOnPrimary)
|
||||
})
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
|
||||
setNavigationOnClickListener {
|
||||
if (drawer?.isDrawerOpen == true)
|
||||
drawer?.closeDrawer()
|
||||
else
|
||||
drawer?.openDrawer()
|
||||
drawer?.toggle()
|
||||
}
|
||||
|
||||
super.setOnMenuItemClickListener {
|
||||
@ -186,4 +208,4 @@ class NavBottomBar : BottomAppBar {
|
||||
override fun setOnMenuItemClickListener(listener: OnMenuItemClickListener?) {
|
||||
onMenuItemClickListener = listener
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ package pl.szczodrzynski.navlib
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.ImageView
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
|
||||
class NavToolbar : MaterialToolbar {
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
create(null, 0)
|
||||
}
|
||||
@ -17,7 +19,37 @@ class NavToolbar : MaterialToolbar {
|
||||
create(attrs, defStyle)
|
||||
}
|
||||
|
||||
var toolbarImage: ImageView? = null
|
||||
set(value) {
|
||||
field = value
|
||||
toolbarImage?.setOnClickListener {
|
||||
profileImageClickListener?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
override fun setSubtitle(subtitle: CharSequence?) {
|
||||
if(subtitle.isNullOrEmpty()) {
|
||||
setPadding(0, 0, 0, 0)
|
||||
toolbarImage?.translationY = 0f
|
||||
} else {
|
||||
setPadding(0, -1, 0, 5)
|
||||
toolbarImage?.translationY = 6f
|
||||
}
|
||||
super.setSubtitle(subtitle)
|
||||
}
|
||||
|
||||
private fun create(attrs: AttributeSet?, defStyle: Int) {
|
||||
|
||||
}
|
||||
|
||||
var subtitleFormat: Int? = null
|
||||
var subtitleFormatWithUnread: Int? = null
|
||||
|
||||
var profileImageClickListener: (() -> Unit)? = null
|
||||
|
||||
var profileImage
|
||||
get() = toolbarImage?.drawable
|
||||
set(value) {
|
||||
toolbarImage?.setImageDrawable(value)
|
||||
}
|
||||
}
|
@ -1,44 +1,50 @@
|
||||
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.graphics.Point
|
||||
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 androidx.core.view.children
|
||||
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.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
|
||||
val coordinator by lazy {
|
||||
findViewById<CoordinatorLayout>(R.id.nv_coordinator)
|
||||
}
|
||||
|
||||
|
||||
var navigationLoader: NavigationLoader? = null
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
create(null, 0)
|
||||
@ -71,34 +77,57 @@ 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_drawerLayout),
|
||||
findViewById(R.id.nv_drawerContainerLandscape),
|
||||
findViewById(R.id.nv_miniDrawerContainerPortrait),
|
||||
findViewById(R.id.nv_miniDrawerElevation)
|
||||
)
|
||||
toolbar = findViewById(R.id.nv_toolbar)
|
||||
bottomBar = findViewById(R.id.nv_bottomBar)
|
||||
bottomSheet = findViewById(R.id.nv_bottomSheet)
|
||||
|
||||
drawer.toolbar = toolbar
|
||||
drawer.bottomBar = bottomBar
|
||||
|
||||
toolbar.toolbarImage = findViewById(R.id.nv_toolbar_image)
|
||||
|
||||
bottomBar.drawer = drawer
|
||||
bottomBar.bottomSheet = bottomSheet
|
||||
bottomBar.fabView = floatingActionButton
|
||||
bottomBar.fabExtendedView = extendedFloatingActionButton
|
||||
|
||||
//bottomSheetBehavior.peekHeight = displayHeight
|
||||
ripple.isEnabled = false
|
||||
ripple.children.forEach { it.isEnabled = false }
|
||||
|
||||
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?) {}
|
||||
})
|
||||
//bottomSheetBehavior.peekHeight = displayHeight
|
||||
}
|
||||
|
||||
private fun convertDpToPixel(dp: Float): Float {
|
||||
val resources = context.resources
|
||||
val metrics = resources.displayMetrics
|
||||
return dp * (metrics.densityDpi / 160f)
|
||||
}
|
||||
|
||||
fun gainAttentionOnBottomBar() {
|
||||
var x = ripple.width.toFloat()
|
||||
var y = ripple.height.toFloat()
|
||||
x -= convertDpToPixel(56f) / 2
|
||||
y -= convertDpToPixel(56f) / 2
|
||||
ripple.performRipple(Point(x.toInt(), y.toInt()))
|
||||
}
|
||||
|
||||
fun configSystemBarsUtil(systemBarsUtil: SystemBarsUtil) {
|
||||
systemBarsUtil.statusBarBgView = statusBarBackground
|
||||
systemBarsUtil.navigationBarBgView = navigationBarBackground
|
||||
systemBarsUtil.statusBarDarkView = nv_statusBarDarker
|
||||
//systemBarsUtil.navigationBarDarkView = navigationBarBackground
|
||||
systemBarsUtil.paddingBySystemBars = mainView
|
||||
systemBarsUtil.paddingByNavigationBar = bottomSheet.getContentView()
|
||||
this.systemBarsUtil = systemBarsUtil.apply {
|
||||
this.statusBarBgView = statusBarBackground
|
||||
this.navigationBarBgView = navigationBarBackground
|
||||
this.statusBarDarkView = nv_statusBarDarker
|
||||
//this.navigationBarDarkView = navigationBarBackground
|
||||
this.insetsListener = nv_drawerLayout
|
||||
this.marginBySystemBars = mainView
|
||||
this.paddingByNavigationBar = bottomSheet.getContentView()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -118,7 +147,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()
|
||||
}
|
||||
@ -126,18 +155,11 @@ class NavView : FrameLayout {
|
||||
/**
|
||||
* Set the FAB's on click listener
|
||||
*/
|
||||
fun setFabOnClickListener(onClickListener: OnClickListener) {
|
||||
floatingActionButton.setOnClickListener(onClickListener)
|
||||
extendedFloatingActionButton.setOnClickListener(onClickListener)
|
||||
fun setFabOnClickListener(onClickListener: OnClickListener?) {
|
||||
bottomBar.setFabOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
fun init(activity: Activity) {
|
||||
|
||||
}
|
||||
internal var systemBarsUtil: SystemBarsUtil? = null
|
||||
|
||||
private fun setContentMargins() {
|
||||
val layoutParams = CoordinatorLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||
@ -147,33 +169,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 && !drawer.fixedDrawerEnabled()) {
|
||||
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?>)
|
||||
}
|
@ -5,7 +5,7 @@ import android.content.res.Configuration.ORIENTATION_PORTRAIT
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.os.Build.VERSION_CODES.*
|
||||
import android.os.Build.VERSION_CODES
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.View.*
|
||||
@ -36,8 +36,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 +57,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 +124,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 +142,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)
|
||||
@ -180,12 +184,12 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
// #3 SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the activity not resize when keyboard is open
|
||||
// Samsung TouchWiz - app will go fullscreen. There is a problem though, see #3.
|
||||
var targetAppFullscreen = false
|
||||
if (SDK_INT >= KITKAT) {
|
||||
if (SDK_INT >= VERSION_CODES.KITKAT) {
|
||||
targetAppFullscreen = true
|
||||
}
|
||||
|
||||
|
||||
if (SDK_INT in KITKAT until LOLLIPOP) {
|
||||
if (SDK_INT in VERSION_CODES.KITKAT until VERSION_CODES.LOLLIPOP) {
|
||||
// API 19-20 (KitKat 4.4) - set gradient status bar
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
||||
// take FallbackGradient color
|
||||
@ -193,7 +197,7 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
// disable darker even if [statusBarDarker] == true BUT gradient fallback is not COLOR_HALF_TRANSPARENT
|
||||
//targetStatusBarDarker = targetStatusBarDarker && targetStatusBarFallbackGradient == COLOR_HALF_TRANSPARENT
|
||||
}
|
||||
else if (SDK_INT >= LOLLIPOP) {
|
||||
else if (SDK_INT >= VERSION_CODES.LOLLIPOP) {
|
||||
// API 21+ (Lollipop 5.0+) - set transparent status bar
|
||||
if (statusBarTranslucent) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
||||
@ -201,17 +205,17 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
else {
|
||||
window.statusBarColor = Color.TRANSPARENT
|
||||
}
|
||||
if (SDK_INT < M && targetStatusBarLight) {
|
||||
if (SDK_INT < VERSION_CODES.M && targetStatusBarLight) {
|
||||
// take FallbackLight color
|
||||
targetStatusBarMode = TARGET_MODE_LIGHT
|
||||
}
|
||||
}
|
||||
if (SDK_INT >= M && targetStatusBarLight) {
|
||||
if (SDK_INT >= VERSION_CODES.M && targetStatusBarLight) {
|
||||
// API 23+ (Marshmallow 6.0+) - set the status bar icons to dark color if [statusBarLight] is true
|
||||
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||
}
|
||||
// FOR SAMSUNG/SONY DEVICES (TouchWiz 4.1-4.3)
|
||||
if (SDK_INT < KITKAT) {
|
||||
if (SDK_INT < VERSION_CODES.KITKAT) {
|
||||
val libs = activity.packageManager.systemSharedLibraryNames
|
||||
var reflect: String? = null
|
||||
// TODO galaxy s3 - opening keyboard does not resize activity if fullscreen
|
||||
@ -277,23 +281,25 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
|
||||
// TODO navigation bar options like status bar
|
||||
// NAVIGATION BAR
|
||||
if (SDK_INT >= KITKAT && (SDK_INT < LOLLIPOP || !navigationBarTransparent)) {
|
||||
if (SDK_INT >= VERSION_CODES.KITKAT && (SDK_INT < VERSION_CODES.LOLLIPOP || !navigationBarTransparent)) {
|
||||
// API 19-20 (KitKat 4.4) - set gradient navigation bar
|
||||
// API 21+ (Lollipop 5.0+) - set half-transparent navigation bar if [navigationBarTransparent] is false
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
|
||||
}
|
||||
|
||||
if (SDK_INT >= LOLLIPOP && navigationBarTransparent) {
|
||||
if (SDK_INT >= VERSION_CODES.LOLLIPOP && navigationBarTransparent) {
|
||||
// API 21+ (Lollipop 5.0+) - set fully transparent navigation bar if [navigationBarTransparent] is true
|
||||
window.navigationBarColor = Color.TRANSPARENT
|
||||
}
|
||||
|
||||
// PADDING
|
||||
if (paddingBySystemBars != null) {
|
||||
if (SDK_INT >= LOLLIPOP) {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(paddingBySystemBars!!) { _, insets ->
|
||||
if (insetsListener != null) {
|
||||
if (SDK_INT >= VERSION_CODES.LOLLIPOP && false) {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(insetsListener!!) { _, insets ->
|
||||
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 +319,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 +352,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
|
||||
@ -367,4 +373,4 @@ class SystemBarsUtil(private val activity: Activity) {
|
||||
keyboardUtil?.disable()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,16 +3,20 @@ package pl.szczodrzynski.navlib
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
import android.util.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 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 {
|
||||
@ -51,12 +55,6 @@ fun getBottomInset(context: Context, view: View): Float {
|
||||
} * context.resources.displayMetrics.density
|
||||
}
|
||||
|
||||
fun getColorFromAttr(context: Context, @AttrRes color: Int): Int {
|
||||
val typedValue = TypedValue()
|
||||
context.theme.resolveAttribute(color, typedValue, true)
|
||||
return typedValue.data
|
||||
}
|
||||
|
||||
fun View.getActivity(): Activity {
|
||||
return findViewById<View>(android.R.id.content).context as Activity
|
||||
}
|
||||
@ -90,9 +88,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().
|
||||
@ -104,7 +120,15 @@ fun hasNavigationBar(resources: Resources): Boolean {
|
||||
return hasNavigationBar
|
||||
}
|
||||
|
||||
fun IconicsDrawable.colorAttr(context: Context, @AttrRes attrRes: Int) = color(IconicsColor.colorInt(getColorFromAttr(context, attrRes)))
|
||||
fun IconicsDrawable.colorAttr(context: Context, @AttrRes attrRes: Int) {
|
||||
colorInt = getColorFromAttr(context, attrRes)
|
||||
}
|
||||
|
||||
fun getColorFromAttr(context: Context, @AttrRes color: Int): Int {
|
||||
val typedValue = TypedValue()
|
||||
context.theme.resolveAttribute(color, typedValue, true)
|
||||
return typedValue.data
|
||||
}
|
||||
|
||||
fun Context.getDrawableFromRes(@DrawableRes id: Int): Drawable {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
@ -113,4 +137,28 @@ fun Context.getDrawableFromRes(@DrawableRes id: Int): Drawable {
|
||||
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 crc16(buffer: String): Int {
|
||||
/* Note the change here */
|
||||
var crc = 0x1D0F
|
||||
for (j in buffer) {
|
||||
crc = crc.ushr(8) or (crc shl 8) and 0xffff
|
||||
crc = crc xor (j.toInt() and 0xff)//byte to int, trunc sign
|
||||
crc = crc xor (crc and 0xff shr 4)
|
||||
crc = crc xor (crc shl 12 and 0xffff)
|
||||
crc = crc xor (crc and 0xFF shl 5 and 0xffff)
|
||||
}
|
||||
crc = crc and 0xffff
|
||||
return crc
|
||||
}
|
||||
|
@ -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,8 @@ 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
|
||||
@ -21,17 +23,16 @@ 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.typeface.library.navlibfont.NavLibFont
|
||||
import com.mikepenz.iconics.utils.paddingDp
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import pl.szczodrzynski.navlib.Anim
|
||||
import pl.szczodrzynski.navlib.R
|
||||
import pl.szczodrzynski.navlib.*
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.IBottomSheetItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.SeparatorItem
|
||||
import pl.szczodrzynski.navlib.elevateSurface
|
||||
import pl.szczodrzynski.navlib.getDrawableFromRes
|
||||
|
||||
|
||||
class NavBottomSheet : CoordinatorLayout {
|
||||
@ -60,6 +61,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 +71,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 +119,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)
|
||||
@ -145,6 +150,7 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
// steal the focus from any EditTexts
|
||||
dragBar.requestFocus()
|
||||
hideKeyboard()
|
||||
onCloseListener?.invoke()
|
||||
}
|
||||
else if (!bottomSheetVisible) {
|
||||
bottomSheetVisible = true
|
||||
@ -169,51 +175,97 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
}
|
||||
|
||||
toggleGroup.addOnButtonCheckedListener(toggleGroupCheckedListener)
|
||||
textInputEditText.addTextChangedListener(textInputWatcher)
|
||||
}
|
||||
|
||||
/* _____ _ _ _
|
||||
|_ _| | ___ | | | |
|
||||
| | | |_ ___ _ __ ___ ___ ( _ ) __| | __ _| |_ __ _
|
||||
| | | __/ _ \ '_ ` _ \/ __| / _ \/\ / _` |/ _` | __/ _` |
|
||||
_| |_| || __/ | | | | \__ \ | (_> < | (_| | (_| | || (_| |
|
||||
|_____|\__\___|_| |_| |_|___/ \___/\/ \__,_|\__,_|\__\__,*/
|
||||
var onCloseListener: (() -> Unit)? = null
|
||||
|
||||
/* _____ _
|
||||
|_ _| |
|
||||
| | | |_ ___ _ __ ___ ___
|
||||
| | | __/ _ \ '_ ` _ \/ __|
|
||||
_| |_| || __/ | | | | \__ \
|
||||
|_____|\__\___|_| |_| |_|__*/
|
||||
operator fun plusAssign(item: IBottomSheetItem<*>) {
|
||||
appendItem(item)
|
||||
}
|
||||
fun appendItem(item: IBottomSheetItem<*>) {
|
||||
items += item
|
||||
adapter.notifyItemInserted(items.size - 1)
|
||||
items.add(item)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemInserted(items.size - 1)
|
||||
}
|
||||
fun appendItems(vararg items: IBottomSheetItem<*>) {
|
||||
this.items.addAll(items)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemRangeInserted(this.items.size - items.size, items.size)
|
||||
}
|
||||
fun prependItem(item: IBottomSheetItem<*>) {
|
||||
items.add(0, item)
|
||||
adapter.notifyItemInserted(0)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemInserted(0)
|
||||
}
|
||||
fun prependItems(vararg items: IBottomSheetItem<*>) {
|
||||
this.items.addAll(0, items.toList())
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemRangeInserted(0, items.size)
|
||||
}
|
||||
fun addItemAt(index: Int, item: IBottomSheetItem<*>) {
|
||||
items.add(index, item)
|
||||
adapter.notifyItemInserted(index)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemInserted(index)
|
||||
}
|
||||
fun removeItemById(id: Int) {
|
||||
items.filterNot { it.id == id }
|
||||
}
|
||||
fun removeItemAt(index: Int) {
|
||||
items.removeAt(index)
|
||||
adapter.notifyItemRemoved(index)
|
||||
adapter.notifyDataSetChanged()
|
||||
//adapter.notifyItemRemoved(index)
|
||||
}
|
||||
fun removeAllItems() {
|
||||
items.clear()
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
fun removeAllStatic() {
|
||||
items.filter { it.isContextual }
|
||||
items.removeAll { !it.isContextual }
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
fun removeAllContextual() {
|
||||
items.filter { !it.isContextual }
|
||||
items.removeAll { it.isContextual }
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
fun removeSeparators() {
|
||||
items.filterNot { it is SeparatorItem }
|
||||
items.removeAll { 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 }
|
||||
@ -226,7 +278,9 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
private fun toggleGroupGetIconicsDrawable(context: Context, icon: IIcon?): Drawable? {
|
||||
if (icon == null)
|
||||
return null
|
||||
return IconicsDrawable(context, icon).sizeDp(24).paddingDp(4)
|
||||
return IconicsDrawable(context, icon).apply {
|
||||
sizeDp = 24
|
||||
}
|
||||
}
|
||||
|
||||
fun toggleGroupAddItem(id: Int, text: String, @DrawableRes icon: Int, defaultSortOrder: Int = SORT_MODE_ASCENDING) {
|
||||
@ -263,7 +317,7 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
* bit 2 = current sorting mode
|
||||
*/
|
||||
if (toggleGroupSelectionMode == TOGGLE_GROUP_SORTING_ORDER) {
|
||||
val button = group.findViewById<MaterialButton>(checkedId)
|
||||
val button = group.findViewById<MaterialButton>(checkedId) ?: return@OnButtonCheckedListener
|
||||
var tag = button.tag as Int
|
||||
var sortingMode: Int? = null
|
||||
if (isChecked) {
|
||||
@ -283,38 +337,77 @@ class NavBottomSheet : CoordinatorLayout {
|
||||
}
|
||||
button.tag = tag
|
||||
button.icon = toggleGroupGetIconicsDrawable(context, when (sortingMode) {
|
||||
SORT_MODE_ASCENDING -> CommunityMaterial.Icon2.cmd_sort_ascending
|
||||
SORT_MODE_DESCENDING -> CommunityMaterial.Icon2.cmd_sort_descending
|
||||
SORT_MODE_ASCENDING -> NavLibFont.Icon.nav_sort_ascending
|
||||
SORT_MODE_DESCENDING -> NavLibFont.Icon.nav_sort_descending
|
||||
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).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)
|
||||
}
|
||||
}
|
||||
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,10 +429,10 @@ 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
|
||||
isOpen = !isOpen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,20 +2,20 @@ package pl.szczodrzynski.navlib.bottomsheet.items
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.IIcon
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import com.mikepenz.materialize.holder.ImageHolder
|
||||
import pl.szczodrzynski.navlib.ImageHolder
|
||||
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> {
|
||||
|
||||
/*_ _
|
||||
| | | |
|
||||
@ -33,22 +33,32 @@ data class PrimaryItem(override val isContextual: Boolean = true) : IBottomSheet
|
||||
|
||||
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val root = itemView.findViewById<View>(R.id.item_root)
|
||||
val image = itemView.findViewById<ImageView>(R.id.item_icon)
|
||||
val text = itemView.findViewById<TextView>(R.id.item_text)
|
||||
val description = itemView.findViewById<TextView>(R.id.item_description)
|
||||
}
|
||||
|
||||
override fun bindViewHolder(viewHolder: ViewHolder) {
|
||||
viewHolder.root.setOnClickListener(onClickListener)
|
||||
viewHolder.text.text = title
|
||||
viewHolder.text.setTextColor(getColorFromAttr(viewHolder.text.context, R.attr.material_drawer_primary_text))
|
||||
viewHolder.text.setCompoundDrawables(
|
||||
IconicsDrawable(viewHolder.text.context)
|
||||
.icon(iconicsIcon?:CommunityMaterial.Icon.cmd_android)
|
||||
.colorAttr(viewHolder.text.context, R.attr.material_drawer_primary_icon)
|
||||
.sizeDp(20),
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
|
||||
viewHolder.image.setImageDrawable(IconicsDrawable(viewHolder.text.context).apply {
|
||||
icon = iconicsIcon
|
||||
colorAttr(viewHolder.text.context, android.R.attr.textColorSecondary)
|
||||
sizeDp = 24
|
||||
})
|
||||
|
||||
viewHolder.description.visibility = View.VISIBLE
|
||||
when {
|
||||
descriptionRes != null -> viewHolder.description.setText(descriptionRes!!)
|
||||
description != null -> viewHolder.description.text = description
|
||||
else -> viewHolder.description.visibility = View.GONE
|
||||
}
|
||||
|
||||
when {
|
||||
titleRes != null -> viewHolder.text.setText(titleRes!!)
|
||||
else -> viewHolder.text.text = title
|
||||
}
|
||||
viewHolder.text.setTextColor(getColorFromAttr(viewHolder.text.context, android.R.attr.textColorPrimary))
|
||||
}
|
||||
|
||||
/*_____ _
|
||||
@ -67,48 +77,48 @@ 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,17 @@
|
||||
package pl.szczodrzynski.navlib.drawer
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.widget.ImageView
|
||||
import pl.szczodrzynski.navlib.ImageHolder
|
||||
|
||||
interface IDrawerProfile {
|
||||
val id: Int
|
||||
var name: String
|
||||
var subname: String?
|
||||
var image: String?
|
||||
|
||||
fun getImageDrawable(context: Context): Drawable?
|
||||
fun getImageHolder(context: Context): ImageHolder?
|
||||
fun applyImageTo(imageView: ImageView)
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package pl.szczodrzynski.navlib.drawer
|
||||
|
||||
interface IUnreadCounter {
|
||||
var profileId: Int
|
||||
var type: Int
|
||||
var drawerItemId: Int?
|
||||
var count: Int
|
||||
}
|
730
navlib/src/main/java/pl/szczodrzynski/navlib/drawer/NavDrawer.kt
Normal file
730
navlib/src/main/java/pl/szczodrzynski/navlib/drawer/NavDrawer.kt
Normal file
@ -0,0 +1,730 @@
|
||||
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.PorterDuff
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.util.Log
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.customview.widget.ViewDragHelper
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import com.mikepenz.fastadapter.IAdapter
|
||||
import com.mikepenz.itemanimators.AlphaCrossFadeAnimator
|
||||
import com.mikepenz.materialdrawer.*
|
||||
import com.mikepenz.materialdrawer.holder.BadgeStyle
|
||||
import com.mikepenz.materialdrawer.holder.ColorHolder
|
||||
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||
import com.mikepenz.materialdrawer.model.BaseDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.MiniProfileDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.*
|
||||
import com.mikepenz.materialdrawer.util.*
|
||||
import com.mikepenz.materialdrawer.widget.AccountHeaderView
|
||||
import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
|
||||
import com.mikepenz.materialdrawer.widget.MiniDrawerSliderView
|
||||
import com.mikepenz.materialize.util.UIUtils
|
||||
import pl.szczodrzynski.navlib.*
|
||||
import pl.szczodrzynski.navlib.R
|
||||
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
||||
|
||||
class NavDrawer(
|
||||
val context: Context,
|
||||
val drawerLayout: DrawerLayout,
|
||||
val drawerContainerLandscape: FrameLayout,
|
||||
val drawerContainerPortrait: FrameLayout,
|
||||
val miniDrawerElevation: View
|
||||
) {
|
||||
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 lateinit var drawer: MaterialDrawerSliderView
|
||||
private lateinit var accountHeader: AccountHeaderView
|
||||
private lateinit var miniDrawer: MiniDrawerSliderView
|
||||
|
||||
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().apply {
|
||||
textColor = ColorHolder.fromColor(Color.WHITE)
|
||||
color = ColorHolder.fromColor(0xffd32f2f.toInt())
|
||||
}
|
||||
|
||||
drawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
|
||||
override fun onDrawerStateChanged(newState: Int) {}
|
||||
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
|
||||
override fun onDrawerClosed(drawerView: View) {
|
||||
drawerClosedListener?.invoke()
|
||||
profileSelectionClose()
|
||||
}
|
||||
override fun onDrawerOpened(drawerView: View) {
|
||||
drawerOpenedListener?.invoke()
|
||||
}
|
||||
})
|
||||
|
||||
accountHeader = AccountHeaderView(context).apply {
|
||||
headerBackground = ImageHolder(R.drawable.header)
|
||||
displayBadgesOnSmallProfileImages = true
|
||||
|
||||
onAccountHeaderListener = { view, profile, current ->
|
||||
if (profile is ProfileSettingDrawerItem) {
|
||||
drawerProfileSettingClickListener?.invoke(profile.identifier.toInt(), view) ?: false
|
||||
}
|
||||
else {
|
||||
updateBadges()
|
||||
if (current) {
|
||||
close()
|
||||
profileSelectionClose()
|
||||
true
|
||||
}
|
||||
else {
|
||||
(drawerProfileSelectedListener?.invoke(profile.identifier.toInt(), profile, current, view) ?: false).also {
|
||||
setToolbarProfileImage(profileList.singleOrNull { it.id == profile.identifier.toInt() })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onAccountHeaderItemLongClickListener = { view, profile, current ->
|
||||
if (profile is ProfileSettingDrawerItem) {
|
||||
drawerProfileSettingLongClickListener?.invoke(profile.identifier.toInt(), view) ?: true
|
||||
}
|
||||
else {
|
||||
drawerProfileLongClickListener?.invoke(profile.identifier.toInt(), profile, current, view) ?: false
|
||||
}
|
||||
}
|
||||
|
||||
onAccountHeaderProfileImageListener = { view, profile, current ->
|
||||
drawerProfileImageClickListener?.invoke(profile.identifier.toInt(), profile, current, view) ?: false
|
||||
}
|
||||
//.withTextColor(ContextCompat.getColor(context, R.color.material_drawer_dark_primary_text))
|
||||
}
|
||||
|
||||
drawer = MaterialDrawerSliderView(context).apply {
|
||||
accountHeader = this@NavDrawer.accountHeader
|
||||
itemAnimator = AlphaCrossFadeAnimator()
|
||||
//hasStableIds = true
|
||||
|
||||
onDrawerItemClickListener = { _, drawerItem, position ->
|
||||
if (drawerItem.identifier.toInt() == selection) {
|
||||
false
|
||||
}
|
||||
else {
|
||||
val consumed = drawerItemSelectedListener?.invoke(drawerItem.identifier.toInt(), position, drawerItem)
|
||||
if (consumed == false || !drawerItem.isSelectable) {
|
||||
setSelection(selection, false)
|
||||
consumed == false
|
||||
}
|
||||
else if (consumed == true) {
|
||||
when (drawerItem) {
|
||||
is DrawerPrimaryItem -> toolbar.title = drawerItem.appTitle ?: drawerItem.name?.getText(context) ?: ""
|
||||
is BaseDrawerItem<*, *> -> toolbar.title = drawerItem.name?.getText(context) ?: ""
|
||||
}
|
||||
false
|
||||
}
|
||||
else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDrawerItemLongClickListener = { _, drawerItem, position ->
|
||||
drawerItemLongClickListener?.invoke(drawerItem.identifier.toInt(), position, drawerItem) ?: true
|
||||
}
|
||||
}
|
||||
|
||||
miniDrawer = MiniDrawerSliderView(context).apply {
|
||||
drawer = this@NavDrawer.drawer
|
||||
includeSecondaryDrawerItems = false
|
||||
try {
|
||||
this::class.java.getDeclaredField("onMiniDrawerItemClickListener").let {
|
||||
it.isAccessible = true
|
||||
it.set(this, { v: View?, position: Int, item: IDrawerItem<*>, type: Int ->
|
||||
if (item is MiniProfileDrawerItem) {
|
||||
profileSelectionOpen()
|
||||
open()
|
||||
true
|
||||
} else false
|
||||
})
|
||||
}
|
||||
} catch (_: Exception) { }
|
||||
}
|
||||
|
||||
updateMiniDrawer()
|
||||
|
||||
toolbar.profileImageClickListener = {
|
||||
profileSelectionOpen()
|
||||
open()
|
||||
}
|
||||
|
||||
val configuration = context.resources.configuration
|
||||
decideDrawerMode(
|
||||
configuration.orientation,
|
||||
configuration.screenWidthDp,
|
||||
configuration.screenHeightDp
|
||||
)
|
||||
}
|
||||
|
||||
/* _____ _
|
||||
|_ _| |
|
||||
| | | |_ ___ _ __ ___ ___
|
||||
| | | __/ _ \ '_ ` _ \/ __|
|
||||
_| |_| || __/ | | | | \__ \
|
||||
|_____|\__\___|_| |_| |_|__*/
|
||||
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)
|
||||
updateMiniDrawer()
|
||||
}
|
||||
|
||||
/* _____ _ _ _ _ _
|
||||
| __ \ (_) | | | | | | | |
|
||||
| |__) | __ ___ ____ _| |_ ___ _ __ ___ ___| |_| |__ ___ __| |___
|
||||
| ___/ '__| \ \ / / _` | __/ _ \ | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
|
||||
| | | | | |\ V / (_| | || __/ | | | | | | __/ |_| | | | (_) | (_| \__ \
|
||||
|_| |_| |_| \_/ \__,_|\__\___| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|__*/
|
||||
private fun drawerSetDragMargin(size: Float) {
|
||||
try {
|
||||
val mDrawerLayout = drawerLayout
|
||||
val mDragger = mDrawerLayout::class.java.getDeclaredField(
|
||||
"mLeftDragger"
|
||||
)
|
||||
mDragger.isAccessible = true
|
||||
val draggerObj = mDragger.get(mDrawerLayout) as ViewDragHelper?
|
||||
draggerObj?.edgeSize = size.toInt()
|
||||
|
||||
// update for SDK >= 29 (Android 10)
|
||||
val useSystemInsets = mDrawerLayout::class.java.getDeclaredField(
|
||||
"sEdgeSizeUsingSystemGestureInsets"
|
||||
)
|
||||
useSystemInsets.isAccessible = true
|
||||
useSystemInsets.set(null, false)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(context, "Oops, proguard works", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
var miniDrawerVisiblePortrait: Boolean? = null
|
||||
set(value) {
|
||||
field = value
|
||||
val configuration = context.resources.configuration
|
||||
decideDrawerMode(
|
||||
configuration.orientation,
|
||||
configuration.screenWidthDp,
|
||||
configuration.screenHeightDp
|
||||
)
|
||||
}
|
||||
var miniDrawerVisibleLandscape: Boolean? = null
|
||||
set(value) {
|
||||
field = value
|
||||
val configuration = context.resources.configuration
|
||||
decideDrawerMode(
|
||||
configuration.orientation,
|
||||
configuration.screenWidthDp,
|
||||
configuration.screenHeightDp
|
||||
)
|
||||
}
|
||||
|
||||
internal fun decideDrawerMode(orientation: Int, widthDp: Int, heightDp: Int) {
|
||||
val drawerLayoutParams = DrawerLayout.LayoutParams(WRAP_CONTENT, MATCH_PARENT).apply {
|
||||
gravity = Gravity.START
|
||||
}
|
||||
val fixedLayoutParams = FrameLayout.LayoutParams(UIUtils.convertDpToPixel(300f, context).toInt(), MATCH_PARENT)
|
||||
|
||||
Log.d("NavLib", "Deciding drawer mode:")
|
||||
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
Log.d("NavLib", "- fixed container disabled")
|
||||
|
||||
if (drawerContainerLandscape.childCount > 0) {
|
||||
drawerContainerLandscape.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- mini drawer land disabled")
|
||||
|
||||
if (drawerLayout.indexOfChild(drawer) == -1) {
|
||||
drawerLayout.addView(drawer, drawerLayoutParams)
|
||||
}
|
||||
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||
Log.d("NavLib", "- slider enabled")
|
||||
|
||||
if ((widthDp >= 480 && miniDrawerVisiblePortrait != false) || miniDrawerVisiblePortrait == true) {
|
||||
if (drawerContainerPortrait.indexOfChild(miniDrawer) == -1)
|
||||
drawerContainerPortrait.addView(miniDrawer)
|
||||
Log.d("NavLib", "- mini drawer port enabled")
|
||||
drawerSetDragMargin(72 * resources.displayMetrics.density)
|
||||
drawerMode = DRAWER_MODE_MINI
|
||||
updateMiniDrawer()
|
||||
}
|
||||
else {
|
||||
if (drawerContainerPortrait.childCount > 0) {
|
||||
drawerContainerPortrait.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- mini drawer port disabled")
|
||||
drawerSetDragMargin(20 * resources.displayMetrics.density)
|
||||
drawerMode = DRAWER_MODE_NORMAL
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (drawerContainerPortrait.childCount > 0) {
|
||||
drawerContainerPortrait.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- mini drawer port disabled")
|
||||
|
||||
if ((widthDp in 480 until 900 && miniDrawerVisibleLandscape != false) || miniDrawerVisibleLandscape == true) {
|
||||
if (drawerContainerLandscape.indexOfChild(miniDrawer) == -1)
|
||||
drawerContainerLandscape.addView(miniDrawer)
|
||||
Log.d("NavLib", "- mini drawer land enabled")
|
||||
drawerSetDragMargin(72 * resources.displayMetrics.density)
|
||||
drawerMode = DRAWER_MODE_MINI
|
||||
updateMiniDrawer()
|
||||
}
|
||||
else {
|
||||
if (drawerContainerLandscape.childCount > 0) {
|
||||
drawerContainerLandscape.removeAllViews()
|
||||
}
|
||||
Log.d("NavLib", "- mini drawer land disabled")
|
||||
drawerSetDragMargin(20 * resources.displayMetrics.density)
|
||||
drawerMode = DRAWER_MODE_NORMAL
|
||||
}
|
||||
if (widthDp >= 900) {
|
||||
// screen is big enough to show fixed drawer
|
||||
if (drawerLayout.indexOfChild(drawer) != -1) {
|
||||
// remove from slider
|
||||
drawerLayout.removeView(drawer)
|
||||
}
|
||||
// lock the slider
|
||||
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||
Log.d("NavLib", "- slider disabled")
|
||||
// add to fixed container
|
||||
if (drawerContainerLandscape.indexOfChild(drawer) == -1)
|
||||
drawerContainerLandscape.addView(drawer, fixedLayoutParams)
|
||||
drawer.visibility = View.VISIBLE
|
||||
Log.d("NavLib", "- fixed container enabled")
|
||||
drawerMode = DRAWER_MODE_FIXED
|
||||
}
|
||||
else {
|
||||
// screen is too small for the fixed drawer
|
||||
if (drawerContainerLandscape.indexOfChild(drawer) != -1) {
|
||||
// remove from fixed container
|
||||
drawerContainerLandscape.removeView(drawer)
|
||||
}
|
||||
Log.d("NavLib", "- fixed container disabled")
|
||||
// unlock the slider
|
||||
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||
if (drawerLayout.indexOfChild(drawer) == -1) {
|
||||
// add to slider
|
||||
drawerLayout.addView(drawer, drawerLayoutParams)
|
||||
}
|
||||
Log.d("NavLib", "- slider enabled")
|
||||
}
|
||||
}
|
||||
|
||||
miniDrawerElevation.visibility = if (drawerMode == DRAWER_MODE_MINI || drawerMode == DRAWER_MODE_FIXED) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
private fun updateMiniDrawer() {
|
||||
selection = drawer.selectedItemIdentifier.toInt()
|
||||
//if (drawerMode == DRAWER_MODE_MINI)
|
||||
miniDrawer.createItems()
|
||||
}
|
||||
|
||||
/* _____ _ _ _ _ _ _
|
||||
| __ \ | | | (_) | | | | | |
|
||||
| |__) | _| |__ | |_ ___ _ __ ___ ___| |_| |__ ___ __| |___
|
||||
| ___/ | | | '_ \| | |/ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
|
||||
| | | |_| | |_) | | | (__ | | | | | | __/ |_| | | | (_) | (_| \__ \
|
||||
|_| \__,_|_.__/|_|_|\___| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|__*/
|
||||
var isOpen
|
||||
get() = drawerLayout.isOpen || drawerMode == DRAWER_MODE_FIXED
|
||||
set(value) {
|
||||
if (drawerMode == DRAWER_MODE_FIXED)
|
||||
return
|
||||
if (value && !isOpen) drawerLayout.open() else if (!value && isOpen) drawerLayout.close()
|
||||
}
|
||||
fun open() { isOpen = true }
|
||||
fun close() { isOpen = false }
|
||||
fun toggle() { isOpen = !isOpen }
|
||||
|
||||
var profileSelectionIsOpen
|
||||
get() = accountHeader.selectionListShown
|
||||
set(value) {
|
||||
if (value != profileSelectionIsOpen)
|
||||
profileSelectionToggle()
|
||||
}
|
||||
fun profileSelectionOpen() { profileSelectionIsOpen = true }
|
||||
fun profileSelectionClose() { profileSelectionIsOpen = false }
|
||||
fun profileSelectionToggle() { accountHeader.selectionListShown = !accountHeader.selectionListShown }
|
||||
|
||||
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) {
|
||||
Log.d("NavDebug", "setSelection(id = $id, fireOnClick = $fireOnClick)")
|
||||
// seems that this cannot be open, because the itemAdapter has Profile items
|
||||
// instead of normal Drawer items...
|
||||
profileSelectionClose()
|
||||
selection = id
|
||||
|
||||
if (drawer.selectedItemIdentifier != id.toLong()) {
|
||||
|
||||
}
|
||||
|
||||
if (drawer.selectedItemIdentifier != id.toLong() || !fireOnClick)
|
||||
drawer.setSelectionAtPosition(drawer.getPosition(id.toLong()), fireOnClick)
|
||||
|
||||
miniDrawer.setSelection(-1L)
|
||||
if (drawerMode == DRAWER_MODE_MINI)
|
||||
miniDrawer.setSelection(id.toLong())
|
||||
}
|
||||
fun getSelection(): Int = selection
|
||||
|
||||
// TODO 2019-08-27 add methods for Drawable, @DrawableRes
|
||||
fun setAccountHeaderBackground(path: String?) {
|
||||
if (path == null) {
|
||||
accountHeader.headerBackground = ImageHolder(R.drawable.header)
|
||||
return
|
||||
}
|
||||
accountHeader.headerBackground = ImageHolder(path)
|
||||
}
|
||||
|
||||
/* _____ __ _ _
|
||||
| __ \ / _(_) |
|
||||
| |__) | __ ___ | |_ _| | ___ ___
|
||||
| ___/ '__/ _ \| _| | |/ _ \/ __|
|
||||
| | | | | (_) | | | | | __/\__ \
|
||||
|_| |_| \___/|_| |_|_|\___||__*/
|
||||
private var profileList: MutableList<IDrawerProfile> = mutableListOf()
|
||||
|
||||
fun addProfileSettings(vararg items: ProfileSettingDrawerItem) {
|
||||
accountHeader.profiles?.addAll(items)
|
||||
}
|
||||
|
||||
private fun updateProfileList() {
|
||||
// remove all profile items
|
||||
val profiles = accountHeader.profiles?.filterNot { it is ProfileDrawerItem } as MutableList<IProfile>?
|
||||
|
||||
if (profileList.isEmpty())
|
||||
drawerProfileListEmptyListener?.invoke()
|
||||
|
||||
profileList.forEachIndexed { index, profile ->
|
||||
val image = profile.getImageHolder(context)
|
||||
ProfileDrawerItem()
|
||||
.withIdentifier(profile.id.toLong())
|
||||
.withName(profile.name)
|
||||
.withEmail(profile.subname)
|
||||
.also { it.icon = image }
|
||||
.withBadgeStyle(badgeStyle)
|
||||
.withNameShown(true)
|
||||
.also { profiles?.add(index, it) }
|
||||
}
|
||||
|
||||
accountHeader.profiles = profiles
|
||||
|
||||
updateBadges()
|
||||
updateMiniDrawer()
|
||||
}
|
||||
|
||||
fun setProfileList(profiles: MutableList<out IDrawerProfile>) {
|
||||
profileList = profiles as MutableList<IDrawerProfile>
|
||||
updateProfileList()
|
||||
}
|
||||
private var currentProfileObj: IDrawerProfile? = null
|
||||
val profileListEmpty: Boolean
|
||||
get() = profileList.isEmpty()
|
||||
var currentProfile: Int
|
||||
get() = accountHeader.activeProfile?.identifier?.toInt() ?: -1
|
||||
set(value) {
|
||||
Log.d("NavDebug", "currentProfile = $value")
|
||||
accountHeader.setActiveProfile(value.toLong(), false)
|
||||
currentProfileObj = profileList.singleOrNull { it.id == value }
|
||||
setToolbarProfileImage(currentProfileObj)
|
||||
updateBadges()
|
||||
}
|
||||
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 = profileList.filterNot { it.id == id }.toMutableList()
|
||||
updateProfileList()
|
||||
}
|
||||
fun removeProfileAt(index: Int) {
|
||||
profileList.removeAt(index)
|
||||
updateProfileList()
|
||||
}
|
||||
fun removeAllProfile() {
|
||||
profileList.clear()
|
||||
updateProfileList()
|
||||
}
|
||||
fun removeAllProfileSettings() {
|
||||
accountHeader.profiles = accountHeader.profiles?.filterNot { it is ProfileSettingDrawerItem }?.toMutableList()
|
||||
}
|
||||
|
||||
fun getProfileById(id: Int, run: (it: IDrawerProfile?) -> Unit) {
|
||||
profileList.singleOrNull { it.id == id }.also {
|
||||
run(it)
|
||||
updateProfileList()
|
||||
}
|
||||
}
|
||||
fun getProfileByIndex(index: Int, run: (it: IDrawerProfile?) -> Unit) {
|
||||
profileList.getOrNull(index).also {
|
||||
run(it)
|
||||
updateProfileList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setToolbarProfileImage(profile: IDrawerProfile?) {
|
||||
toolbar.profileImage = profile?.getImageDrawable(context)
|
||||
}
|
||||
|
||||
|
||||
/* ____ _
|
||||
| _ \ | |
|
||||
| |_) | __ _ __| | __ _ ___ ___
|
||||
| _ < / _` |/ _` |/ _` |/ _ \/ __|
|
||||
| |_) | (_| | (_| | (_| | __/\__ \
|
||||
|____/ \__,_|\__,_|\__, |\___||___/
|
||||
__/ |
|
||||
|__*/
|
||||
private var unreadCounterList: MutableList<IUnreadCounter> = mutableListOf()
|
||||
private val unreadCounterTypeMap = mutableMapOf<Int, Int>()
|
||||
|
||||
fun updateBadges() {
|
||||
|
||||
currentProfileObj = profileList.singleOrNull { it.id == currentProfile }
|
||||
|
||||
drawer.itemAdapter.itemList.items.forEachIndexed { index, item ->
|
||||
if (item is Badgeable) {
|
||||
item.badge = null
|
||||
drawer.updateItem(item)
|
||||
}
|
||||
}
|
||||
|
||||
var profileCounters = listOf<IUnreadCounter>()
|
||||
|
||||
accountHeader.profiles?.forEach { profile ->
|
||||
if (profile !is ProfileDrawerItem) return@forEach
|
||||
val counters = unreadCounterList.filter { it.profileId == profile.identifier.toInt() }
|
||||
val count = counters.sumBy { it.count }
|
||||
val badge = when {
|
||||
count == 0 -> null
|
||||
count >= 99 -> StringHolder("99+")
|
||||
else -> StringHolder(count.toString())
|
||||
}
|
||||
if (profile.badge != badge) {
|
||||
profile.badge = badge
|
||||
accountHeader.updateProfile(profile)
|
||||
}
|
||||
|
||||
if (currentProfile == profile.identifier.toInt())
|
||||
profileCounters = counters
|
||||
}
|
||||
|
||||
Log.d("NavDebug", "updateBadges()")
|
||||
profileCounters.map {
|
||||
it.drawerItemId = unreadCounterTypeMap[it.type]
|
||||
}
|
||||
var totalCount = 0
|
||||
profileCounters.forEach {
|
||||
if (it.drawerItemId == null)
|
||||
return@forEach
|
||||
if (it.profileId != currentProfile) {
|
||||
//Log.d("NavDebug", "- Remove badge for ${it.drawerItemId}")
|
||||
//drawer?.updateBadge(it.drawerItemId?.toLong() ?: 0, null)
|
||||
return@forEach
|
||||
}
|
||||
Log.d("NavDebug", "- Set badge ${it.count} for ${it.drawerItemId}")
|
||||
drawer.updateBadge(
|
||||
it.drawerItemId?.toLong() ?: 0,
|
||||
when {
|
||||
it.count == 0 -> null
|
||||
it.count >= 99 -> StringHolder("99+")
|
||||
else -> StringHolder(it.count.toString())
|
||||
}
|
||||
)
|
||||
totalCount += it.count
|
||||
}
|
||||
updateMiniDrawer()
|
||||
|
||||
if (bottomBar.navigationIcon is LayerDrawable) {
|
||||
(bottomBar.navigationIcon as LayerDrawable?)?.apply {
|
||||
findDrawableByLayerId(R.id.ic_badge)
|
||||
.takeIf { it is BadgeDrawable }
|
||||
?.also { badge ->
|
||||
(badge as BadgeDrawable).setCount(totalCount.toString())
|
||||
mutate()
|
||||
setDrawableByLayerId(R.id.ic_badge, badge)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (totalCount == 0) {
|
||||
toolbar.subtitle = resources.getString(
|
||||
toolbar.subtitleFormat ?: return,
|
||||
currentProfileObj?.name ?: ""
|
||||
)
|
||||
}
|
||||
else {
|
||||
toolbar.subtitle = resources.getQuantityString(
|
||||
toolbar.subtitleFormatWithUnread ?: toolbar.subtitleFormat ?: return,
|
||||
totalCount,
|
||||
currentProfileObj?.name ?: "",
|
||||
totalCount
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setUnreadCounterList(unreadCounterList: MutableList<out IUnreadCounter>) {
|
||||
this.unreadCounterList = unreadCounterList as MutableList<IUnreadCounter>
|
||||
updateBadges()
|
||||
}
|
||||
|
||||
fun addUnreadCounterType(type: Int, drawerItem: Int) {
|
||||
unreadCounterTypeMap[type] = drawerItem
|
||||
}
|
||||
|
||||
data class UnreadCounter(
|
||||
override var profileId: Int,
|
||||
override var type: Int,
|
||||
override var drawerItemId: Int?,
|
||||
override var count: Int
|
||||
) : IUnreadCounter
|
||||
|
||||
fun setUnreadCount(profileId: Int, type: Int, count: Int) {
|
||||
val item = unreadCounterList.singleOrNull {
|
||||
it.type == type && it.profileId == profileId
|
||||
}
|
||||
if (item != null) {
|
||||
item.count = count
|
||||
}
|
||||
else {
|
||||
unreadCounterList.add(UnreadCounter(profileId, type, null, count))
|
||||
}
|
||||
updateBadges()
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
fun PrimaryDrawerItem.withAppTitle(appTitle: String?): PrimaryDrawerItem {
|
||||
if (this !is DrawerPrimaryItem)
|
||||
return this
|
||||
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>
|
BIN
navlib/src/main/res/drawable/header.png
Normal file
BIN
navlib/src/main/res/drawable/header.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
10
navlib/src/main/res/drawable/ic_menu_badge.xml
Normal file
10
navlib/src/main/res/drawable/ic_menu_badge.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/ic_menu"
|
||||
android:drawable="@drawable/placeholder"
|
||||
android:gravity="center" />
|
||||
<item
|
||||
android:id="@+id/ic_badge"
|
||||
android:drawable="@drawable/placeholder" />
|
||||
</layer-list>
|
3
navlib/src/main/res/drawable/placeholder.xml
Normal file
3
navlib/src/main/res/drawable/placeholder.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
</shape>
|
15
navlib/src/main/res/drawable/profile.xml
Normal file
15
navlib/src/main/res/drawable/profile.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="512dp"
|
||||
android:height="512dp"
|
||||
android:viewportWidth="135.5"
|
||||
android:viewportHeight="135.5">
|
||||
<path
|
||||
android:pathData="M0,0h135.5L135.5,135.5L0,135.5z"
|
||||
android:fillColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="M41.674,55.89a28.412,26.387 85.529,1 0,52.798 0.379a28.412,26.387 85.529,1 0,-52.798 -0.379z"
|
||||
android:fillColor="#b0ffffff"/>
|
||||
<path
|
||||
android:pathData="M121,133.2a53.3,39 0,0 1,-50.9 38.9A53.3,39 0,0 1,14.8 136.5a53.3,39 0,0 1,46 -42,53.3 39,0 0,1 59.5,32"
|
||||
android:fillColor="#b0ffffff"/>
|
||||
</vector>
|
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>
|
@ -32,8 +32,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bottom_sheet_background"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingHorizontal="8dp"
|
||||
tools:paddingBottom="48dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
@ -43,19 +42,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 +85,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>
|
||||
|
||||
@ -122,7 +98,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="never"
|
||||
android:minHeight="50dp"
|
||||
tools:minHeight="50dp"
|
||||
tools:listitem="@layout/nav_bs_item_primary"/>
|
||||
|
||||
</LinearLayout>
|
||||
@ -130,4 +106,4 @@
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</layout>
|
||||
</layout>
|
||||
|
@ -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>
|
@ -3,20 +3,47 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/item_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:gravity="center"
|
||||
android:background="?selectableItemBackground"
|
||||
android:orientation="vertical">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
<ImageView
|
||||
android:id="@+id/item_icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:drawablePadding="16dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large"
|
||||
android:textSize="14sp"
|
||||
tools:text="Search activity" />
|
||||
tools:srcCompat="@drawable/ic_android" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textAppearance="@style/NavView.TextView"
|
||||
android:textSize="14sp"
|
||||
tools:text="Search activity" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif"
|
||||
android:gravity="center_vertical|start"
|
||||
android:lines="1"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/NavView.TextView.Small"
|
||||
android:textSize="12sp"
|
||||
tools:text="Some drawer text" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -4,122 +4,208 @@
|
||||
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"
|
||||
<androidx.drawerlayout.widget.DrawerLayout
|
||||
android:id="@+id/nv_drawerLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
tools:layout_height="25dp"
|
||||
android:background="?android:windowBackground" />
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<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
|
||||
android:id="@+id/nv_drawerContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/nv_main"
|
||||
android:layout_width="match_parent"
|
||||
<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_drawerContainerLandscape"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/colorSurface_4dp"
|
||||
tools:layout_width="72dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/nv_coordinator"
|
||||
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"
|
||||
style="@style/Widget.MaterialComponents.Toolbar.Surface"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?actionBarBackground"
|
||||
android:clipToPadding="false"
|
||||
android:elevation="4dp"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:title="@string/app_name"
|
||||
app:titleMargin="0dp"
|
||||
tools:targetApi="lollipop">
|
||||
|
||||
<com.mikepenz.materialdrawer.view.BezelImageView
|
||||
android:id="@+id/nv_toolbar_image"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:layout_marginEnd="13dp"
|
||||
android:layout_marginRight="13dp"
|
||||
android:scaleType="centerCrop"
|
||||
app:materialDrawerSelectorOnPress="#80ffffff"
|
||||
tools:src="@tools:sample/backgrounds/scenic" />
|
||||
|
||||
</pl.szczodrzynski.navlib.NavToolbar>
|
||||
|
||||
<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"
|
||||
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
|
||||
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:gravity="start"
|
||||
android:visibility="visible"
|
||||
app:fabAlignmentMode="center"
|
||||
app:fabAnimationMode="scale" />
|
||||
|
||||
<com.balysv.materialripple.MaterialRippleLayout
|
||||
android:id="@+id/ripple"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="?actionBarSize"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:enabled="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:focusable="false"
|
||||
app:mrl_rippleFadeDuration="200"
|
||||
app:mrl_rippleDuration="350"
|
||||
app:mrl_rippleColor="?colorOnBackground"
|
||||
app:mrl_rippleAlpha="0.3">
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:enabled="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:focusable="false"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
</com.balysv.materialripple.MaterialRippleLayout>
|
||||
|
||||
<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"/>
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
<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" />
|
||||
|
||||
</FrameLayout>
|
||||
<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>
|
||||
</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" />
|
||||
|
@ -6,4 +6,14 @@
|
||||
<color name="background_light">#ffffff</color>
|
||||
<color name="background_dark">#242424</color>
|
||||
<color name="background_black">#000000</color>
|
||||
|
||||
<color name="colorSurface_1dp">#0dffffff</color>
|
||||
<color name="colorSurface_2dp">#12ffffff</color>
|
||||
<color name="colorSurface_3dp">#14ffffff</color>
|
||||
<color name="colorSurface_4dp">#17ffffff</color>
|
||||
<color name="colorSurface_6dp">#1cffffff</color>
|
||||
<color name="colorSurface_8dp">#1fffffff</color>
|
||||
<color name="colorSurface_12dp">#24ffffff</color>
|
||||
<color name="colorSurface_16dp">#26ffffff</color>
|
||||
<color name="colorSurface_24dp">#29ffffff</color>
|
||||
</resources>
|
4
navlib/src/main/res/values/dimens.xml
Normal file
4
navlib/src/main/res/values/dimens.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="badge_text_size">10sp</dimen>
|
||||
</resources>
|
@ -1,3 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">NavLib</string>
|
||||
<string name="toolbar_subtitle">%1$s</string>
|
||||
</resources>
|
||||
|
@ -13,67 +13,141 @@
|
||||
<item name="android:textColor">?colorOnFab</item>
|
||||
</style>
|
||||
|
||||
<style name="NavView.TextView">
|
||||
<item name="android:textAppearance">@style/NavView.TextView.Normal</item>
|
||||
</style>
|
||||
<!-- title text 20sp, primary, medium -->
|
||||
<!-- subtitle text 16sp, primary, medium -->
|
||||
<!-- large body text 22sp, primary, regular -->
|
||||
<!-- medium body text 18sp, primary, regular -->
|
||||
<!-- normal(default) body text 14sp, primary, regular -->
|
||||
<!-- small body text 14sp, secondary, medium -->
|
||||
<!-- helper body text 14sp, secondary, regular -->
|
||||
<style name="NavView.TextView.Normal" parent="Widget.MaterialComponents.TextView">
|
||||
<item name="android:textAppearance">?attr/textAppearanceBody2</item>
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textColor">?android:textColorPrimary</item>
|
||||
</style>
|
||||
<style name="NavView.TextView.Title" parent="TextAppearance.AppCompat.Title">
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
<style name="NavView.TextView.Subtitle" parent="TextAppearance.AppCompat.Subhead">
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
</style>
|
||||
<style name="NavView.TextView.Large" parent="TextAppearance.AppCompat.Large">
|
||||
</style>
|
||||
<style name="NavView.TextView.Medium" parent="TextAppearance.AppCompat.Medium">
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
</style>
|
||||
<style name="NavView.TextView.Small" parent="TextAppearance.AppCompat.Small">
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:fontFamily">sans-serif-medium</item>
|
||||
</style>
|
||||
<style name="NavView.TextView.Helper" parent="TextAppearance.AppCompat.Small">
|
||||
<item name="android:textSize">14sp</item>
|
||||
</style>
|
||||
|
||||
|
||||
<!--<item name="colorAccent">#ffb300</item>-->
|
||||
|
||||
<style name="NavView.Light" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
<item name="android:colorBackground">@color/background_light</item>
|
||||
<!-- 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:windowBackground">?android:colorBackground</item>
|
||||
<!-- a descendant theme should specify those two as background colors -->
|
||||
<item name="android:colorBackground">@color/background_light</item>
|
||||
<item name="colorSurface">#ffffff</item>
|
||||
|
||||
<!-- FAB styling -->
|
||||
<item name="colorFab">?colorAccent</item>
|
||||
<item name="colorFabIcon">?colorOnSecondary</item>
|
||||
<item name="colorOnFab">?colorOnSecondary</item>
|
||||
|
||||
<!-- text colors -->
|
||||
<item name="android:textColorPrimary">#db000000</item>
|
||||
<item name="android:textColorSecondary">#99000000</item>
|
||||
<item name="colorOnPrimary">#ffffff</item>
|
||||
<item name="colorOnSecondary">#ffffff</item>
|
||||
<item name="colorOnBackground">?android:textColorPrimary</item>
|
||||
<item name="colorOnSurface">?android:textColorPrimary</item>
|
||||
|
||||
<item name="elevationOverlayColor">#ffffff</item>
|
||||
|
||||
<item name="colorOnBackground">#000000</item>
|
||||
<item name="colorOnSurface">#000000</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" tools:ignore="PrivateResource">@color/mtrl_filled_background_color</item>
|
||||
<item name="android:textViewStyle">@style/NavView.TextView</item>
|
||||
|
||||
<item name="material_drawer_background">?android:colorBackground</item>
|
||||
<item name="material_drawer_primary_text">#242424</item>
|
||||
<item name="material_drawer_primary_icon">#5F6368</item>
|
||||
<item name="material_drawer_secondary_text">@color/material_drawer_secondary_text</item>
|
||||
<item name="material_drawer_hint_text">@color/material_drawer_hint_text</item>
|
||||
<item name="material_drawer_divider">@color/material_drawer_divider</item>
|
||||
<item name="material_drawer_selected">@color/material_drawer_selected</item> <!-- Material 2 defines 12% alpha, primary color -->
|
||||
<item name="material_drawer_selected_text">#242424</item>
|
||||
<item name="material_drawer_header_selection_text">@color/material_drawer_header_selection_text</item>
|
||||
<item name="material_drawer_header_selection_subtext">@color/material_drawer_dark_header_selection_subtext</item>
|
||||
<!-- drawer & bottom sheet styling -->
|
||||
<item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyle</item>
|
||||
<item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyle</item>
|
||||
<!--<item name="materialDrawerPrimaryIcon">#5F6368</item>-->
|
||||
</style>
|
||||
|
||||
<style name="NavView.Dark" parent="Theme.MaterialComponents.NoActionBar">
|
||||
<item name="android:colorBackground">@color/background_dark</item>
|
||||
<!-- 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:windowBackground">?android:colorBackground</item>
|
||||
<item name="colorSurface">#303030</item>
|
||||
<!-- a descendant theme should specify those two as background colors -->
|
||||
<item name="android:colorBackground">@color/background_dark</item>
|
||||
<item name="colorSurface">#333333</item>
|
||||
|
||||
<item name="colorOnBackground">#ffffff</item>
|
||||
<item name="colorOnSurface">#ffffff</item>
|
||||
<!-- FAB styling -->
|
||||
<item name="colorFab">?colorAccent</item>
|
||||
<item name="colorFabIcon">?colorOnSecondary</item>
|
||||
<item name="colorOnFab">?colorOnSecondary</item>
|
||||
|
||||
<item name="nv_actionBarBackground">?colorSurface</item>
|
||||
<!-- text colors -->
|
||||
<item name="android:textColorPrimary">#ffffffff</item>
|
||||
<item name="android:textColorSecondary">#99ffffff</item>
|
||||
<item name="colorOnPrimary">#ffffff</item>
|
||||
<item name="colorOnSecondary">#ffffff</item>
|
||||
<item name="colorOnBackground">?android:textColorPrimary</item>
|
||||
<item name="colorOnSurface">?android:textColorPrimary</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>
|
||||
|
||||
<item name="material_drawer_background">?android:colorBackground</item>
|
||||
<item name="material_drawer_primary_text">#FFFFFF</item>
|
||||
<item name="material_drawer_primary_icon">#9AA0A6</item>
|
||||
<item name="material_drawer_secondary_text">@color/material_drawer_dark_secondary_text</item>
|
||||
<item name="material_drawer_hint_text">@color/material_drawer_dark_hint_text</item>
|
||||
<item name="material_drawer_divider">@color/material_drawer_dark_divider</item>
|
||||
<item name="material_drawer_selected">@color/material_drawer_dark_selected</item> <!-- Material 2 defines 12% alpha, primary color -->
|
||||
<item name="material_drawer_selected_text">#FFFFFF</item>
|
||||
<item name="material_drawer_header_selection_text">@color/material_drawer_dark_header_selection_text</item>
|
||||
<item name="material_drawer_header_selection_subtext">@color/material_drawer_dark_header_selection_subtext</item>
|
||||
<!-- drawer & bottom sheet styling -->
|
||||
<item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyle</item>
|
||||
<item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyle</item>
|
||||
<!--<item name="material_drawer_primary_icon">#9AA0A6</item>-->
|
||||
</style>
|
||||
|
||||
<style name="NavView.Black" parent="NavView.Dark">
|
||||
<item name="android:colorBackground">@color/background_black</item>
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
<item name="colorSurface">#121212</item>
|
||||
</style>
|
||||
|
||||
@ -82,4 +156,4 @@
|
||||
<style name="width_max_600dp">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
</style>
|
||||
</resources>
|
||||
</resources>
|
||||
|
@ -1 +1 @@
|
||||
include ':app', ':navlib'
|
||||
include ':app', ':navlib', ':navlib-font'
|
||||
|
Loading…
x
Reference in New Issue
Block a user