Bottom app bar

pull/1719/head
Alex Baker 2 years ago
parent db973b2419
commit 28f45b05ac

@ -95,7 +95,6 @@ public class BeastModePreferences extends ThemedInjectingAppCompatActivity
toolbar.setNavigationOnClickListener(v -> finish());
toolbar.inflateMenu(R.menu.beast_mode);
toolbar.setOnMenuItemClickListener(this);
themeColor.apply(toolbar);
adapter = new BeastModeRecyclerAdapter(this, constructOrderedControlList(preferences, this));
recyclerView.setHasFixedSize(true);

@ -5,7 +5,6 @@
*/
package com.todoroo.astrid.activity
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
@ -14,7 +13,6 @@ import android.os.Bundle
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.view.ActionMode
import androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListener
import androidx.lifecycle.lifecycleScope
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.activity.TaskEditFragment.Companion.newTaskEditFragment
@ -45,7 +43,6 @@ import org.tasks.intents.TaskIntents.getTaskListIntent
import org.tasks.location.LocationPickerActivity
import org.tasks.preferences.DefaultFilterProvider
import org.tasks.preferences.Preferences
import org.tasks.tasklist.ActionUtils
import org.tasks.themes.ColorProvider
import org.tasks.themes.Theme
import org.tasks.themes.ThemeColor
@ -53,6 +50,7 @@ import org.tasks.ui.DeadlineControlSet.DueDateChangeListener
import org.tasks.ui.EmptyTaskEditFragment.Companion.newEmptyTaskEditFragment
import org.tasks.ui.ListFragment.OnListChanged
import org.tasks.ui.NavigationDrawerFragment
import org.tasks.ui.NavigationDrawerFragment.Companion.newNavigationDrawer
import timber.log.Timber
import javax.inject.Inject
@ -70,7 +68,6 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
@Inject lateinit var tagDataDao: TagDataDao
@Inject lateinit var alarmDao: AlarmDao
private lateinit var navigationDrawer: NavigationDrawerFragment
private var currentNightMode = 0
private var currentPro = false
private var filter: Filter? = null
@ -90,18 +87,6 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
filter = savedInstanceState.getParcelable(EXTRA_FILTER)
applyTheme()
}
navigationDrawer = navigationDrawerFragment
navigationDrawer.setUp(binding.drawerLayout)
binding.drawerLayout.addDrawerListener(
object : SimpleDrawerListener() {
override fun onDrawerStateChanged(newState: Int) {
finishActionMode()
}
override fun onDrawerClosed(drawerView: View) {
taskListFragment?.themeColor?.setStatusBarColor(binding.drawerLayout)
}
})
handleIntent()
}
@ -138,7 +123,7 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
private fun clearUi() {
finishActionMode()
navigationDrawer.closeDrawer()
navigationDrawer?.closeDrawer()
}
private suspend fun getTaskToLoad(filter: Filter?): Task? {
@ -262,18 +247,16 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
}
private fun hideDetailFragment() {
filter?.let {
supportFragmentManager
.beginTransaction()
.replace(R.id.detail, newEmptyTaskEditFragment(it))
.runOnCommit {
if (isSinglePaneLayout) {
binding.master.visibility = View.VISIBLE
binding.detail.visibility = View.GONE
}
supportFragmentManager
.beginTransaction()
.replace(R.id.detail, newEmptyTaskEditFragment())
.runOnCommit {
if (isSinglePaneLayout) {
binding.master.visibility = View.VISIBLE
binding.detail.visibility = View.GONE
}
.commit()
}
}
.commit()
}
private fun setFilter(newFilter: Filter?) {
@ -298,7 +281,6 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
return
}
filter = newFilter
navigationDrawer.setSelected(filter)
defaultFilterProvider.lastViewedFilter = newFilter
applyTheme()
supportFragmentManager
@ -309,7 +291,6 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
private fun applyTheme() {
val filterColor = filterColor
filterColor.setStatusBarColor(binding.drawerLayout)
filterColor.applyToNavigationBar(this)
filterColor.applyTaskDescription(this, filter?.listingTitle ?: getString(R.string.app_name))
theme.withThemeColor(filterColor).applyToContext(this)
@ -318,9 +299,8 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
private val filterColor: ThemeColor
get() = if (filter != null && filter!!.tint != 0) colorProvider.getThemeColor(filter!!.tint, true) else theme.themeColor
private val navigationDrawerFragment: NavigationDrawerFragment
get() = supportFragmentManager
.findFragmentById(NavigationDrawerFragment.FRAGMENT_NAVIGATION_DRAWER) as NavigationDrawerFragment
private val navigationDrawer: NavigationDrawerFragment?
get() = supportFragmentManager.findFragmentByTag(FRAG_TAG_NAV_DRAWER) as? NavigationDrawerFragment
override fun onResume() {
super.onResume()
@ -365,7 +345,7 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
location.await(),
tags.await(),
alarms.await(),
filterColor)
)
}
supportFragmentManager.beginTransaction()
.replace(R.id.detail, fragment, TaskEditFragment.TAG_TASKEDIT_FRAGMENT)
@ -377,14 +357,10 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
override fun onNavigationIconClicked() {
hideKeyboard()
navigationDrawer.openDrawer()
newNavigationDrawer(filter).show(supportFragmentManager, FRAG_TAG_NAV_DRAWER)
}
override fun onBackPressed() {
if (navigationDrawer.isDrawerOpen) {
navigationDrawer.closeDrawer()
return
}
taskEditFragment?.let {
if (preferences.backButtonSavesTask()) {
lifecycleScope.launch {
@ -460,15 +436,6 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
override fun onSupportActionModeStarted(mode: ActionMode) {
super.onSupportActionModeStarted(mode)
actionMode = mode
val filterColor = filterColor
ActionUtils.applySupportActionModeColor(filterColor, mode)
filterColor.setStatusBarColor(this)
}
@SuppressLint("NewApi")
override fun onSupportActionModeFinished(mode: ActionMode) {
super.onSupportActionModeFinished(mode)
window.statusBarColor = 0
}
private fun finishActionMode() {
@ -495,6 +462,7 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
const val FINISH_AFFINITY = "finish_affinity"
private const val FRAG_TAG_TASK_LIST = "frag_tag_task_list"
private const val FRAG_TAG_WHATS_NEW = "frag_tag_whats_new"
private const val FRAG_TAG_NAV_DRAWER = "frag_tag_nav_drawer"
private const val EXTRA_FILTER = "extra_filter"
private const val FLAG_FROM_HISTORY
= Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY

@ -8,7 +8,6 @@ package com.todoroo.astrid.activity
import android.app.Activity
import android.content.Context
import android.graphics.Paint
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Bundle
import android.text.format.DateUtils
@ -22,7 +21,6 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback
@ -40,11 +38,14 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.Event
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.analytics.Firebase
import org.tasks.data.*
import org.tasks.data.Alarm
import org.tasks.data.Location
import org.tasks.data.TagData
import org.tasks.data.UserActivity
import org.tasks.data.UserActivityDao
import org.tasks.databinding.FragmentTaskEditBinding
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.dialogs.DialogBuilder
@ -55,7 +56,6 @@ import org.tasks.fragments.TaskEditControlSetFragmentManager
import org.tasks.markdown.MarkdownProvider
import org.tasks.notifications.NotificationManager
import org.tasks.preferences.Preferences
import org.tasks.themes.ThemeColor
import org.tasks.ui.SubtaskControlSet
import org.tasks.ui.TaskEditControlFragment
import org.tasks.ui.TaskEditViewModel
@ -95,9 +95,9 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
args.getParcelableArrayList(EXTRA_TAGS)!!,
args.getLongArray(EXTRA_ALARMS)!!)
val activity = requireActivity() as MainActivity
editViewModel.cleared.observe(activity, Observer<Event<Boolean>> {
editViewModel.cleared.observe(activity) {
activity.removeTaskEditFragment()
})
}
}
override fun onCreateView(
@ -105,7 +105,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
binding = FragmentTaskEditBinding.inflate(inflater)
val view: View = binding.root
val model = editViewModel.task!!
val themeColor: ThemeColor = requireArguments().getParcelable(EXTRA_THEME)!!
val toolbar = binding.toolbar
toolbar.navigationIcon = context.getDrawable(R.drawable.ic_outline_save_24px)
toolbar.setNavigationOnClickListener {
@ -141,7 +140,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
}
})
toolbar.setOnMenuItemClickListener(this)
themeColor.apply(binding.collapsingtoolbarlayout, toolbar)
val title = binding.title
val textWatcher = markdownProvider.markdown(linkifyEnabled).textWatcher(title)
title.addTextChangedListener(
@ -154,8 +152,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
)
title.setText(model.title)
title.setHorizontallyScrolling(false)
title.setTextColor(themeColor.colorOnPrimary)
title.setHintTextColor(themeColor.hintOnPrimary)
title.maxLines = 5
if (model.isNew || preferences.getBoolean(R.string.p_hide_check_button, false)) {
binding.fab.visibility = View.INVISIBLE
@ -175,9 +171,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
}
}
}
if (AndroidUtilities.atLeastQ()) {
title.verticalScrollbarThumbDrawable = ColorDrawable(themeColor.hintOnPrimary)
}
binding.appbarlayout.addOnOffsetChangedListener(
OnOffsetChangedListener { appBarLayout: AppBarLayout, verticalOffset: Int ->
if (verticalOffset == 0) {
@ -376,7 +369,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
private const val EXTRA_LOCATION = "extra_location"
private const val EXTRA_TAGS = "extra_tags"
private const val EXTRA_ALARMS = "extra_alarms"
private const val EXTRA_THEME = "extra_theme"
fun newTaskEditFragment(
task: Task,
@ -384,7 +376,7 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
location: Location?,
tags: ArrayList<TagData>,
alarms: ArrayList<Alarm>,
themeColor: ThemeColor?): TaskEditFragment {
): TaskEditFragment {
val taskEditFragment = TaskEditFragment()
val arguments = Bundle()
arguments.putParcelable(EXTRA_TASK, task)
@ -392,7 +384,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
arguments.putParcelable(EXTRA_LOCATION, location)
arguments.putParcelableArrayList(EXTRA_TAGS, tags)
arguments.putLongArray(EXTRA_ALARMS, alarms.map { it.time }.toLongArray())
arguments.putParcelable(EXTRA_THEME, themeColor)
taskEditFragment.arguments = arguments
return taskEditFragment
}

@ -29,6 +29,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.snackbar.Snackbar
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.andlib.utility.DateUtilities
@ -114,7 +115,6 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
private lateinit var emptyRefreshLayout: SwipeRefreshLayout
private lateinit var toolbar: Toolbar
private lateinit var coordinatorLayout: CoordinatorLayout
private lateinit var recyclerView: RecyclerView
@ -128,6 +128,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
private var mode: ActionMode? = null
lateinit var themeColor: ThemeColor
private lateinit var callbacks: TaskListFragmentCallbackHandler
private lateinit var binding: FragmentTaskListBinding
override fun onRefresh() {
syncAdapters.sync(true)
@ -170,14 +171,14 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding = FragmentTaskListBinding.inflate(inflater, container, false)
binding = FragmentTaskListBinding.inflate(inflater, container, false)
with (binding) {
swipeRefreshLayout = bodyStandard.swipeLayout
emptyRefreshLayout = bodyEmpty.swipeLayoutEmpty
this@TaskListFragment.toolbar = toolbar.toolbar
coordinatorLayout = taskListCoordinator
recyclerView = bodyStandard.recyclerView
fab.setOnClickListener { createNewTask() }
bottomAppBar.setNavigationOnClickListener { callbacks.onNavigationIconClicked() }
}
filter = getFilter()
themeColor = if (filter.tint != 0) colorProvider.getThemeColor(filter.tint, true) else defaultThemeColor
@ -204,11 +205,16 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
}
setupRefresh(swipeRefreshLayout)
setupRefresh(emptyRefreshLayout)
toolbar.title = filter.listingTitle
toolbar.setNavigationIcon(R.drawable.ic_outline_menu_24px)
toolbar.setNavigationOnClickListener { callbacks.onNavigationIconClicked() }
toolbar.setOnMenuItemClickListener(this)
setupMenu()
binding.toolbar.title = filter.listingTitle
binding.toolbar.navigationIcon = null
binding.bottomAppBar.setOnMenuItemClickListener(this)
binding.appbarlayout.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
if (verticalOffset == 0 && binding.bottomAppBar.isScrolledDown) {
binding.bottomAppBar.performShow()
}
})
setupBottomMenu()
search = binding.toolbar.menu.findItem(R.id.menu_search).setOnActionExpandListener(this)
return binding.root
}
@ -235,15 +241,16 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
taskAdapter.setDataSource(adapter)
}
private fun setupMenu() {
val menu = toolbar.menu
private fun setupBottomMenu() {
val menu = binding.bottomAppBar.menu
val bottomAppBar = binding.bottomAppBar
menu.clear()
if (filter.hasBeginningMenu()) {
toolbar.inflateMenu(filter.beginningMenu)
bottomAppBar.inflateMenu(filter.beginningMenu)
}
toolbar.inflateMenu(R.menu.menu_task_list_fragment)
bottomAppBar.inflateMenu(R.menu.menu_task_list_fragment_bottom)
if (filter.hasMenu()) {
toolbar.inflateMenu(filter.menu)
bottomAppBar.inflateMenu(filter.menu)
}
val hidden = menu.findItem(R.id.menu_show_unstarted)
val completed = menu.findItem(R.id.menu_show_completed)
@ -268,8 +275,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
menu.findItem(R.id.menu_expand_subtasks).isVisible = false
}
menu.findItem(R.id.menu_voice_add).isVisible = device.voiceInputAvailable()
search = menu.findItem(R.id.menu_search).setOnActionExpandListener(this)
themeColor.apply(toolbar)
themeColor.apply(bottomAppBar)
}
private fun openFilter(filter: Filter?) {
@ -564,10 +570,6 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
if (searchQuery == null) {
searchByQuery("")
}
val menu = toolbar.menu
for (i in 0 until menu.size()) {
menu.getItem(i).isVisible = false
}
return true
}
@ -576,7 +578,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
listViewModel.searchByFilter(filter)
searchJob?.cancel()
searchQuery = null
setupMenu()
setupBottomMenu()
return true
}
@ -598,7 +600,6 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL
override fun onCreateActionMode(actionMode: ActionMode, menu: Menu): Boolean {
val inflater = actionMode.menuInflater
inflater.inflate(R.menu.menu_multi_select, menu)
themeColor.colorMenu(menu)
return true
}

