diff --git a/build.gradle b/build.gradle index 71dfc288..3000b040 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,9 @@ ext { /* Android */ - androidUtilsVersion = '1.1.0' + androidUtilsVersion = '1.1.1-SNAPSHOT' + + materialDrawerVersion = "8.0.1" clansFloatingActionButtonVersion = '1.6.4' diff --git a/fints4javaAndroidApp/build.gradle b/fints4javaAndroidApp/build.gradle index d4d0a70c..24ad3316 100644 --- a/fints4javaAndroidApp/build.gradle +++ b/fints4javaAndroidApp/build.gradle @@ -8,7 +8,7 @@ android { defaultConfig { applicationId "net.dankito.banking.fints4java.android" - minSdkVersion 15 + minSdkVersion 16 targetSdkVersion 28 versionCode appVersionCode versionName appVersionName @@ -77,6 +77,14 @@ dependencies { implementation "com.google.android.material:material:$materialComponentsVersion" implementation "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" + // for MaterialDrawer + implementation "com.mikepenz:materialdrawer:$materialDrawerVersion" + implementation "com.mikepenz:materialdrawer-nav:$materialDrawerVersion" + + implementation "com.mikepenz:materialdrawer-iconics:$materialDrawerVersion" + implementation "com.mikepenz:google-material-typeface:3.0.1.4.original-kotlin@aar" + implementation "com.mikepenz:fontawesome-typeface:5.9.0.0-kotlin@aar" + implementation 'androidx.navigation:navigation-fragment:2.0.0-rc02' implementation 'androidx.navigation:navigation-ui:2.0.0-rc02' diff --git a/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/MainActivity.kt b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/MainActivity.kt index e6228d88..6fec6ad8 100644 --- a/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/MainActivity.kt +++ b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/MainActivity.kt @@ -2,23 +2,18 @@ package net.dankito.banking.fints4java.android import android.os.Bundle import android.view.Menu -import android.view.MenuItem import android.view.MotionEvent -import android.view.SubMenu -import android.widget.TextView import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar -import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout import com.github.clans.fab.FloatingActionMenu -import com.google.android.material.navigation.NavigationView -import kotlinx.android.synthetic.main.action_view_account_menu_item.view.* +import kotlinx.android.synthetic.main.activity_main.* +import net.dankito.banking.fints4java.android.ui.views.DrawerView import net.dankito.banking.fints4java.android.ui.views.MainActivityFloatingActionMenuButton import net.dankito.banking.fints4java.android.util.Base64ServiceAndroid import net.dankito.banking.fints4javaBankingClientCreator import net.dankito.banking.persistence.BankingPersistenceJson -import net.dankito.banking.ui.model.Account import net.dankito.banking.ui.presenter.BankingPresenter import net.dankito.utils.web.client.OkHttpWebClient import org.slf4j.LoggerFactory @@ -36,6 +31,8 @@ class MainActivity : AppCompatActivity() { private lateinit var drawerToggle: ActionBarDrawerToggle + private lateinit var drawerView: DrawerView + private lateinit var floatingActionMenuButton: MainActivityFloatingActionMenuButton @@ -60,7 +57,6 @@ class MainActivity : AppCompatActivity() { setSupportActionBar(toolbar) val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout) - val navigationView: NavigationView = findViewById(R.id.nav_view) // val navController = findNavController(R.id.nav_host_fragment) // // Passing each menu ID as a set of Ids because each @@ -80,7 +76,9 @@ class MainActivity : AppCompatActivity() { drawerLayout.addDrawerListener(drawerToggle) drawerToggle.syncState() - setupNavigationView(navigationView, drawerLayout) + slider?.let { slider -> + drawerView = DrawerView(this, slider, presenter) + } val floatingActionMenu = findViewById(R.id.floatingActionMenu) floatingActionMenuButton = MainActivityFloatingActionMenuButton(floatingActionMenu, presenter) @@ -93,89 +91,6 @@ class MainActivity : AppCompatActivity() { } - private fun setupNavigationView(navigationView: NavigationView, drawerLayout: DrawerLayout) { - showAppVersion(navigationView) - - val navigationMenu = navigationView.menu - val accountsMenuItem = navigationMenu.findItem(R.id.navBankAccountsSectionItem) - val accountsMenu = accountsMenuItem.subMenu - - presenter.addAccountsChangedListener { - runOnUiThread { updateNavigationMenuItems(accountsMenu) } - } - - updateNavigationMenuItems(accountsMenu) - - navigationView.setNavigationItemSelectedListener { navigationItemSelected(it) } - } - - private fun updateNavigationMenuItems(accountsMenu: SubMenu) { - accountsMenu.findItem(R.id.navAllBankAccounts).isVisible = presenter.accounts.isNotEmpty() - - // removes previously shown accounts; index 0 = 'Add account', 1 = 'All accounts', don't remove these - for (index in (accountsMenu.size() - 1) downTo 2) { - accountsMenu.removeItem(accountsMenu.getItem(index).itemId) - } - - presenter.accounts.forEach { account -> - val accountMenuItem = accountsMenu.add("") - - accountMenuItem.setActionView(R.layout.action_view_account_menu_item) - accountMenuItem.actionView.txtvwAccountName.text = account.displayName - accountMenuItem.actionView.imgvwEditAccount.setImageResource(R.drawable.ic_build_white_48dp) - accountMenuItem.actionView.imgvwEditAccount.setOnClickListener { editAccount(account) } - - accountMenuItem.setOnMenuItemClickListener { setSelectedAccount(account) } - } - } - - private fun setSelectedAccount(account: Account): Boolean { - presenter.selectedAccount(account) - - closeDrawer() - - return true - } - - private fun editAccount(account: Account) { - // TODO: implement - log.info("Edit account $account") - - closeDrawer() - } - - private fun showAppVersion(navigationView: NavigationView) { - try { - val packageInfo = this.packageManager.getPackageInfo(packageName, 0) - val version = packageInfo.versionName - (navigationView.getHeaderView(0).findViewById(R.id.txtAppVersion) as? TextView)?.text = version - } catch (e: Exception) { - log.error("Could not read application version") - } - } - - private fun navigationItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - R.id.navAddBankAccount -> presenter.showAddAccountDialog() - R.id.navAllBankAccounts -> presenter.selectedAllBankAccounts() - } - - closeDrawer() - - return true - } - - private fun closeDrawer() { - val drawer = findViewById(R.id.drawer_layout) as DrawerLayout - drawer.closeDrawer(GravityCompat.START) - } - -// override fun onSupportNavigateUp(): Boolean { -// val navController = findNavController(R.id.nav_host_fragment) -// return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() -// } - - override fun dispatchTouchEvent(event: MotionEvent): Boolean { if(floatingActionMenuButton.handlesTouch(event)) { // close menu when menu is opened and touch is outside floatingActionMenuButton return true diff --git a/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/extensions/IDrawerItemExtensions.kt b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/extensions/IDrawerItemExtensions.kt new file mode 100644 index 00000000..8c902c0c --- /dev/null +++ b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/extensions/IDrawerItemExtensions.kt @@ -0,0 +1,19 @@ +package net.dankito.banking.fints4java.android.ui.extensions + +import android.content.Context +import com.mikepenz.iconics.typeface.IIcon +import com.mikepenz.materialdrawer.iconics.withIcon +import com.mikepenz.materialdrawer.model.AbstractBadgeableDrawerItem +import com.mikepenz.materialdrawer.model.interfaces.withIconColor +import net.dankito.utils.android.extensions.createColorStateList + + +fun > AbstractBadgeableDrawerItem.withIcon( + context: Context, icon: IIcon, iconColorId: Int): AbstractBadgeableDrawerItem { + + withIcon(icon) + + withIconColor(context.createColorStateList(iconColorId)) + + return this +} \ No newline at end of file diff --git a/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/views/DrawerView.kt b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/views/DrawerView.kt new file mode 100644 index 00000000..cde449c3 --- /dev/null +++ b/fints4javaAndroidApp/src/main/java/net/dankito/banking/fints4java/android/ui/views/DrawerView.kt @@ -0,0 +1,148 @@ +package net.dankito.banking.fints4java.android.ui.views + +import android.view.View +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import com.mikepenz.iconics.typeface.library.fontawesome.FontAwesome +import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial +import com.mikepenz.materialdrawer.model.PrimaryDrawerItem +import com.mikepenz.materialdrawer.model.SecondaryDrawerItem +import com.mikepenz.materialdrawer.model.SectionDrawerItem +import com.mikepenz.materialdrawer.model.interfaces.* +import com.mikepenz.materialdrawer.util.addItems +import com.mikepenz.materialdrawer.util.addItemsAtPosition +import com.mikepenz.materialdrawer.util.removeItemByPosition +import com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView +import net.dankito.banking.fints4java.android.R +import net.dankito.banking.fints4java.android.ui.extensions.withIcon +import net.dankito.banking.ui.model.Account +import net.dankito.banking.ui.presenter.BankingPresenter +import org.slf4j.LoggerFactory + + +open class DrawerView( + protected val activity: AppCompatActivity, + protected val slider: MaterialDrawerSliderView, + protected val presenter: BankingPresenter +) { + + companion object { + private const val AccountLevel = 2 + + private const val BankAccountLevel = 7 + + private const val AccountsSectionHeaderId = 1000L + private const val AllAccountsId = 1001L + private const val AddAccountId = 1002L + + private const val CountDefaultAccountItems = 3 + + + private val log = LoggerFactory.getLogger(DrawerView::class.java) + } + + + init { + setupDrawerView() + } + + + protected open fun setupDrawerView() { + slider.headerView = activity.layoutInflater.inflate(R.layout.nav_header_main, null) + + showAppVersion(slider.headerView) + + setDefaultDrawerItems() + + presenter.addAccountsChangedListener { + activity.runOnUiThread { updateDrawerItems() } + } + + updateDrawerItems() + } + + private fun setDefaultDrawerItems() { + slider.apply { + addItems( + SectionDrawerItem() + .withName(R.string.drawer_menu_bank_accounts_section_title) + .withIdentifier(AccountsSectionHeaderId) + .withDivider(false) + , + + PrimaryDrawerItem() + .withName(R.string.drawer_menu_all_bank_accounts_title) + .withIdentifier(AllAccountsId) + .withLevel(AccountLevel) + .withSelected(true) + .withIcon(activity, GoogleMaterial.Icon.gmd_account_balance, R.color.primaryTextColor_Dark) + .withOnDrawerItemClickListener { _, _, _ -> itemClicked { presenter.selectedAllBankAccounts() } } + , + + PrimaryDrawerItem() + .withName(R.string.drawer_menu_add_bank_account_title) + .withIdentifier(AddAccountId) + .withLevel(AccountLevel) + .withIcon(activity, GoogleMaterial.Icon.gmd_add, R.color.primaryTextColor_Dark) + .withSelectable(false) + .withOnDrawerItemClickListener { _, _, _ -> itemClicked { presenter.showAddAccountDialog() } } + ) + } + } + + private fun updateDrawerItems() { + // removes previously shown accounts; index 1 = 'Accounts header', 1 = 'All accounts', index 2 = 'Add account', don't remove these + while (slider.itemAdapter.adapterItems.size > CountDefaultAccountItems) { + slider.removeItemByPosition(CountDefaultAccountItems) + } + + val accountItems = createAccountsDrawerItems() + + slider.addItemsAtPosition(CountDefaultAccountItems, *accountItems.toTypedArray()) + } + + private fun createAccountsDrawerItems(): List> { + return presenter.accounts.map { account -> + val accountItem = createAccountDrawerItem(account) + + val bankAccountsItems = createBankAccountsDrawerItems(account).toMutableList() + bankAccountsItems.add(0, accountItem) + + return@map bankAccountsItems + }.flatten() + } + + private fun createAccountDrawerItem(account: Account): PrimaryDrawerItem { + return PrimaryDrawerItem() + .withName(account.displayName) + .withLevel(AccountLevel) + .withIcon(activity, FontAwesome.Icon.faw_piggy_bank, R.color.primaryTextColor_Dark) + .withOnDrawerItemClickListener { _, _, _ -> itemClicked { presenter.selectedAccount(account) } } + } + + private fun createBankAccountsDrawerItems(account: Account): List> { + return account.bankAccounts.map { bankAccount -> + SecondaryDrawerItem() + .withName(bankAccount.displayName) + .withLevel(BankAccountLevel) + .withOnDrawerItemClickListener { _, _, _ -> itemClicked { presenter.selectedBankAccount(bankAccount) } } + } + } + + private fun itemClicked(action: () -> Unit): Boolean { + action() + + return false + } + + private fun showAppVersion(navigationHeaderView: View?) { + try { + val packageInfo = activity.packageManager.getPackageInfo(activity.packageName, 0) + val version = packageInfo.versionName + (navigationHeaderView?.findViewById(R.id.txtAppVersion) as? TextView)?.text = version + } catch (e: Exception) { + log.error("Could not read application version") + } + } + +} \ No newline at end of file diff --git a/fints4javaAndroidApp/src/main/res/layout/action_view_account_menu_item.xml b/fints4javaAndroidApp/src/main/res/layout/action_view_account_menu_item.xml deleted file mode 100644 index 7ea8d692..00000000 --- a/fints4javaAndroidApp/src/main/res/layout/action_view_account_menu_item.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/fints4javaAndroidApp/src/main/res/layout/activity_main.xml b/fints4javaAndroidApp/src/main/res/layout/activity_main.xml index d57ff59a..170ef8e2 100644 --- a/fints4javaAndroidApp/src/main/res/layout/activity_main.xml +++ b/fints4javaAndroidApp/src/main/res/layout/activity_main.xml @@ -15,16 +15,12 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> - + diff --git a/fints4javaAndroidApp/src/main/res/menu/activity_main_drawer.xml b/fints4javaAndroidApp/src/main/res/menu/activity_main_drawer.xml deleted file mode 100644 index ceaa8c09..00000000 --- a/fints4javaAndroidApp/src/main/res/menu/activity_main_drawer.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/fints4javaAndroidApp/src/main/res/values-de/strings.xml b/fints4javaAndroidApp/src/main/res/values-de/strings.xml index 8297239a..90b3c54b 100644 --- a/fints4javaAndroidApp/src/main/res/values-de/strings.xml +++ b/fints4javaAndroidApp/src/main/res/values-de/strings.xml @@ -15,9 +15,9 @@ @string/app_name Version\u0020 Navigationsbereich - Konten - Konto hinzufügen - Alle Konten + Konten + Konto hinzufügen + Alle Konten Konto Überweisung diff --git a/fints4javaAndroidApp/src/main/res/values/dimens.xml b/fints4javaAndroidApp/src/main/res/values/dimens.xml index 63cc85b7..47b9addc 100644 --- a/fints4javaAndroidApp/src/main/res/values/dimens.xml +++ b/fints4javaAndroidApp/src/main/res/values/dimens.xml @@ -4,9 +4,6 @@ 16dp 8dp 176dp - 8dp - 56dp - 24dp 16dp 16dp 42dp diff --git a/fints4javaAndroidApp/src/main/res/values/drawables.xml b/fints4javaAndroidApp/src/main/res/values/drawables.xml deleted file mode 100644 index be008299..00000000 --- a/fints4javaAndroidApp/src/main/res/values/drawables.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/fints4javaAndroidApp/src/main/res/values/strings.xml b/fints4javaAndroidApp/src/main/res/values/strings.xml index 8f786b10..47c6e526 100644 --- a/fints4javaAndroidApp/src/main/res/values/strings.xml +++ b/fints4javaAndroidApp/src/main/res/values/strings.xml @@ -15,9 +15,9 @@ @string/app_name Version\u0020 Navigation header - Accounts - Add account - All accounts + Accounts + All accounts + Add account Account Transfer money diff --git a/fints4javaAndroidApp/src/main/res/values/styles.xml b/fints4javaAndroidApp/src/main/res/values/styles.xml index 2b194d10..84cdea14 100644 --- a/fints4javaAndroidApp/src/main/res/values/styles.xml +++ b/fints4javaAndroidApp/src/main/res/values/styles.xml @@ -10,6 +10,18 @@ @color/fabTextColor @color/fabLabelBackgroundColor @color/fabShadowColor + + + @style/Widget.MaterialDrawerStyleCustom + @style/Widget.MaterialDrawerHeaderStyle + + + -