From e657a2262d68b6a7a9d83795e445978d2fffb719 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 6 Jun 2019 17:13:50 +0200 Subject: [PATCH] Add submenu for new add task button --- .../drawable-hdpi/fab_submenu_background.png | Bin 0 -> 3034 bytes .../drawable-mdpi/fab_submenu_background.png | Bin 0 -> 1876 bytes .../drawable-xhdpi/fab_submenu_background.png | Bin 0 -> 4245 bytes .../fab_submenu_background.png | Bin 0 -> 7291 bytes .../fab_submenu_background.png | Bin 0 -> 10392 bytes .../res/drawable/bottom_submenu_label_bg.xml | 5 + Habitica/res/layout/activity_main.xml | 1 - .../res/layout/bottom_navigation_item.xml | 3 + .../res/layout/bottom_navigation_submenu.xml | 35 +++++++ Habitica/res/layout/main_navigation_view.xml | 22 +++-- Habitica/res/values/strings.xml | 1 + Habitica/res/xml/remote_config_defaults.xml | 4 + .../habitica/helpers/AppConfigManager.kt | 4 + .../ui/fragments/tasks/TasksFragment.kt | 4 + .../navigation/BottomNavigationSubmenuItem.kt | 46 +++++++++ .../HabiticaBottomNavigationView.kt | 87 +++++++++++++++++- 16 files changed, 203 insertions(+), 9 deletions(-) create mode 100644 Habitica/res/drawable-hdpi/fab_submenu_background.png create mode 100644 Habitica/res/drawable-mdpi/fab_submenu_background.png create mode 100644 Habitica/res/drawable-xhdpi/fab_submenu_background.png create mode 100644 Habitica/res/drawable-xxhdpi/fab_submenu_background.png create mode 100644 Habitica/res/drawable-xxxhdpi/fab_submenu_background.png create mode 100644 Habitica/res/drawable/bottom_submenu_label_bg.xml create mode 100644 Habitica/res/layout/bottom_navigation_submenu.xml create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/navigation/BottomNavigationSubmenuItem.kt diff --git a/Habitica/res/drawable-hdpi/fab_submenu_background.png b/Habitica/res/drawable-hdpi/fab_submenu_background.png new file mode 100644 index 0000000000000000000000000000000000000000..2dca2398a366569719db262ab96c9375a1b7ac39 GIT binary patch literal 3034 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%0A!^U%pPqC6+pS-3Z8`ec(PSo*;j^>L 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 literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable-xxhdpi/fab_submenu_background.png b/Habitica/res/drawable-xxhdpi/fab_submenu_background.png new file mode 100644 index 0000000000000000000000000000000000000000..e77a6846caaea46f6dc4888d6402e08a6961675e GIT binary patch literal 7291 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 NTixJswW@8@{{g9c?&1Id literal 0 HcmV?d00001 diff --git a/Habitica/res/drawable/bottom_submenu_label_bg.xml b/Habitica/res/drawable/bottom_submenu_label_bg.xml new file mode 100644 index 000000000..246cb63b2 --- /dev/null +++ b/Habitica/res/drawable/bottom_submenu_label_bg.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/activity_main.xml b/Habitica/res/layout/activity_main.xml index 65abd301c..85441ced8 100644 --- a/Habitica/res/layout/activity_main.xml +++ b/Habitica/res/layout/activity_main.xml @@ -123,7 +123,6 @@ android:orientation="vertical" android:layout_gravity="bottom|center_horizontal" android:layout_alignParentBottom="true" - app:layout_behavior="com.habitrpg.android.habitica.ui.helpers.FloatingActionMenuBehavior" android:padding="0dp" android:layout_margin="0dp"> @@ -31,6 +33,7 @@ tools:text="@string/habits" android:layout_gravity="center" android:textSize="12sp" + android:letterSpacing="0.05" android:fontFamily="@string/font_family_medium" android:paddingStart="@dimen/spacing_small" android:paddingEnd="@dimen/spacing_small" diff --git a/Habitica/res/layout/bottom_navigation_submenu.xml b/Habitica/res/layout/bottom_navigation_submenu.xml new file mode 100644 index 000000000..c27ab691d --- /dev/null +++ b/Habitica/res/layout/bottom_navigation_submenu.xml @@ -0,0 +1,35 @@ + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/main_navigation_view.xml b/Habitica/res/layout/main_navigation_view.xml index be983d27b..67b315bf3 100644 --- a/Habitica/res/layout/main_navigation_view.xml +++ b/Habitica/res/layout/main_navigation_view.xml @@ -8,10 +8,10 @@ tools:parentTag="android.widget.RelativeLayout"> + android:layout_alignBottom="@id/bottom_navigation_background" + android:layout_marginBottom="21dp" + android:background="@drawable/fab_background" + android:contentDescription="@string/new_task" /> + \ No newline at end of file diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index b478dfc12..b312c2482 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -934,4 +934,5 @@ Switch to list view Switch to grid view Confirm deletion + New Task diff --git a/Habitica/res/xml/remote_config_defaults.xml b/Habitica/res/xml/remote_config_defaults.xml index 9a7d6784c..ee24650c7 100644 --- a/Habitica/res/xml/remote_config_defaults.xml +++ b/Habitica/res/xml/remote_config_defaults.xml @@ -44,5 +44,9 @@ supportEmail admin@habitica.com + + flipAddTaskBehaviour + true + \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt index b855c2f1f..1b63a6932 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt @@ -62,4 +62,8 @@ class AppConfigManager { fun enableLocalTaskScoring(): Boolean { return remoteConfig.getBoolean("enableLocalTaskScoring") } + + fun flipAddTaskBehaviour(): Boolean { + return remoteConfig.getBoolean("flipAddTaskBehaviour") + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt index 6a216a776..97461a51a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt @@ -12,6 +12,7 @@ import com.habitrpg.android.habitica.components.UserComponent import com.habitrpg.android.habitica.data.TagRepository import com.habitrpg.android.habitica.events.TaskTappedEvent import com.habitrpg.android.habitica.helpers.AmplitudeManager +import com.habitrpg.android.habitica.helpers.AppConfigManager import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.helpers.TaskFilterHelper import com.habitrpg.android.habitica.models.tasks.Task @@ -30,6 +31,8 @@ class TasksFragment : BaseMainFragment() { lateinit var taskFilterHelper: TaskFilterHelper @Inject lateinit var tagRepository: TagRepository + @Inject + lateinit var appConfigManager: AppConfigManager private var refreshItem: MenuItem? = null private var floatingMenu: FloatingActionMenu? = null @@ -70,6 +73,7 @@ class TasksFragment : BaseMainFragment() { bottomNavigation?.onAddListener = { openNewTaskActivity(it) } + bottomNavigation?.flipAddBehaviour = appConfigManager.flipAddTaskBehaviour() } override fun onDestroy() { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/navigation/BottomNavigationSubmenuItem.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/navigation/BottomNavigationSubmenuItem.kt new file mode 100644 index 000000000..a6ef2a2f0 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/navigation/BottomNavigationSubmenuItem.kt @@ -0,0 +1,46 @@ +package com.habitrpg.android.habitica.ui.views.navigation + +import android.content.Context +import android.graphics.drawable.Drawable +import android.util.AttributeSet +import android.widget.ImageView +import android.widget.RelativeLayout +import android.widget.TextView +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.extensions.inflate +import com.habitrpg.android.habitica.ui.helpers.bindView + +class BottomNavigationSubmenuItem @JvmOverloads constructor( + context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 +) : RelativeLayout(context, attrs, defStyleAttr) { + + val measuredTitleWidth: Int + get() { + titleView.measure(width, height) + return titleView.measuredWidth + } + private val iconView: ImageView by bindView(R.id.icon_view) + private val titleView: TextView by bindView(R.id.title_view) + + var icon: Drawable? = null + set(value) { + field = value + iconView.setImageDrawable(value) + } + var title: String? = null + set(value) { + field = value + titleView.text = title + } + + init { + inflate(R.layout.bottom_navigation_submenu, true) + } + + fun setTitleWidth(width: Int) { + val layoutParams = titleView.layoutParams as? LayoutParams + layoutParams?.width = width + titleView.layoutParams = layoutParams + } + +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/navigation/HabiticaBottomNavigationView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/navigation/HabiticaBottomNavigationView.kt index f3f6abab0..93a374a52 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/navigation/HabiticaBottomNavigationView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/navigation/HabiticaBottomNavigationView.kt @@ -3,7 +3,10 @@ package com.habitrpg.android.habitica.ui.views.navigation import android.content.Context import android.util.AttributeSet import android.widget.ImageButton +import android.widget.LinearLayout import android.widget.RelativeLayout +import androidx.core.view.ViewCompat +import androidx.core.view.children import com.habitrpg.android.habitica.R import com.habitrpg.android.habitica.extensions.inflate import com.habitrpg.android.habitica.models.tasks.Task @@ -13,6 +16,8 @@ class HabiticaBottomNavigationView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : RelativeLayout(context, attrs, defStyleAttr) { + var flipAddBehaviour = true + private var isShowingSubmenu: Boolean = false var selectedPosition: Int get() { return when (activeTaskType) { @@ -44,6 +49,7 @@ class HabiticaBottomNavigationView @JvmOverloads constructor( private val todosTab: BottomNavigationItem by bindView(R.id.tab_todos) private val rewardsTab: BottomNavigationItem by bindView(R.id.tab_rewards) private val addButton: ImageButton by bindView(R.id.add) + private val submenuWrapper: LinearLayout by bindView(R.id.submenu_wrapper) init { inflate(R.layout.main_navigation_view, true) @@ -52,11 +58,90 @@ class HabiticaBottomNavigationView @JvmOverloads constructor( todosTab.setOnClickListener { activeTaskType = Task.TYPE_TODO } rewardsTab.setOnClickListener { activeTaskType = Task.TYPE_REWARD } addButton.setOnClickListener { - onAddListener?.invoke(activeTaskType) + if (flipAddBehaviour) { + if (isShowingSubmenu) { + hideSubmenu() + } else { + onAddListener?.invoke(activeTaskType) + } + } else { + showSubmenu() + } + } + addButton.setOnLongClickListener { + if (flipAddBehaviour) { + showSubmenu() + } else { + onAddListener?.invoke(activeTaskType) + } + true } updateItemSelection() } + private fun showSubmenu() { + isShowingSubmenu = true + var pos = 4 + submenuWrapper.removeAllViews() + for (taskType in listOf(Task.TYPE_HABIT, Task.TYPE_DAILY, Task.TYPE_TODO, Task.TYPE_REWARD)) { + val view = BottomNavigationSubmenuItem(context) + when (taskType) { + Task.TYPE_HABIT -> { + view.icon = context.getDrawable(R.drawable.add_habit) + view.title = context.getString(R.string.habit) + } + Task.TYPE_DAILY -> { + view.icon = context.getDrawable(R.drawable.add_daily) + view.title = context.getString(R.string.daily) + } + Task.TYPE_TODO -> { + view.icon = context.getDrawable(R.drawable.add_todo) + view.title = context.getString(R.string.todo) + } + Task.TYPE_REWARD -> { + view.icon = context.getDrawable(R.drawable.add_rewards) + view.title = context.getString(R.string.reward) + } + } + view.setOnClickListener { + onAddListener?.invoke(taskType) + hideSubmenu() + } + submenuWrapper.addView(view) + view.alpha = 0f + view.scaleY = 0.7f + ViewCompat.animate(view).alpha(1f).setDuration(250.toLong()).startDelay = (100 * pos).toLong() + ViewCompat.animate(view).scaleY(1f).setDuration(250.toLong()).startDelay = (100 * pos).toLong() + pos -= 1 + } + var widestWidth = 0 + for (view in submenuWrapper.children) { + if (view is BottomNavigationSubmenuItem) { + val width = view.measuredTitleWidth + if (widestWidth < width) { + widestWidth = width + } + } + } + for (view in submenuWrapper.children) { + if (view is BottomNavigationSubmenuItem) { + view.setTitleWidth(widestWidth) + } + } + } + + private fun hideSubmenu() { + isShowingSubmenu = false + var pos = 0 + for (view in submenuWrapper.children) { + view.alpha = 1f + view.scaleY = 1f + ViewCompat.animate(view).alpha(0f).setDuration(200.toLong()).startDelay = (150 * pos).toLong() + ViewCompat.animate(view).scaleY(0.7f).setDuration(250.toLong()).setStartDelay((100 * pos).toLong()).withEndAction { submenuWrapper.removeView(view) } + pos += 1 + } + } + private fun updateItemSelection() { habitsTab.isActive = activeTaskType == Task.TYPE_HABIT dailiesTab.isActive = activeTaskType == Task.TYPE_DAILY