@ -148,8 +148,7 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic
.setTint(themeColor.primaryColor)
clear.visibility = View.VISIBLE
}
themeColor.apply(toolbar)
themeColor.applyToSystemBars(this)
themeColor.applyToNavigationBar(this)
var icon = getIconResId(selectedIcon)
if (icon == null) {
icon = getIconResId(CustomIcons.LIST)

@ -67,8 +67,7 @@ class NavigationDrawerCustomization : ThemedInjectingAppCompatActivity(), Toolba
inflateMenu(R.menu.menu_nav_drawer_customization)
}
themeColor.apply(toolbar)
themeColor.applyToSystemBars(this)
themeColor.applyToNavigationBar(this)
adapter.setOnClick(this::onClick)
binding.recyclerView.layoutManager = LinearLayoutManager(this)

@ -21,7 +21,6 @@ class AttributionActivity : ThemedInjectingAppCompatActivity() {
setTitle(R.string.third_party_licenses)
setNavigationIcon(R.drawable.ic_outline_arrow_back_24px)
setNavigationOnClickListener { finish() }
themeColor.apply(this)
}
viewModel.attributions.observe(this) {
binding.compose.setContent {

@ -89,7 +89,6 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
toolbar.inflateMenu(menuRes)
toolbar.setOnMenuItemClickListener(this)
toolbar.showOverflowMenu()
themeColor.apply(toolbar)
if (caldavAccount == null) {
toolbar.menu.findItem(R.id.remove).isVisible = false
binding.name.requestFocus()

@ -44,7 +44,6 @@ public final class TaskerCreateTaskActivity extends AbstractFragmentPluginAppCom
toolbar.setNavigationOnClickListener(v -> save());
toolbar.setOnMenuItemClickListener(this);
toolbar.inflateMenu(R.menu.menu_help);
themeColor.apply(toolbar);
if (savedInstanceState != null) {
previousBundle = savedInstanceState.getParcelable(TaskCreationBundle.EXTRA_BUNDLE);

@ -11,6 +11,7 @@ import androidx.activity.viewModels
import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.widget.ContentLoadingProgressBar
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
@ -90,6 +91,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
theme.applyTheme(this)
window.statusBarColor = ContextCompat.getColor(this, android.R.color.transparent)
val binding = ActivityLocationPickerBinding.inflate(layoutInflater)
setContentView(binding.root)
toolbar = binding.toolbar
@ -123,10 +125,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC
search.setOnActionExpandListener(this)
toolbar.setOnMenuItemClickListener(this)
val themeColor = theme.themeColor
themeColor.applyToStatusBarIcons(this)
themeColor.applyToNavigationBar(this)
themeColor.setStatusBarColor(toolbarLayout)
themeColor.apply(toolbar)
val dark = preferences.mapTheme == 2
|| preferences.mapTheme == 0 && theme.themeBase.isDarkTheme(this)
map.init(this, this, dark)

@ -46,7 +46,6 @@ abstract class BasePreferences : ThemedInjectingAppCompatActivity(),
getDrawable(R.drawable.ic_outline_arrow_back_24px)
toolbar.setNavigationOnClickListener { onBackPressed() }
toolbar.setOnMenuItemClickListener(this)
themeColor.apply(toolbar)
}
private fun setupMenu() = setupMenu(supportFragmentManager.findFragmentById(R.id.settings))

@ -55,9 +55,7 @@ class TagPickerActivity : ThemedInjectingAppCompatActivity() {
toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px)
toolbar.setNavigationOnClickListener { onBackPressed() }
val themeColor = theme.themeColor
themeColor.applyToStatusBarIcons(this)
themeColor.applyToNavigationBar(this)
themeColor.apply(toolbar)
val recyclerAdapter = TagRecyclerAdapter(this, viewModel, inventory, colorProvider) { tagData, vh ->
onToggle(tagData, vh)
}

@ -1,80 +0,0 @@
package org.tasks.tasklist;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.WindowDecorActionBar;
import androidx.appcompat.view.StandaloneActionMode;
import androidx.appcompat.widget.ActionBarContextView;
import java.lang.reflect.Field;
import org.tasks.R;
import org.tasks.themes.ThemeColor;
public class ActionUtils {
// cribbed from Twittnuker
public static void applySupportActionModeColor(
ThemeColor themeColor, final androidx.appcompat.view.ActionMode modeCompat) {
// Very dirty implementation
// This call ensures TitleView created
modeCompat.setTitle(modeCompat.getTitle());
View contextView = null;
if (modeCompat instanceof WindowDecorActionBar.ActionModeImpl) {
WindowDecorActionBar actionBar =
(WindowDecorActionBar)
findFieldOfTypes(
modeCompat,
WindowDecorActionBar.ActionModeImpl.class,
WindowDecorActionBar.class);
if (actionBar == null) {
return;
}
contextView =
(View)
findFieldOfTypes(actionBar, WindowDecorActionBar.class, ActionBarContextView.class);
} else if (modeCompat instanceof StandaloneActionMode) {
contextView =
(View)
findFieldOfTypes(modeCompat, StandaloneActionMode.class, ActionBarContextView.class);
}
if (!(contextView instanceof ActionBarContextView)) {
return;
}
contextView.setBackgroundColor(themeColor.getPrimaryColor());
TextView title = contextView.findViewById(R.id.action_bar_title);
if (title != null) {
title.setTextColor(themeColor.getColorOnPrimary());
}
ImageView closeButton = contextView.findViewById(R.id.action_mode_close_button);
if (closeButton != null) {
closeButton.setColorFilter(themeColor.getColorOnPrimary());
}
}
private static <T> Object findFieldOfTypes(
T obj, Class<? extends T> cls, Class<?>... checkTypes) {
labelField:
for (Field field : cls.getDeclaredFields()) {
field.setAccessible(true);
final Object fieldObj;
try {
fieldObj = field.get(obj);
} catch (Exception ignore) {
continue;
}
if (fieldObj != null) {
final Class<?> type = fieldObj.getClass();
for (Class<?> checkType : checkTypes) {
if (!checkType.isAssignableFrom(type)) {
continue labelField;
}
}
return fieldObj;
}
}
return null;
}
}

@ -19,7 +19,7 @@ class Theme @Inject constructor(
fun applyThemeAndStatusBarColor(activity: Activity) {
applyTheme(activity)
themeColor.applyToSystemBars(activity)
themeColor.applyToNavigationBar(activity)
themeColor.applyTaskDescription(activity, activity.getString(R.string.app_name))
}

@ -5,23 +5,20 @@ import static com.todoroo.andlib.utility.AndroidUtilities.atLeastOreo;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION_CODES;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import androidx.annotation.ColorInt;
import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.Toolbar;
import androidx.core.graphics.ColorUtils;
import androidx.core.os.ParcelCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.bottomappbar.BottomAppBar;
import org.tasks.R;
import org.tasks.dialogs.ColorPalettePicker.Pickable;
@ -163,7 +160,6 @@ public class ThemeColor implements Pickable {
private final int original;
private final int colorOnPrimary;
private final int hintOnPrimary;
private final int colorPrimary;
private final boolean isDark;
@ -184,10 +180,8 @@ public class ThemeColor implements Pickable {
isDark = contrast < 3;
if (isDark) {
colorOnPrimary = context.getColor(R.color.black_87);
hintOnPrimary = context.getColor(R.color.black_60);
} else {
colorOnPrimary = WHITE;
hintOnPrimary = context.getColor(R.color.white_60);
}
}
@ -196,73 +190,12 @@ public class ThemeColor implements Pickable {
colorPrimary = source.readInt();
isDark = ParcelCompat.readBoolean(source);
original = source.readInt();
hintOnPrimary = source.readInt();
}
public static ThemeColor getLauncherColor(Context context, int index) {
return new ThemeColor(context, context.getColor(LAUNCHER_COLORS[index]));
}
private static void colorMenu(Menu menu, int color) {
for (int i = 0, size = menu.size(); i < size; i++) {
final MenuItem menuItem = menu.getItem(i);
colorMenuItem(menuItem, color);
if (menuItem.hasSubMenu()) {
final SubMenu subMenu = menuItem.getSubMenu();
for (int j = 0; j < subMenu.size(); j++) {
colorMenuItem(subMenu.getItem(j), color);
}
}
}
}
private static void colorMenuItem(final MenuItem menuItem, final int color) {
colorDrawable(menuItem.getIcon(), color);
}
private static Drawable colorDrawable(Drawable drawable, int color) {
if (drawable != null) {
drawable.mutate();
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
return drawable;
}
public void applyToSystemBars(Activity activity) {
setStatusBarColor(activity);
applyToStatusBarIcons(activity);
applyToNavigationBar(activity);
}
public void setStatusBarColor(Activity activity) {
activity.getWindow().setStatusBarColor(colorPrimary);
}
public void setStatusBarColor(DrawerLayout drawerLayout) {
drawerLayout.setStatusBarBackgroundColor(colorPrimary);
org.tasks.extensions.View.INSTANCE.lightStatusBar(drawerLayout, isDark);
}
public void setStatusBarColor(CollapsingToolbarLayout layout) {
layout.setContentScrimColor(colorPrimary);
layout.setStatusBarScrimColor(colorPrimary);
}
public void apply(CollapsingToolbarLayout layout, Toolbar toolbar) {
setStatusBarColor(layout);
layout.setBackgroundColor(colorPrimary);
layout.setCollapsedTitleTextColor(colorOnPrimary);
layout.setExpandedTitleColor(colorOnPrimary);
toolbar.setNavigationIcon(colorDrawable(toolbar.getNavigationIcon(), colorOnPrimary));
colorMenu(toolbar.getMenu(), colorOnPrimary);
}
public void applyToStatusBarIcons(Activity activity) {
org.tasks.extensions.View.INSTANCE.lightStatusBar(activity.getWindow().getDecorView(), isDark);
}
public void applyToNavigationBar(Activity activity) {
activity.getWindow().setNavigationBarColor(getPrimaryColor());
@ -319,19 +252,12 @@ public class ThemeColor implements Pickable {
return colorOnPrimary;
}
public int getHintOnPrimary() {
return hintOnPrimary;
}
public boolean isDark() {
return isDark;
}
public void apply(Toolbar toolbar) {
toolbar.setBackgroundColor(getPrimaryColor());
toolbar.setNavigationIcon(colorDrawable(toolbar.getNavigationIcon(), colorOnPrimary));
toolbar.setTitleTextColor(colorOnPrimary);
colorMenu(toolbar.getMenu(), colorOnPrimary);
public void apply(BottomAppBar bottomAppBar) {
bottomAppBar.setBackgroundTint(ColorStateList.valueOf(getPrimaryColor()));
}
@Override
@ -345,11 +271,6 @@ public class ThemeColor implements Pickable {
dest.writeInt(colorPrimary);
ParcelCompat.writeBoolean(dest, isDark);
dest.writeInt(original);
dest.writeInt(hintOnPrimary);
}
public void colorMenu(Menu menu) {
colorMenu(menu, colorOnPrimary);
}
@Override

@ -5,46 +5,19 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.todoroo.astrid.api.Filter
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.databinding.FragmentTaskEditEmptyBinding
import org.tasks.themes.ColorProvider
import org.tasks.themes.ThemeColor
import javax.inject.Inject
@AndroidEntryPoint
class EmptyTaskEditFragment : Fragment() {
@Inject lateinit var themeColor: ThemeColor
@Inject lateinit var colorProvider: ColorProvider
companion object {
const val EXTRA_FILTER = "extra_filter"
fun newEmptyTaskEditFragment(filter: Filter): EmptyTaskEditFragment {
val arguments = Bundle()
arguments.putParcelable(EXTRA_FILTER, filter)
val fragment = EmptyTaskEditFragment()
fragment.arguments = arguments
return fragment
fun newEmptyTaskEditFragment(): EmptyTaskEditFragment {
return EmptyTaskEditFragment()
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
val binding = FragmentTaskEditEmptyBinding.inflate(inflater)
val tint = arguments?.getParcelable<Filter>(EXTRA_FILTER)?.tint
val color = colorProvider.getThemeColor(if (tint == null || tint == 0) {
themeColor.primaryColor
} else {
tint
})
color.apply(binding.toolbar.toolbar)
return binding.root
return FragmentTaskEditEmptyBinding.inflate(inflater).root
}
}

@ -1,21 +1,23 @@
package org.tasks.ui
import android.app.Activity
import android.app.Dialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.graphics.Rect
import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.drawerlayout.widget.DrawerLayout
import androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListener
import androidx.fragment.app.Fragment
import android.widget.FrameLayout
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.todoroo.astrid.adapter.NavigationDrawerAdapter
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.FilterListItem
@ -25,16 +27,15 @@ import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.billing.PurchaseActivity
import org.tasks.data.TaskDao
import org.tasks.dialogs.NewFilterDialog.Companion.newFilterDialog
import org.tasks.dialogs.NewFilterDialog
import org.tasks.extensions.Context.openUri
import org.tasks.extensions.View.lightStatusBar
import org.tasks.filters.FilterProvider
import org.tasks.filters.NavigationDrawerAction
import org.tasks.intents.TaskIntents
import javax.inject.Inject
@AndroidEntryPoint
class NavigationDrawerFragment : Fragment() {
class NavigationDrawerFragment : BottomSheetDialogFragment() {
private val refreshReceiver = RefreshReceiver()
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
@ -43,14 +44,26 @@ class NavigationDrawerFragment : Fragment() {
@Inject lateinit var taskDao: TaskDao
private lateinit var recyclerView: RecyclerView
private lateinit var mDrawerLayout: DrawerLayout
private var mFragmentContainerView: View? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
adapter.restore(savedInstanceState)
}
arguments?.getParcelable<Filter>(EXTRA_SELECTED)?.let {
adapter.setSelected(it)
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
dialog.setOnShowListener {
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
val bottomSheet = dialog.findViewById<FrameLayout>(com.google.android.material.R.id.design_bottom_sheet)
BottomSheetBehavior.from(bottomSheet!!).state = BottomSheetBehavior.STATE_HALF_EXPANDED
}
}
return dialog
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -64,8 +77,6 @@ class NavigationDrawerFragment : Fragment() {
val layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false)
recyclerView = layout.findViewById(R.id.recycler_view)
(recyclerView.itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
(layout.findViewById<View>(R.id.scrim_layout) as ScrimInsetsFrameLayout)
.setOnInsetsCallback { insets: Rect -> recyclerView.setPadding(0, insets.top, 0, 0) }
return layout
}
@ -76,46 +87,21 @@ class NavigationDrawerFragment : Fragment() {
}
private fun onFilterItemSelected(item: FilterListItem?) {
mDrawerLayout.addDrawerListener(
object : SimpleDrawerListener() {
override fun onDrawerClosed(drawerView: View) {
mDrawerLayout.removeDrawerListener(this)
if (item is Filter) {
activity?.startActivity(TaskIntents.getTaskListIntent(activity, item))
} else if (item is NavigationDrawerAction) {
when (item.requestCode) {
REQUEST_PURCHASE ->
startActivity(Intent(context, PurchaseActivity::class.java))
REQUEST_DONATE -> context?.openUri(R.string.url_donate)
REQUEST_NEW_FILTER -> newFilterDialog().show(parentFragmentManager, FRAG_TAG_NEW_FILTER)
else -> activity?.startActivityForResult(item.intent, item.requestCode)
}
}
}
})
close()
}
val isDrawerOpen: Boolean
get() = mDrawerLayout.isDrawerOpen(mFragmentContainerView!!)
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* @param drawerLayout The DrawerLayout containing this fragment's UI.
*/
fun setUp(drawerLayout: DrawerLayout) {
mFragmentContainerView = requireActivity().findViewById(FRAGMENT_NAVIGATION_DRAWER)
mDrawerLayout = drawerLayout
mDrawerLayout.addDrawerListener(object : SimpleDrawerListener() {
override fun onDrawerOpened(drawerView: View) {
setStatusBarColors()
if (item is Filter) {
activity?.startActivity(TaskIntents.getTaskListIntent(activity, item))
} else if (item is NavigationDrawerAction) {
when (item.requestCode) {
REQUEST_PURCHASE ->
startActivity(Intent(context, PurchaseActivity::class.java))
REQUEST_DONATE -> context?.openUri(R.string.url_donate)
REQUEST_NEW_FILTER -> NewFilterDialog.newFilterDialog()
.show(parentFragmentManager, FRAG_TAG_NEW_FILTER)
else -> activity?.startActivityForResult(item.intent, item.requestCode)
}
})
}
closeDrawer()
}
fun setSelected(selected: Filter?) = adapter.setSelected(selected)
override fun onPause() {
super.onPause()
localBroadcastManager.unregisterReceiver(refreshReceiver)
@ -127,26 +113,13 @@ class NavigationDrawerFragment : Fragment() {
}
fun closeDrawer() {
mDrawerLayout.setDrawerListener(null)
close()
dismiss()
}
private fun close() = mDrawerLayout.closeDrawer(mFragmentContainerView!!)
fun openDrawer() {
setStatusBarColors()
mDrawerLayout.openDrawer(mFragmentContainerView!!)
}
private fun setStatusBarColors() = mDrawerLayout.lightStatusBar(false)
override fun onResume() {
super.onResume()
localBroadcastManager.registerRefreshListReceiver(refreshReceiver)
updateFilters()
if (isDrawerOpen) {
setStatusBarColors()
}
}
private fun updateFilters() = lifecycleScope.launch {
@ -173,7 +146,6 @@ class NavigationDrawerFragment : Fragment() {
}
companion object {
const val FRAGMENT_NAVIGATION_DRAWER = R.id.navigation_drawer
const val REQUEST_NEW_LIST = 10100
const val REQUEST_SETTINGS = 10101
const val REQUEST_PURCHASE = 10102
@ -181,5 +153,14 @@ class NavigationDrawerFragment : Fragment() {
const val REQUEST_NEW_PLACE = 10104
const val REQUEST_NEW_FILTER = 101015
private const val FRAG_TAG_NEW_FILTER = "frag_tag_new_filter"
private const val EXTRA_SELECTED = "extra_selected"
fun newNavigationDrawer(selected: Filter?): NavigationDrawerFragment {
val fragment = NavigationDrawerFragment()
fragment.arguments = Bundle().apply {
putParcelable(EXTRA_SELECTED, selected)
}
return fragment
}
}
}

@ -1,141 +0,0 @@
/*
* Copyright 2014 Google Inc.
*
* 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 org.tasks.ui;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import org.tasks.R;
/**
* A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the
* area above UI chrome (status and navigation bars, overlay action bars).
*/
public class ScrimInsetsFrameLayout extends FrameLayout {
private final Rect mTempRect = new Rect();
private Drawable mInsetForeground;
private Rect mInsets;
private OnInsetsCallback mOnInsetsCallback;
public ScrimInsetsFrameLayout(Context context) {
super(context);
init(context, null, 0);
}
public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
final TypedArray a =
context.obtainStyledAttributes(attrs, R.styleable.ScrimInsetsFrameLayout, defStyle, 0);
if (a == null) {
return;
}
mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsFrameLayout_insetForeground);
a.recycle();
setWillNotDraw(true);
}
@Override
protected boolean fitSystemWindows(Rect insets) {
mInsets = new Rect(insets);
setWillNotDraw(mInsetForeground == null);
postInvalidateOnAnimation();
if (mOnInsetsCallback != null) {
mOnInsetsCallback.onInsetsChanged(insets);
}
return true; // consume insets
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
int width = getWidth();
int height = getHeight();
if (mInsets != null && mInsetForeground != null) {
int sc = canvas.save();
canvas.translate(getScrollX(), getScrollY());
// Top
mTempRect.set(0, 0, width, mInsets.top);
mInsetForeground.setBounds(mTempRect);
mInsetForeground.draw(canvas);
// Bottom
mTempRect.set(0, height - mInsets.bottom, width, height);
mInsetForeground.setBounds(mTempRect);
mInsetForeground.draw(canvas);
// Left
mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
mInsetForeground.setBounds(mTempRect);
mInsetForeground.draw(canvas);
// Right
mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
mInsetForeground.setBounds(mTempRect);
mInsetForeground.draw(canvas);
canvas.restoreToCount(sc);
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (mInsetForeground != null) {
mInsetForeground.setCallback(this);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mInsetForeground != null) {
mInsetForeground.setCallback(null);
}
}
/**
* Allows the calling container to specify a callback for custom processing when insets change
* (i.e. when {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI
* elements based on UI chrome insets (e.g. a Google Map or a ListView). When using with ListView
* or GridView, remember to set clipToPadding to false.
*/
public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
mOnInsetsCallback = onInsetsCallback;
}
public interface OnInsetsCallback {
void onInsetsChanged(Rect insets);
}
}

@ -121,8 +121,7 @@ class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPaletteP
val color = ThemeColor.getLauncherColor(this, themeIndex)
DrawableUtil.setLeftDrawable(this, colorIcon, R.drawable.color_picker)
DrawableUtil.setTint(DrawableUtil.getLeftDrawable(colorIcon), color.primaryColor)
color.apply(toolbar)
color.applyToSystemBars(this)
color.applyToNavigationBar(this)
}
private val themeIndex: Int

@ -1,9 +1,9 @@
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
@ -29,7 +29,5 @@
</LinearLayout>
<include layout="@layout/navigation_drawer"/>
</androidx.drawerlayout.widget.DrawerLayout>
</LinearLayout>

@ -19,7 +19,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:theme="@style/ToolbarTheme"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:contentScrim="@color/content_background"
app:statusBarScrim="@color/content_background"
app:titleEnabled="false">
<androidx.constraintlayout.widget.ConstraintLayout
@ -136,7 +139,7 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="?attr/overlay_theme"
android:theme="@style/ToolbarTheme"
app:layout_collapseMode="pin"
app:popupTheme="@style/popup_overlay"
app:title="@string/choose_a_location"/>

@ -11,12 +11,11 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="@dimen/elevation_toolbar"
android:theme="?attr/overlay_theme"
android:theme="@style/ToolbarTheme"
android:background="@color/content_background"
app:popupTheme="@style/popup_overlay"
app:titleTextColor="?attr/colorOnPrimary"
app:toolbarStyle="@style/Widget.MaterialComponents.Toolbar"
app:titleTextColor="@color/text_primary"
tools:ignore="UnusedAttribute">
<EditText
@ -30,8 +29,8 @@
android:lines="1"
android:maxLines="1"
android:scrollbars="vertical"
android:textColor="?attr/colorOnPrimary"
android:textColorHint="?attr/colorOnPrimaryHint" />
android:textColor="@color/text_primary"
android:textColorHint="@color/text_secondary" />
</androidx.appcompat.widget.Toolbar>

@ -1,7 +1,6 @@
<org.tasks.ui.ScrimInsetsFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout 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/scrim_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/drawer_color"
@ -15,4 +14,4 @@
android:scrollbars="vertical"
tools:context=".NavigationDrawerFragment"/>
</org.tasks.ui.ScrimInsetsFrameLayout>
</FrameLayout>

@ -18,6 +18,7 @@
android:id="@+id/collapsingtoolbarlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/content_background"
app:collapsedTitleTextAppearance="?attr/textAppearanceHeadline6"
app:expandedTitleGravity="top"
app:expandedTitleMarginTop="?attr/actionBarSize"
@ -49,11 +50,11 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="@dimen/elevation_toolbar"
android:theme="@style/ToolbarTheme"
app:layout_collapseMode="pin"
android:theme="?attr/overlay_theme"
app:popupTheme="@style/popup_overlay"
app:titleTextColor="?attr/colorOnPrimary"
app:navigationIconTint="@color/text_primary"
app:toolbarStyle="@style/Widget.MaterialComponents.Toolbar"
app:popupTheme="@style/popup_overlay"
tools:ignore="UnusedAttribute" />
</com.google.android.material.appbar.CollapsingToolbarLayout>

@ -5,6 +5,7 @@
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/task_list_coordinator"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
@ -13,14 +14,30 @@
android:focusableInTouchMode="true"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbarlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="@dimen/elevation_app_bar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_gravity="top"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/content_background"
android:theme="@style/ToolbarTheme"
app:hideOnScroll="true"
app:layout_scrollFlags="scroll|enterAlways"
app:menu="@menu/menu_task_list_fragment_top"
tools:ignore="UnusedAttribute" />
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<LinearLayout
android:layout_width="match_parent"
@ -49,16 +66,27 @@
</LinearLayout>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@+id/bottomAppBar"
style="@style/Widget.MaterialComponents.BottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:theme="?attr/overlay_theme"
app:popupTheme="@style/popup_overlay"
app:hideOnScroll="true"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIcon="@drawable/ic_outline_menu_24px" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/keyline_first"
android:layout_gravity="end|bottom"
android:padding="0dp"
android:src="@drawable/ic_outline_add_24px"
android:contentDescription="@string/action_create_new_task"
app:backgroundTint="?attr/colorAccent"
app:borderWidth="0dp"/>
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/action_create_new_task"
app:backgroundTint="?attr/colorAccent"
app:layout_anchor="@id/bottomAppBar"
app:hideOnScroll="true"
app:layout_scrollFlags="scroll|enterAlways"
app:srcCompat="@drawable/ic_outline_add_24px" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

@ -1,10 +0,0 @@
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation_drawer"
android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:name="org.tasks.ui.NavigationDrawerFragment"
tools:layout="@layout/fragment_navigation_drawer"/>

@ -1,25 +1,22 @@
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout
android:id="@+id/master"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="InconsistentLayout"/>
<FrameLayout
android:id="@+id/detail"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:ignore="InconsistentLayout"/>
android:orientation="vertical">
<FrameLayout
android:id="@+id/master"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="InconsistentLayout" />
<include layout="@layout/navigation_drawer"/>
<FrameLayout
android:id="@+id/detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:ignore="InconsistentLayout" />
</androidx.drawerlayout.widget.DrawerLayout>
</LinearLayout>

@ -5,8 +5,7 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="@dimen/elevation_toolbar"
android:theme="?attr/overlay_theme"
app:popupTheme="@style/popup_overlay"
app:titleTextColor="?attr/colorOnPrimary"
app:toolbarStyle="@style/Widget.MaterialComponents.Toolbar"
android:theme="@style/ToolbarTheme"
android:background="@color/content_background"
app:titleTextColor="?attr/colorOnSurface"
tools:ignore="UnusedAttribute" />

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_voice_add"
android:icon="@drawable/ic_outline_mic_none_24px"
android:title="@string/EPr_voiceInputEnabled_title"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_search"
android:icon="@drawable/ic_outline_search_24px"
android:title="@string/TLA_menu_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/>
<item
android:id="@+id/menu_sort"
android:icon="@drawable/ic_outline_sort_24px"
android:title="@string/TLA_menu_sort"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_share"
android:icon="@drawable/ic_outline_send_24px"
android:title="@string/share"
app:showAsAction="ifRoom" />
<group
android:checkableBehavior="all">
<item
android:id="@+id/menu_show_unstarted"
android:checkable="true"
android:title="@string/show_unstarted"/>
<item
android:id="@+id/menu_show_completed"
android:checkable="true"
android:title="@string/show_completed"/>
</group>
<item
android:id="@+id/menu_expand_subtasks"
android:title="@string/expand_subtasks"
app:showAsAction="never" />
<item
android:id="@+id/menu_collapse_subtasks"
android:title="@string/collapse_subtasks"
app:showAsAction="never" />
<item
android:id="@+id/menu_clear_completed"
android:title="@string/gtasks_GTA_clear_completed"
app:showAsAction="never"/>
</menu>

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_clear_completed"
android:title="@string/gtasks_GTA_clear_completed"
app:showAsAction="never" />
<item
android:id="@+id/menu_collapse_subtasks"
android:title="@string/collapse_subtasks"
app:showAsAction="never" />
<item
android:id="@+id/menu_expand_subtasks"
android:title="@string/expand_subtasks"
app:showAsAction="never" />
<group android:checkableBehavior="all">
<item
android:id="@+id/menu_show_completed"
android:checkable="true"
android:title="@string/show_completed" />
<item
android:id="@+id/menu_show_unstarted"
android:checkable="true"
android:title="@string/show_unstarted" />
</group>
<item
android:id="@+id/menu_share"
android:icon="@drawable/ic_outline_send_24px"
android:title="@string/share" />
<item
android:id="@+id/menu_voice_add"
android:icon="@drawable/ic_outline_mic_none_24px"
android:title="@string/EPr_voiceInputEnabled_title"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_sort"
android:icon="@drawable/ic_outline_sort_24px"
android:title="@string/TLA_menu_sort"
app:showAsAction="ifRoom" />
</menu>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_search"
android:icon="@drawable/ic_outline_search_24px"
android:title="@string/TLA_menu_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/>
</menu>

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="is_dark">true</bool>
<bool name="light_status_bar">false</bool>
</resources>

@ -6,4 +6,11 @@
<style name="DayNightAlert" parent="ThemeOverlay.MaterialComponents.Dialog.Alert"/>
<style name="popup_overlay" parent="ThemeOverlay.MaterialComponents"/>
<style name="ToolbarTheme" parent="@style/ThemeOverlay.MaterialComponents.Dark">
<item name="toolbarNavigationButtonStyle">@style/WhiteNavigation</item>
<item name="iconTint">@color/text_primary</item>
<item name="android:actionOverflowButtonStyle">@style/WhiteOverflow</item>
</style>
</resources>

@ -15,8 +15,4 @@
<attr format="string" name="time_summary"/>
</declare-styleable>
<declare-styleable name="ScrimInsetsFrameLayout">
<attr format="reference|color" name="insetForeground"/>
</declare-styleable>
</resources>

@ -3,5 +3,6 @@
<bool name="two_pane_layout">false</bool>
<bool name="default_bundle_notifications">true</bool>
<bool name="is_dark">false</bool>
<bool name="light_status_bar">true</bool>
<bool name="whats_new_action">false</bool>
</resources>

@ -31,18 +31,28 @@
<item name="android:textSize">@dimen/task_edit_text_size</item>
</style>
<style name="ToolbarTheme" parent="ThemeOverlay.MaterialComponents.Light">
<item name="toolbarNavigationButtonStyle">@style/BlackNavigation</item>
<item name="iconTint">@color/text_primary</item>
<item name="android:actionOverflowButtonStyle">@style/BlackOverflow</item>
</style>
<style name="WhiteToolbarTheme">
<item name="overlay_theme">@style/WhiteToolbarOverlay</item>
<item name="iconTint">@color/white_100</item>
<item name="colorOnPrimary">@color/white_100</item>
<item name="colorOnPrimaryHint">@color/white_60</item>
<item name="android:actionOverflowButtonStyle">@style/WhiteOverflow</item>
<item name="toolbarNavigationButtonStyle">@style/WhiteNavigation</item>
</style>
<style name="BlackToolbarTheme">
<item name="overlay_theme">@style/BlackToolbarOverlay</item>
<item name="iconTint">@color/black_87</item>
<item name="colorOnPrimary">@color/black_87</item>
<item name="colorOnPrimaryHint">@color/black_60</item>
<item name="android:actionOverflowButtonStyle">@style/BlackOverflow</item>
<item name="toolbarNavigationButtonStyle">@style/BlackNavigation</item>
</style>
<style name="WhiteTint">
@ -53,10 +63,40 @@
<item name="colorOnSecondary">@color/black_87</item>
</style>
<style name="WhiteNavigation" parent="Widget.AppCompat.Toolbar.Button.Navigation">
<item name="android:tint">@color/white_100</item>
</style>
<style name="WhiteOverflow" parent="Widget.AppCompat.Light.ActionButton.Overflow">
<item name="android:tint">@color/white_100</item>
</style>
<style name="ActionModeStyle" parent="Widget.AppCompat.ActionMode">
<item name="background">@color/content_background</item>
<item name="titleTextStyle">@style/ActionModeTitleTextStyle</item>
</style>
<style name="ActionModeTitleTextStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionMode.Title">
<item name="android:textColor">@color/text_primary</item>
</style>
<style name="ActionModeTheme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<item name="iconTint">@color/text_primary</item>
<item name="android:actionOverflowButtonStyle">@style/ActionModeOverflowButton</item>
</style>
<style name="ActionModeOverflowButton" parent="Widget.AppCompat.Light.ActionButton.Overflow">
<item name="android:tint">@color/text_primary</item>
</style>
<style name="ActionModeCloseButton" parent="Widget.AppCompat.ActionButton.CloseMode">
<item name="android:tint">@color/text_primary</item>
</style>
<style name="BlackNavigation" parent="Widget.AppCompat.Toolbar.Button.Navigation">
<item name="android:tint">@color/black_100</item>
</style>
<style name="BlackOverflow" parent="Widget.AppCompat.Light.ActionButton.Overflow">
<item name="android:tint">@color/black_100</item>
</style>

@ -11,6 +11,10 @@
<item name="android:windowBackground">@color/window_background</item>
<item name="android:colorBackground">@color/content_background</item>
<item name="windowActionModeOverlay">true</item>
<item name="actionModeStyle">@style/ActionModeStyle</item>
<item name="actionBarTheme">@style/ActionModeTheme</item>
<item name="actionModeCloseButtonStyle">@style/ActionModeCloseButton</item>
<item name="actionModeCloseDrawable">@drawable/ic_outline_arrow_back_24px</item>
<item name="android:spinnerItemStyle">@style/SpinnerNoPadding</item>
<item name="dialogTheme">@style/TasksDialog</item>
<item name="android:dialogTheme">@style/TasksDialog</item>
@ -28,7 +32,8 @@
<style name="Tasks" parent="TasksBase">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowLightStatusBar">@bool/light_status_bar</item>
<item name="android:statusBarColor">@color/content_background</item>
</style>
<style name="TasksDialogAlert" parent="DayNightAlert">

Loading…
Cancel
Save