From 2fc38d008945888519bb11f00dcb90e922f0372e Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Fri, 26 Mar 2021 12:41:03 -0500 Subject: [PATCH] Remove ButterKnife --- app/build.gradle.kts | 4 - app/licenses.yml | 18 -- app/proguard.pro | 6 - app/src/main/assets/licenses.json | 42 ----- .../astrid/activity/BeastModePreferences.java | 32 ++-- .../astrid/activity/TaskListFragment.kt | 39 ++-- .../astrid/adapter/ActionViewHolder.kt | 21 +-- .../astrid/adapter/FilterViewHolder.kt | 30 ++- .../astrid/adapter/SubheaderViewHolder.kt | 20 +- .../astrid/core/CriterionViewHolder.kt | 35 ++-- .../todoroo/astrid/files/FilesControlSet.kt | 23 ++- .../astrid/repeats/RepeatControlSet.kt | 32 ++-- .../com/todoroo/astrid/tags/TagsControlSet.kt | 17 +- .../todoroo/astrid/timers/TimerControlSet.kt | 27 +-- .../todoroo/astrid/ui/ReminderControlSet.kt | 29 +-- .../todoroo/astrid/ui/StartDateControlSet.kt | 12 +- .../activities/BaseListSettingsActivity.kt | 45 +++-- .../activities/FilterSettingsActivity.kt | 50 ++--- .../GoogleTaskListSettingsActivity.kt | 18 +- .../tasks/activities/PlaceSettingsActivity.kt | 24 +-- .../tasks/activities/TagSettingsActivity.kt | 27 ++- .../attribution/AttributionActivity.kt | 2 - .../BaseCaldavAccountSettingsActivity.kt | 41 ++--- .../BaseCaldavCalendarSettingsActivity.kt | 37 ++-- .../caldav/CaldavCalendarSettingsActivity.kt | 2 - .../tasks/caldav/LocalListSettingsActivity.kt | 3 - .../org/tasks/dialogs/ColorPalettePicker.kt | 18 +- .../org/tasks/dialogs/ColorPickerAdapter.kt | 11 +- .../java/org/tasks/dialogs/DateTimePicker.kt | 83 ++++----- .../org/tasks/dialogs/GeofenceDialog.java | 32 ++-- .../org/tasks/dialogs/IconPickerAdapter.java | 5 +- .../org/tasks/dialogs/IconPickerDialog.java | 21 +-- .../org/tasks/dialogs/IconPickerHolder.java | 22 +-- .../org/tasks/dialogs/RecordAudioDialog.java | 35 ++-- .../java/org/tasks/dialogs/StartDatePicker.kt | 70 +++---- .../etebase/EtebaseAccountSettingsActivity.kt | 9 +- .../etesync/EncryptionSettingsActivity.kt | 16 +- .../etesync/EteSyncAccountSettingsActivity.kt | 7 +- .../org/tasks/fragments/CommentBarFragment.kt | 52 +++--- .../tasks/location/LocationPickerActivity.kt | 61 +++---- .../OpenTasksListSettingsActivity.kt | 5 - .../beast/BeastModeRecyclerAdapter.java | 15 +- .../beast/BeastModeViewHolder.java | 21 +-- .../tasks/repeats/CustomRecurrenceDialog.java | 172 +++++++++--------- .../java/org/tasks/tags/TagPickerActivity.kt | 31 ++-- .../org/tasks/tags/TagPickerViewHolder.kt | 32 ++-- .../java/org/tasks/tags/TagRecyclerAdapter.kt | 11 +- .../org/tasks/tasklist/SubtaskViewHolder.java | 51 +++--- .../tasklist/SubtasksRecyclerAdapter.java | 18 +- .../java/org/tasks/tasklist/TaskViewHolder.kt | 91 ++++----- .../org/tasks/tasklist/ViewHolderFactory.kt | 3 +- .../java/org/tasks/ui/CalendarControlSet.kt | 27 +-- .../java/org/tasks/ui/DeadlineControlSet.kt | 13 +- .../org/tasks/ui/DescriptionControlSet.kt | 23 ++- .../main/java/org/tasks/ui/ListFragment.kt | 13 +- .../java/org/tasks/ui/LocationControlSet.kt | 28 +-- .../main/java/org/tasks/ui/OnItemSelected.kt | 12 ++ .../main/java/org/tasks/ui/OnTextChanged.kt | 13 ++ .../java/org/tasks/ui/PriorityControlSet.kt | 39 ++-- .../java/org/tasks/ui/SubtaskControlSet.kt | 21 ++- .../org/tasks/ui/TaskEditControlFragment.kt | 6 +- .../tasks/widget/ShortcutConfigActivity.kt | 48 +++-- .../activity_caldav_calendar_settings.xml | 4 +- .../activity_google_task_list_settings.xml | 4 +- .../activity_widget_shortcut_content.xml | 4 +- .../activity_widget_shortcut_layout.xml | 8 +- .../res/layout/beast_mode_pref_activity.xml | 4 +- .../res/layout/control_set_gcal_display.xml | 4 +- .../main/res/layout/fragment_task_list.xml | 12 +- .../main/res/layout/list_settings_color.xml | 4 +- app/src/main/res/layout/week_day_button.xml | 1 + buildSrc/src/main/kotlin/Versions.kt | 1 - deps_fdroid.txt | 5 - deps_googleplay.txt | 5 - 74 files changed, 867 insertions(+), 960 deletions(-) create mode 100644 app/src/main/java/org/tasks/ui/OnItemSelected.kt create mode 100644 app/src/main/java/org/tasks/ui/OnTextChanged.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index af579b729..b47d5c3e2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -188,9 +188,6 @@ dependencies { implementation("androidx.paging:paging-runtime:2.1.2") implementation("io.noties.markwon:core:${Versions.markwon}") - kapt("com.jakewharton:butterknife-compiler:${Versions.butterknife}") - implementation("com.jakewharton:butterknife:${Versions.butterknife}") - debugImplementation("com.facebook.flipper:flipper:${Versions.flipper}") debugImplementation("com.facebook.flipper:flipper-network-plugin:${Versions.flipper}") debugImplementation("com.facebook.soloader:soloader:0.10.1") @@ -246,7 +243,6 @@ dependencies { androidTestImplementation("com.google.dagger:hilt-android-testing:${Versions.hilt}") kaptAndroidTest("com.google.dagger:hilt-compiler:${Versions.hilt}") kaptAndroidTest("androidx.hilt:hilt-compiler:${Versions.hilt_androidx}") - kaptAndroidTest("com.jakewharton:butterknife-compiler:${Versions.butterknife}") androidTestImplementation("org.mockito:mockito-android:${Versions.mockito}") androidTestImplementation("com.natpryce:make-it-easy:${Versions.make_it_easy}") androidTestImplementation("androidx.test:runner:${Versions.androidx_test}") diff --git a/app/licenses.yml b/app/licenses.yml index 8f6055185..9a2b10ece 100644 --- a/app/licenses.yml +++ b/app/licenses.yml @@ -383,18 +383,6 @@ license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt url: https://kotlinlang.org/ -- artifact: com.jakewharton:butterknife:+ - name: ButterKnife - copyrightHolder: Jake Wharton - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://github.com/JakeWharton/butterknife/ -- artifact: com.jakewharton:butterknife-annotations:+ - name: ButterKnife Annotations - copyrightHolder: Jake Wharton - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://github.com/JakeWharton/butterknife/ - artifact: com.squareup.okhttp3:logging-interceptor:+ name: OkHttp Logging Interceptor copyrightHolder: Square, Inc. @@ -406,12 +394,6 @@ license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt url: https://kotlinlang.org/ -- artifact: com.jakewharton:butterknife-runtime:+ - name: ButterKnife Runtime - copyrightHolder: Jake Wharton - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://github.com/JakeWharton/butterknife/ - artifact: io.grpc:grpc-context:+ name: io.grpc:grpc-context copyrightHolder: The gRPC Authors diff --git a/app/proguard.pro b/app/proguard.pro index b1f023d43..488e2c102 100644 --- a/app/proguard.pro +++ b/app/proguard.pro @@ -9,12 +9,6 @@ public static *** i(...); } -# https://github.com/JakeWharton/butterknife/blob/581666a28022796fdd62caaf3420e621215abfda/butterknife/proguard-rules.txt --keep public class * implements butterknife.Unbinder { public (**, android.view.View); } --keep class butterknife.* --keepclasseswithmembernames class * { @butterknife.* ; } --keepclasseswithmembernames class * { @butterknife.* ; } - # guava -dontwarn sun.misc.Unsafe -dontwarn java.lang.ClassValue diff --git a/app/src/main/assets/licenses.json b/app/src/main/assets/licenses.json index b0368dcbd..899bbb0f0 100644 --- a/app/src/main/assets/licenses.json +++ b/app/src/main/assets/licenses.json @@ -912,34 +912,6 @@ "url": "https://kotlinlang.org/", "libraryName": "org.jetbrains.kotlin:kotlin-stdlib-common" }, - { - "artifactId": { - "name": "butterknife", - "group": "com.jakewharton", - "version": "+" - }, - "copyrightHolder": "Jake Wharton", - "copyrightStatement": "Copyright © Jake Wharton. All rights reserved.", - "license": "The Apache Software License, Version 2.0", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt", - "normalizedLicense": "apache2", - "url": "https://github.com/JakeWharton/butterknife/", - "libraryName": "ButterKnife" - }, - { - "artifactId": { - "name": "butterknife-annotations", - "group": "com.jakewharton", - "version": "+" - }, - "copyrightHolder": "Jake Wharton", - "copyrightStatement": "Copyright © Jake Wharton. All rights reserved.", - "license": "The Apache Software License, Version 2.0", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt", - "normalizedLicense": "apache2", - "url": "https://github.com/JakeWharton/butterknife/", - "libraryName": "ButterKnife Annotations" - }, { "artifactId": { "name": "logging-interceptor", @@ -967,20 +939,6 @@ "url": "https://kotlinlang.org/", "libraryName": "org.jetbrains.kotlin:kotlin-stdlib-jdk7" }, - { - "artifactId": { - "name": "butterknife-runtime", - "group": "com.jakewharton", - "version": "+" - }, - "copyrightHolder": "Jake Wharton", - "copyrightStatement": "Copyright © Jake Wharton. All rights reserved.", - "license": "The Apache Software License, Version 2.0", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt", - "normalizedLicense": "apache2", - "url": "https://github.com/JakeWharton/butterknife/", - "libraryName": "ButterKnife Runtime" - }, { "artifactId": { "name": "grpc-context", diff --git a/app/src/main/java/com/todoroo/astrid/activity/BeastModePreferences.java b/app/src/main/java/com/todoroo/astrid/activity/BeastModePreferences.java index cf452aa9b..3642fd2e6 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/BeastModePreferences.java +++ b/app/src/main/java/com/todoroo/astrid/activity/BeastModePreferences.java @@ -6,27 +6,31 @@ package com.todoroo.astrid.activity; -import static java.util.Arrays.asList; import static org.tasks.Strings.isNullOrEmpty; +import static java.util.Arrays.asList; import android.content.Context; import android.os.Bundle; import android.view.MenuItem; + import androidx.appcompat.widget.Toolbar; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import butterknife.BindView; -import butterknife.ButterKnife; -import dagger.hilt.android.AndroidEntryPoint; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import javax.inject.Inject; + import org.tasks.R; +import org.tasks.databinding.BeastModePrefActivityBinding; import org.tasks.injection.ThemedInjectingAppCompatActivity; import org.tasks.preferences.Preferences; import org.tasks.preferences.beast.BeastModeRecyclerAdapter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.inject.Inject; + +import dagger.hilt.android.AndroidEntryPoint; + @AndroidEntryPoint public class BeastModePreferences extends ThemedInjectingAppCompatActivity implements Toolbar.OnMenuItemClickListener { @@ -34,12 +38,6 @@ public class BeastModePreferences extends ThemedInjectingAppCompatActivity private static final String BEAST_MODE_ORDER_PREF = "beast_mode_order_v6"; // $NON-NLS-1$ private static final String BEAST_MODE_PREF_ITEM_SEPARATOR = ";"; - @BindView(R.id.toolbar) - Toolbar toolbar; - - @BindView(R.id.recycler_view) - RecyclerView recyclerView; - @Inject Preferences preferences; private BeastModeRecyclerAdapter adapter; @@ -87,8 +85,10 @@ public class BeastModePreferences extends ThemedInjectingAppCompatActivity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.beast_mode_pref_activity); - ButterKnife.bind(this); + BeastModePrefActivityBinding binding = BeastModePrefActivityBinding.inflate(getLayoutInflater()); + Toolbar toolbar = binding.toolbar.toolbar; + RecyclerView recyclerView = binding.recyclerView; + setContentView(binding.getRoot()); toolbar.setNavigationIcon( getDrawable(R.drawable.ic_outline_arrow_back_24px)); diff --git a/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt b/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt index 809ea2e11..3b2b99141 100644 --- a/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt +++ b/app/src/main/java/com/todoroo/astrid/activity/TaskListFragment.kt @@ -28,9 +28,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener -import butterknife.BindView -import butterknife.ButterKnife -import butterknife.OnClick import com.google.android.material.snackbar.Snackbar import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.DateUtilities @@ -61,6 +58,7 @@ import org.tasks.caldav.BaseCaldavCalendarSettingsActivity import org.tasks.data.CaldavDao import org.tasks.data.TagDataDao import org.tasks.data.TaskContainer +import org.tasks.databinding.FragmentTaskListBinding import org.tasks.db.SuspendDbUtils.chunkedMap import org.tasks.dialogs.DateTimePicker.Companion.newDateTimePicker import org.tasks.dialogs.DialogBuilder @@ -118,20 +116,11 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL @Inject lateinit var locale: Locale @Inject lateinit var firebase: Firebase - @BindView(R.id.swipe_layout) - lateinit var swipeRefreshLayout: SwipeRefreshLayout - - @BindView(R.id.swipe_layout_empty) - lateinit var emptyRefreshLayout: SwipeRefreshLayout - - @BindView(R.id.toolbar) - lateinit var toolbar: Toolbar - - @BindView(R.id.task_list_coordinator) - lateinit var coordinatorLayout: CoordinatorLayout - - @BindView(R.id.recycler_view) - lateinit var recyclerView: RecyclerView + 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 private val listViewModel: TaskListViewModel by viewModels() private lateinit var taskAdapter: TaskAdapter @@ -186,8 +175,15 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val parent = inflater.inflate(R.layout.fragment_task_list, container, false) - ButterKnife.bind(this, parent) + val 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() } + } filter = getFilter() themeColor = if (filter.tint != 0) colorProvider.getThemeColor(filter.tint, true) else defaultThemeColor filter.setFilterQueryOverride(null) @@ -218,7 +214,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL toolbar.setNavigationOnClickListener { callbacks.onNavigationIconClicked() } toolbar.setOnMenuItemClickListener(this) setupMenu() - return parent + return binding.root } private fun submitList(tasks: List) { @@ -423,8 +419,7 @@ class TaskListFragment : Fragment(), OnRefreshListener, Toolbar.OnMenuItemClickL context?.toast(R.string.delete_multiple_tasks_confirmation, locale.formatNumber(count)) } - @OnClick(R.id.fab) - fun createNewTask() { + private fun createNewTask() { lifecycleScope.launch { shortcutManager.reportShortcutUsed(ShortcutManager.SHORTCUT_NEW_TASK) onTaskListItemClicked(addTask("")) diff --git a/app/src/main/java/com/todoroo/astrid/adapter/ActionViewHolder.kt b/app/src/main/java/com/todoroo/astrid/adapter/ActionViewHolder.kt index af787264e..fc1bc350d 100644 --- a/app/src/main/java/com/todoroo/astrid/adapter/ActionViewHolder.kt +++ b/app/src/main/java/com/todoroo/astrid/adapter/ActionViewHolder.kt @@ -5,10 +5,8 @@ import android.view.View import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import com.todoroo.astrid.api.FilterListItem -import org.tasks.R +import org.tasks.databinding.FilterAdapterActionBinding import org.tasks.themes.DrawableUtil class ActionViewHolder internal constructor( @@ -16,17 +14,16 @@ class ActionViewHolder internal constructor( itemView: View, private val onClick: ((FilterListItem?) -> Unit)?) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.row) - lateinit var row: View - - @BindView(R.id.text) - lateinit var text: TextView - - @BindView(R.id.icon) - lateinit var icon: ImageView + private val row: View + private val text: TextView + private val icon: ImageView init { - ButterKnife.bind(this, itemView) + FilterAdapterActionBinding.bind(itemView).let { + row = it.row + text = it.text + icon = it.icon + } } fun bind(filter: FilterListItem) { diff --git a/app/src/main/java/com/todoroo/astrid/adapter/FilterViewHolder.kt b/app/src/main/java/com/todoroo/astrid/adapter/FilterViewHolder.kt index 8e38c7847..9a2bc6fa6 100644 --- a/app/src/main/java/com/todoroo/astrid/adapter/FilterViewHolder.kt +++ b/app/src/main/java/com/todoroo/astrid/adapter/FilterViewHolder.kt @@ -7,8 +7,6 @@ import android.widget.ImageView import android.widget.TextView import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import com.todoroo.astrid.api.CaldavFilter import com.todoroo.astrid.api.CustomFilter import com.todoroo.astrid.api.FilterListItem @@ -16,6 +14,7 @@ import com.todoroo.astrid.api.GtasksFilter import com.todoroo.astrid.api.TagFilter import org.tasks.R import org.tasks.billing.Inventory +import org.tasks.databinding.FilterAdapterRowBinding import org.tasks.filters.PlaceFilter import org.tasks.locale.Locale import org.tasks.themes.ColorProvider @@ -31,25 +30,22 @@ class FilterViewHolder internal constructor( private val colorProvider: ColorProvider, private val onClick: ((FilterListItem?) -> Unit)?) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.row) - lateinit var row: View - - @BindView(R.id.text) - lateinit var text: CheckedTextView - - @BindView(R.id.icon) - lateinit var icon: ImageView - - @BindView(R.id.size) - lateinit var size: TextView - - @BindView(R.id.share_indicator) - lateinit var shareIndicator: ImageView + private val row: View + private val text: CheckedTextView + private val icon: ImageView + private val size: TextView + private val shareIndicator: ImageView lateinit var filter: FilterListItem init { - ButterKnife.bind(this, itemView) + FilterAdapterRowBinding.bind(itemView).let { + row = it.row + text = it.text + icon = it.icon + size = it.size + shareIndicator = it.shareIndicator + } if (navigationDrawer) { text.checkMarkDrawable = null } diff --git a/app/src/main/java/com/todoroo/astrid/adapter/SubheaderViewHolder.kt b/app/src/main/java/com/todoroo/astrid/adapter/SubheaderViewHolder.kt index 9ecf45c02..5f58b8e2c 100644 --- a/app/src/main/java/com/todoroo/astrid/adapter/SubheaderViewHolder.kt +++ b/app/src/main/java/com/todoroo/astrid/adapter/SubheaderViewHolder.kt @@ -8,14 +8,12 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import butterknife.OnClick import kotlinx.coroutines.launch import org.tasks.LocalBroadcastManager import org.tasks.R import org.tasks.data.CaldavDao import org.tasks.data.GoogleTaskDao +import org.tasks.databinding.FilterAdapterSubheaderBinding import org.tasks.filters.NavigationDrawerSubheader import org.tasks.filters.NavigationDrawerSubheader.SubheaderType import org.tasks.preferences.MainPreferences @@ -31,16 +29,12 @@ internal class SubheaderViewHolder( private val localBroadcastManager: LocalBroadcastManager) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.text) - lateinit var text: TextView - - @BindView(R.id.icon_error) - lateinit var errorIcon: ImageView + private val text: TextView + private val errorIcon: ImageView private lateinit var subheader: NavigationDrawerSubheader - @OnClick(R.id.subheader_row) - fun onClick() { + private fun onClick() { activity.lifecycleScope.launch { val collapsed = !subheader.isCollapsed when (subheader.subheaderType) { @@ -74,7 +68,11 @@ internal class SubheaderViewHolder( } init { - ButterKnife.bind(this, itemView) + FilterAdapterSubheaderBinding.bind(itemView).let { + text = it.text + errorIcon = it.iconError + it.subheaderRow.setOnClickListener { onClick() } + } errorIcon.setOnClickListener { activity.startActivity(Intent(activity, MainPreferences::class.java)) } diff --git a/app/src/main/java/com/todoroo/astrid/core/CriterionViewHolder.kt b/app/src/main/java/com/todoroo/astrid/core/CriterionViewHolder.kt index 7d3d79dd3..d5ba38c83 100644 --- a/app/src/main/java/com/todoroo/astrid/core/CriterionViewHolder.kt +++ b/app/src/main/java/com/todoroo/astrid/core/CriterionViewHolder.kt @@ -5,10 +5,8 @@ import android.view.View import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import butterknife.OnClick import org.tasks.R +import org.tasks.databinding.CustomFilterRowBinding import org.tasks.locale.Locale import org.tasks.preferences.ResourceResolver @@ -19,25 +17,23 @@ class CriterionViewHolder( private val onClick: (String) -> Unit) : RecyclerView.ViewHolder(itemView) { - @BindView(R.id.divider) - lateinit var divider: View - - @BindView(R.id.icon) - lateinit var icon: ImageView - - @BindView(R.id.name) - lateinit var name: TextView - - @BindView(R.id.filter_count) - lateinit var filterCount: TextView - - @BindView(R.id.row) - lateinit var row: View + private val divider: View + private val icon: ImageView + private val name: TextView + private val filterCount: TextView + private val row: View private lateinit var criterion: CriterionInstance init { - ButterKnife.bind(this, itemView) + CustomFilterRowBinding.bind(itemView).let { + divider = it.divider + icon = it.icon + name = it.name + filterCount = it.filterCount + row = it.row + } + row.setOnClickListener { onClick(criterion.id) } } fun bind(criterion: CriterionInstance) { @@ -71,9 +67,6 @@ class CriterionViewHolder( row.isClickable = criterion.type != CriterionInstance.TYPE_UNIVERSE } - @OnClick(R.id.row) - fun onClick() = onClick(criterion.id) - fun setMoving(moving: Boolean) { if (moving) { row.setBackgroundColor(ResourceResolver.getData(context, R.attr.colorControlHighlight)) diff --git a/app/src/main/java/com/todoroo/astrid/files/FilesControlSet.kt b/app/src/main/java/com/todoroo/astrid/files/FilesControlSet.kt index 62d1ad250..97f310d7d 100644 --- a/app/src/main/java/com/todoroo/astrid/files/FilesControlSet.kt +++ b/app/src/main/java/com/todoroo/astrid/files/FilesControlSet.kt @@ -11,11 +11,10 @@ import android.content.Intent import android.net.Uri import android.os.Bundle import android.view.View +import android.view.ViewGroup import android.widget.LinearLayout import android.widget.TextView import androidx.lifecycle.lifecycleScope -import butterknife.BindView -import butterknife.OnClick import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.launch @@ -23,6 +22,7 @@ import kotlinx.coroutines.withContext import org.tasks.R import org.tasks.data.TaskAttachment import org.tasks.data.TaskAttachmentDao +import org.tasks.databinding.ControlSetFilesBinding import org.tasks.dialogs.AddAttachmentDialog import org.tasks.dialogs.DialogBuilder import org.tasks.files.FileHelper @@ -38,11 +38,8 @@ class FilesControlSet : TaskEditControlFragment() { @Inject lateinit var dialogBuilder: DialogBuilder @Inject lateinit var preferences: Preferences - @BindView(R.id.attachment_container) - lateinit var attachmentContainer: LinearLayout - - @BindView(R.id.add_attachment) - lateinit var addAttachment: TextView + private lateinit var attachmentContainer: LinearLayout + private lateinit var addAttachment: TextView override fun createView(savedInstanceState: Bundle?) { val task = viewModel.task!! @@ -61,12 +58,18 @@ class FilesControlSet : TaskEditControlFragment() { } } - @OnClick(R.id.add_attachment) - fun addAttachment() { + private fun addAttachment() { AddAttachmentDialog.newAddAttachmentDialog(this).show(parentFragmentManager, FRAG_TAG_ADD_ATTACHMENT_DIALOG) } - override val layout = R.layout.control_set_files + override fun bind(parent: ViewGroup?) = + ControlSetFilesBinding.inflate(layoutInflater, parent, true).let { + attachmentContainer = it.attachmentContainer + addAttachment = it.addAttachment.apply { + setOnClickListener { addAttachment() } + } + it.root + } override val icon = R.drawable.ic_outline_attachment_24px diff --git a/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.kt b/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.kt index 2f6bc27d4..e7c0703e5 100644 --- a/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.kt +++ b/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.kt @@ -15,13 +15,12 @@ import android.widget.AdapterView import android.widget.LinearLayout import android.widget.Spinner import android.widget.TextView -import butterknife.BindView -import butterknife.OnItemSelected import dagger.hilt.android.AndroidEntryPoint import net.fortuna.ical4j.model.Recur import net.fortuna.ical4j.model.WeekDay import org.tasks.R import org.tasks.analytics.Firebase +import org.tasks.databinding.ControlSetRepeatDisplayBinding import org.tasks.dialogs.DialogBuilder import org.tasks.repeats.BasicRecurrenceDialog import org.tasks.repeats.RecurrenceUtils.newRecur @@ -30,6 +29,7 @@ import org.tasks.themes.Theme import org.tasks.time.DateTime import org.tasks.time.DateTimeUtils.currentTimeMillis import org.tasks.ui.HiddenTopArrayAdapter +import org.tasks.ui.OnItemSelected import org.tasks.ui.TaskEditControlFragment import java.util.* import javax.inject.Inject @@ -49,14 +49,9 @@ class RepeatControlSet : TaskEditControlFragment() { @Inject lateinit var firebase: Firebase @Inject lateinit var repeatRuleToString: RepeatRuleToString - @BindView(R.id.display_row_edit) - lateinit var displayView: TextView - - @BindView(R.id.repeatType) - lateinit var typeSpinner: Spinner - - @BindView(R.id.repeatTypeContainer) - lateinit var repeatTypeContainer: LinearLayout + private lateinit var displayView: TextView + private lateinit var typeSpinner: Spinner + private lateinit var repeatTypeContainer: LinearLayout private lateinit var typeAdapter: HiddenTopArrayAdapter @@ -118,8 +113,7 @@ class RepeatControlSet : TaskEditControlFragment() { refreshDisplayView() } - @OnItemSelected(R.id.repeatType) - fun onRepeatTypeChanged(position: Int) { + private fun onRepeatTypeChanged(position: Int) { viewModel.repeatAfterCompletion = position == TYPE_COMPLETION_DATE repeatTypes[0] = if (viewModel.repeatAfterCompletion!!) repeatTypes[2] else repeatTypes[1] typeAdapter.notifyDataSetChanged() @@ -136,7 +130,19 @@ class RepeatControlSet : TaskEditControlFragment() { override val isClickable = true - override val layout = R.layout.control_set_repeat_display + override fun bind(parent: ViewGroup?) = + ControlSetRepeatDisplayBinding.inflate(layoutInflater, parent, true).let { + displayView = it.displayRowEdit + typeSpinner = it.repeatType.apply { + onItemSelectedListener = object : OnItemSelected() { + override fun onItemSelected(position: Int) { + onRepeatTypeChanged(position) + } + } + } + repeatTypeContainer = it.repeatTypeContainer + it.root + } override val icon = R.drawable.ic_outline_repeat_24px diff --git a/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.kt b/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.kt index f19b966c8..2d610b924 100644 --- a/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.kt +++ b/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.kt @@ -9,12 +9,13 @@ import android.app.Activity import android.content.Intent import android.os.Bundle import android.view.View +import android.view.ViewGroup import android.widget.TextView -import butterknife.BindView import com.google.android.material.chip.ChipGroup import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.data.TagData +import org.tasks.databinding.ControlSetTagsBinding import org.tasks.tags.TagPickerActivity import org.tasks.ui.ChipProvider import org.tasks.ui.TaskEditControlFragment @@ -29,11 +30,8 @@ import javax.inject.Inject class TagsControlSet : TaskEditControlFragment() { @Inject lateinit var chipProvider: ChipProvider - @BindView(R.id.no_tags) - lateinit var tagsDisplay: TextView - - @BindView(R.id.chip_group) - lateinit var chipGroup: ChipGroup + private lateinit var tagsDisplay: TextView + private lateinit var chipGroup: ChipGroup override fun createView(savedInstanceState: Bundle?) { refreshDisplayView() @@ -45,7 +43,12 @@ class TagsControlSet : TaskEditControlFragment() { startActivityForResult(intent, REQUEST_TAG_PICKER_ACTIVITY) } - override val layout = R.layout.control_set_tags + override fun bind(parent: ViewGroup?) = + ControlSetTagsBinding.inflate(layoutInflater, parent, true).let { + tagsDisplay = it.noTags + chipGroup = it.chipGroup + it.root + } override val isClickable = true diff --git a/app/src/main/java/com/todoroo/astrid/timers/TimerControlSet.kt b/app/src/main/java/com/todoroo/astrid/timers/TimerControlSet.kt index 2f52207ef..357f1a4e8 100644 --- a/app/src/main/java/com/todoroo/astrid/timers/TimerControlSet.kt +++ b/app/src/main/java/com/todoroo/astrid/timers/TimerControlSet.kt @@ -11,14 +11,13 @@ import android.os.SystemClock import android.text.format.DateFormat import android.text.format.DateUtils import android.view.View +import android.view.ViewGroup import android.widget.Chronometer import android.widget.Chronometer.OnChronometerTickListener import android.widget.ImageView import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.lifecycle.lifecycleScope -import butterknife.BindView -import butterknife.OnClick import com.todoroo.andlib.utility.DateUtilities import com.todoroo.astrid.data.Task import com.todoroo.astrid.ui.TimeDurationControlSet @@ -26,6 +25,7 @@ import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import org.tasks.R import org.tasks.Strings.isNullOrEmpty +import org.tasks.databinding.ControlSetTimersBinding import org.tasks.dialogs.DialogBuilder import org.tasks.themes.Theme import org.tasks.ui.TaskEditControlFragment @@ -42,14 +42,9 @@ class TimerControlSet : TaskEditControlFragment() { @Inject lateinit var dialogBuilder: DialogBuilder @Inject lateinit var theme: Theme - @BindView(R.id.display_row_edit) - lateinit var displayEdit: TextView - - @BindView(R.id.timer) - lateinit var chronometer: Chronometer - - @BindView(R.id.timer_button) - lateinit var timerButton: ImageView + private lateinit var displayEdit: TextView + private lateinit var chronometer: Chronometer + private lateinit var timerButton: ImageView private lateinit var estimated: TimeDurationControlSet private lateinit var elapsed: TimeDurationControlSet @@ -87,8 +82,7 @@ class TimerControlSet : TaskEditControlFragment() { .create() } - @OnClick(R.id.timer_container) - fun timerClicked() { + private fun timerClicked() { lifecycleScope.launch { if (timerActive()) { val task = callback.stopTimer() @@ -105,7 +99,14 @@ class TimerControlSet : TaskEditControlFragment() { } } - override val layout = R.layout.control_set_timers + override fun bind(parent: ViewGroup?) = + ControlSetTimersBinding.inflate(layoutInflater, parent, true).let { + displayEdit = it.displayRowEdit + chronometer = it.timer + timerButton = it.timerButton + it.timerContainer.setOnClickListener { timerClicked() } + it.root + } override val icon = R.drawable.ic_outline_timer_24px diff --git a/app/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.kt b/app/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.kt index 0bb7d7e9f..e8c1ff482 100644 --- a/app/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.kt +++ b/app/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.kt @@ -11,16 +11,15 @@ import android.content.Intent import android.graphics.Paint import android.os.Bundle import android.view.View +import android.view.ViewGroup import android.widget.LinearLayout import android.widget.TextView import androidx.annotation.StringRes -import butterknife.BindView -import butterknife.OnClick import com.todoroo.andlib.utility.DateUtilities -import com.todoroo.astrid.alarms.AlarmService import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.activities.DateAndTimePickerActivity +import org.tasks.databinding.ControlSetRemindersBinding import org.tasks.date.DateTimeUtils import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.MyTimePickerDialog @@ -38,15 +37,11 @@ import javax.inject.Inject @AndroidEntryPoint class ReminderControlSet : TaskEditControlFragment() { @Inject lateinit var activity: Activity - @Inject lateinit var alarmService: AlarmService @Inject lateinit var locale: Locale @Inject lateinit var dialogBuilder: DialogBuilder - @BindView(R.id.alert_container) - lateinit var alertContainer: LinearLayout - - @BindView(R.id.reminder_alarm) - lateinit var mode: TextView + private lateinit var alertContainer: LinearLayout + private lateinit var mode: TextView private var randomControlSet: RandomReminderControlSet? = null @@ -69,8 +64,7 @@ class ReminderControlSet : TaskEditControlFragment() { viewModel.selectedAlarms?.forEach(this::addAlarmRow) } - @OnClick(R.id.reminder_alarm) - fun onClickRingType() { + private fun onClickRingType() { val modes = resources.getStringArray(R.array.reminder_ring_modes) val ringMode = when { viewModel.ringNonstop == true -> 2 @@ -110,8 +104,7 @@ class ReminderControlSet : TaskEditControlFragment() { } } - @OnClick(R.id.alarms_add) - fun addAlarm() { + private fun addAlarm() { val options = options if (options.size == 1) { addNewAlarm() @@ -126,7 +119,15 @@ class ReminderControlSet : TaskEditControlFragment() { } } - override val layout = R.layout.control_set_reminders + override fun bind(parent: ViewGroup?) = + ControlSetRemindersBinding.inflate(layoutInflater, parent, true).let { + alertContainer = it.alertContainer + mode = it.reminderAlarm.apply { + setOnClickListener { onClickRingType() } + } + it.alarmsAdd.setOnClickListener { addAlarm() } + it.root + } override val icon = R.drawable.ic_outline_notifications_24px diff --git a/app/src/main/java/com/todoroo/astrid/ui/StartDateControlSet.kt b/app/src/main/java/com/todoroo/astrid/ui/StartDateControlSet.kt index 9326e2c37..6a1dad249 100644 --- a/app/src/main/java/com/todoroo/astrid/ui/StartDateControlSet.kt +++ b/app/src/main/java/com/todoroo/astrid/ui/StartDateControlSet.kt @@ -3,13 +3,14 @@ package com.todoroo.astrid.ui import android.app.Activity import android.content.Intent import android.os.Bundle +import android.view.ViewGroup import android.widget.TextView -import butterknife.BindView import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities.now import com.todoroo.astrid.data.Task import dagger.hilt.android.AndroidEntryPoint import org.tasks.R +import org.tasks.databinding.ControlSetHideBinding import org.tasks.date.DateTimeUtils.newDateTime import org.tasks.date.DateTimeUtils.toDateTime import org.tasks.dialogs.StartDatePicker @@ -35,8 +36,7 @@ class StartDateControlSet : TaskEditControlFragment() { @Inject lateinit var preferences: Preferences @Inject lateinit var locale: Locale - @BindView(R.id.start_date) - lateinit var startDate: TextView + private lateinit var startDate: TextView private val dueDateTime get() = viewModel.dueDate!! @@ -95,7 +95,11 @@ class StartDateControlSet : TaskEditControlFragment() { applySelectionToHideUntil() } - override val layout = R.layout.control_set_hide + override fun bind(parent: ViewGroup?) = + ControlSetHideBinding.inflate(layoutInflater, parent, true).let { + startDate = it.startDate + it.root + } override val icon = R.drawable.ic_pending_actions_24px diff --git a/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt b/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt index f1b1dbbc8..adb01d98a 100644 --- a/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/BaseListSettingsActivity.kt @@ -5,12 +5,10 @@ import android.graphics.drawable.LayerDrawable import android.os.Bundle import android.view.MenuItem import android.view.View +import android.view.ViewGroup import android.widget.TextView import androidx.appcompat.widget.Toolbar import androidx.lifecycle.lifecycleScope -import butterknife.BindView -import butterknife.ButterKnife -import butterknife.OnClick import kotlinx.coroutines.launch import org.tasks.R import org.tasks.dialogs.ColorPalettePicker @@ -34,22 +32,26 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic protected var selectedColor = 0 protected var selectedIcon = -1 - @BindView(R.id.clear) - lateinit var clear: View - - @BindView(R.id.color) - lateinit var color: TextView - - @BindView(R.id.icon) - lateinit var icon: TextView - - @BindView(R.id.toolbar) - lateinit var toolbar: Toolbar + private lateinit var clear: View + private lateinit var color: TextView + private lateinit var icon: TextView + protected lateinit var toolbar: Toolbar + protected lateinit var colorRow: ViewGroup override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(layout) - ButterKnife.bind(this) + val view = bind() + setContentView(view) + clear = findViewById(R.id.clear).apply { + setOnClickListener { clearColor() } + } + color = findViewById(R.id.color) + colorRow = findViewById(R.id.color_row).apply { + setOnClickListener { showThemePicker() } + } + icon = findViewById(R.id.icon) + findViewById(R.id.icon_row).setOnClickListener { showIconPicker() } + toolbar = view.findViewById(R.id.toolbar) if (savedInstanceState != null) { selectedColor = savedInstanceState.getInt(EXTRA_SELECTED_THEME) selectedIcon = savedInstanceState.getInt(EXTRA_SELECTED_ICON) @@ -73,12 +75,12 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic discard() } - protected abstract val layout: Int protected abstract fun hasChanges(): Boolean protected abstract suspend fun save() protected abstract val isNew: Boolean protected abstract val toolbarTitle: String? protected abstract suspend fun delete() + protected abstract fun bind(): View protected open fun discard() { if (!hasChanges()) { finish() @@ -91,19 +93,16 @@ abstract class BaseListSettingsActivity : ThemedInjectingAppCompatActivity(), Ic } } - @OnClick(R.id.clear) - fun clearColor() { + private fun clearColor() { onColorPicked(0) } - @OnClick(R.id.color_row) - fun showThemePicker() { + private fun showThemePicker() { newColorPalette(null, 0, selectedColor, Palette.COLORS) .show(supportFragmentManager, FRAG_TAG_COLOR_PICKER) } - @OnClick(R.id.icon_row) - fun showIconPicker() { + private fun showIconPicker() { IconPickerDialog.newIconPicker(selectedIcon).show(supportFragmentManager, FRAG_TAG_ICON_PICKER) } diff --git a/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt b/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt index 96c8845d8..010978df0 100644 --- a/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/FilterSettingsActivity.kt @@ -9,13 +9,11 @@ import android.view.MenuItem import android.view.inputmethod.InputMethodManager import android.widget.EditText import android.widget.FrameLayout +import androidx.core.widget.addTextChangedListener import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.OnClick -import butterknife.OnTextChanged import com.google.android.material.button.MaterialButtonToggleGroup import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.textfield.TextInputEditText @@ -26,7 +24,12 @@ import com.todoroo.andlib.sql.UnaryCriterion import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.astrid.activity.MainActivity import com.todoroo.astrid.activity.TaskListFragment -import com.todoroo.astrid.api.* +import com.todoroo.astrid.api.BooleanCriterion +import com.todoroo.astrid.api.CustomFilter +import com.todoroo.astrid.api.CustomFilterCriterion +import com.todoroo.astrid.api.MultipleSelectCriterion +import com.todoroo.astrid.api.PermaSql +import com.todoroo.astrid.api.TextInputCriterion import com.todoroo.astrid.core.CriterionInstance import com.todoroo.astrid.core.CustomFilterAdapter import com.todoroo.astrid.core.CustomFilterItemTouchHelper @@ -39,6 +42,7 @@ import org.tasks.Strings import org.tasks.data.Filter import org.tasks.data.FilterDao import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible +import org.tasks.databinding.FilterSettingsActivityBinding import org.tasks.db.QueryUtils import org.tasks.extensions.Context.openUri import org.tasks.filters.FilterCriteriaProvider @@ -54,17 +58,10 @@ class FilterSettingsActivity : BaseListSettingsActivity() { @Inject lateinit var database: Database @Inject lateinit var filterCriteriaProvider: FilterCriteriaProvider - @BindView(R.id.name) - lateinit var name: TextInputEditText - - @BindView(R.id.name_layout) - lateinit var nameLayout: TextInputLayout - - @BindView(R.id.recycler_view) - lateinit var recyclerView: RecyclerView - - @BindView(R.id.fab) - lateinit var fab: ExtendedFloatingActionButton + private lateinit var name: TextInputEditText + private lateinit var nameLayout: TextInputLayout + private lateinit var recyclerView: RecyclerView + private lateinit var fab: ExtendedFloatingActionButton private var filter: CustomFilter? = null private lateinit var adapter: CustomFilterAdapter @@ -162,8 +159,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() { else -> CriterionInstance.TYPE_INTERSECT } - @OnClick(R.id.fab) - fun addCriteria() { + private fun addCriteria() { AndroidUtilities.hideKeyboard(this) fab.shrink() lifecycleScope.launch { @@ -230,11 +226,6 @@ class FilterSettingsActivity : BaseListSettingsActivity() { override val toolbarTitle: String? get() = if (isNew) getString(R.string.FLA_new_filter) else filter!!.listingTitle - @OnTextChanged(R.id.name) - fun onTextChanged() { - nameLayout.error = null - } - override suspend fun save() { val newName = newName if (Strings.isNullOrEmpty(newName)) { @@ -290,8 +281,19 @@ class FilterSettingsActivity : BaseListSettingsActivity() { super.finish() } - override val layout: Int - get() = R.layout.filter_settings_activity + override fun bind() = FilterSettingsActivityBinding.inflate(layoutInflater).let { + name = it.name.apply { + addTextChangedListener( + onTextChanged = { _, _, _, _ -> nameLayout.error = null } + ) + } + nameLayout = it.nameLayout + recyclerView = it.recyclerView + fab = it.fab.apply { + setOnClickListener { addCriteria() } + } + it.root + } override suspend fun delete() { filterDao.delete(filter!!.id) diff --git a/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt b/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt index 4d7103355..0b741b0d0 100644 --- a/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/GoogleTaskListSettingsActivity.kt @@ -8,7 +8,6 @@ import android.view.View import android.view.inputmethod.InputMethodManager import android.widget.ProgressBar import androidx.activity.viewModels -import butterknife.BindView import com.google.android.material.textfield.TextInputEditText import com.google.api.services.tasks.model.TaskList import com.todoroo.astrid.activity.MainActivity @@ -21,6 +20,7 @@ import org.tasks.Strings.isNullOrEmpty import org.tasks.data.GoogleTaskAccount import org.tasks.data.GoogleTaskList import org.tasks.data.GoogleTaskListDao +import org.tasks.databinding.ActivityGoogleTaskListSettingsBinding import org.tasks.extensions.Context.toast import timber.log.Timber import javax.inject.Inject @@ -30,11 +30,8 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { @Inject lateinit var googleTaskListDao: GoogleTaskListDao @Inject lateinit var taskDeleter: TaskDeleter - @BindView(R.id.name) - lateinit var name: TextInputEditText - - @BindView(R.id.progress_bar) - lateinit var progressView: ProgressBar + private lateinit var name: TextInputEditText + private lateinit var progressView: ProgressBar private var isNewList = false private lateinit var gtasksList: GoogleTaskList @@ -126,8 +123,11 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { super.finish() } - override val layout: Int - get() = R.layout.activity_google_task_list_settings + override fun bind() = ActivityGoogleTaskListSettingsBinding.inflate(layoutInflater).let { + name = it.name + progressView = it.progressBar.progressBar + it.root + } override fun promptDelete() { if (!requestInProgress()) { @@ -174,7 +174,7 @@ class GoogleTaskListSettingsActivity : BaseListSettingsActivity() { finish() } - private suspend fun onListDeleted(deleted: Boolean) { + private fun onListDeleted(deleted: Boolean) { if (deleted) { taskDeleter.delete(gtasksList) setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED)) diff --git a/app/src/main/java/org/tasks/activities/PlaceSettingsActivity.kt b/app/src/main/java/org/tasks/activities/PlaceSettingsActivity.kt index 6910e1f7d..f4d4f4f03 100644 --- a/app/src/main/java/org/tasks/activities/PlaceSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/PlaceSettingsActivity.kt @@ -3,8 +3,7 @@ package org.tasks.activities import android.app.Activity import android.content.Intent import android.os.Bundle -import butterknife.BindView -import butterknife.OnTextChanged +import androidx.core.widget.addTextChangedListener import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.todoroo.astrid.activity.MainActivity @@ -14,6 +13,7 @@ import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.data.LocationDao import org.tasks.data.Place +import org.tasks.databinding.ActivityLocationSettingsBinding import org.tasks.filters.PlaceFilter import org.tasks.location.MapFragment import org.tasks.preferences.Preferences @@ -26,8 +26,8 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen const val EXTRA_PLACE = "extra_place" } - @BindView(R.id.name) lateinit var name: TextInputEditText - @BindView(R.id.name_layout) lateinit var nameLayout: TextInputLayout + private lateinit var name: TextInputEditText + private lateinit var nameLayout: TextInputLayout @Inject lateinit var locationDao: LocationDao @Inject lateinit var map: MapFragment @@ -64,18 +64,20 @@ class PlaceSettingsActivity : BaseListSettingsActivity(), MapFragment.MapFragmen updateTheme() } - override val layout: Int - get() = R.layout.activity_location_settings + override fun bind() = ActivityLocationSettingsBinding.inflate(layoutInflater).let { + name = it.name.apply { + addTextChangedListener( + onTextChanged = { _, _, _, _ -> nameLayout.error = null } + ) + } + nameLayout = it.nameLayout + it.root + } override fun hasChanges() = name.text.toString() != place.displayName || selectedColor != place.color || selectedIcon != place.getIcon()!! - @OnTextChanged(R.id.name) - fun onNameChanged() { - nameLayout.error = null - } - override suspend fun save() { val newName: String = name.text.toString() diff --git a/app/src/main/java/org/tasks/activities/TagSettingsActivity.kt b/app/src/main/java/org/tasks/activities/TagSettingsActivity.kt index 9021043b1..81d40f39d 100644 --- a/app/src/main/java/org/tasks/activities/TagSettingsActivity.kt +++ b/app/src/main/java/org/tasks/activities/TagSettingsActivity.kt @@ -10,8 +10,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.view.inputmethod.InputMethodManager -import butterknife.BindView -import butterknife.OnTextChanged +import androidx.core.widget.addTextChangedListener import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.todoroo.astrid.activity.MainActivity @@ -24,6 +23,7 @@ import org.tasks.Strings.isNullOrEmpty import org.tasks.data.TagDao import org.tasks.data.TagData import org.tasks.data.TagDataDao +import org.tasks.databinding.ActivityTagSettingsBinding import javax.inject.Inject @AndroidEntryPoint @@ -31,11 +31,8 @@ class TagSettingsActivity : BaseListSettingsActivity() { @Inject lateinit var tagDataDao: TagDataDao @Inject lateinit var tagDao: TagDao - @BindView(R.id.name) - lateinit var name: TextInputEditText - - @BindView(R.id.name_layout) - lateinit var nameLayout: TextInputLayout + private lateinit var name: TextInputEditText + private lateinit var nameLayout: TextInputLayout private var isNewTag = false private lateinit var tagData: TagData @@ -70,11 +67,6 @@ class TagSettingsActivity : BaseListSettingsActivity() { override val toolbarTitle: String get() = if (isNew) getString(R.string.new_tag) else tagData.name!! - @OnTextChanged(R.id.name) - fun onTextChanged() { - nameLayout.error = null - } - private val newName: String get() = name.text.toString().trim { it <= ' ' } @@ -129,8 +121,15 @@ class TagSettingsActivity : BaseListSettingsActivity() { super.finish() } - override val layout: Int - get() = R.layout.activity_tag_settings + override fun bind() = ActivityTagSettingsBinding.inflate(layoutInflater).let { + name = it.name.apply { + addTextChangedListener( + onTextChanged = { _, _, _, _ -> nameLayout.error = null } + ) + } + nameLayout = it.nameLayout + it.root + } override suspend fun delete() { val uuid = tagData.remoteId diff --git a/app/src/main/java/org/tasks/activities/attribution/AttributionActivity.kt b/app/src/main/java/org/tasks/activities/attribution/AttributionActivity.kt index 4b7f2a974..984c5dce0 100644 --- a/app/src/main/java/org/tasks/activities/attribution/AttributionActivity.kt +++ b/app/src/main/java/org/tasks/activities/attribution/AttributionActivity.kt @@ -2,7 +2,6 @@ package org.tasks.activities.attribution import android.os.Bundle import androidx.activity.viewModels -import butterknife.ButterKnife import com.google.android.material.composethemeadapter.MdcTheme import dagger.hilt.android.AndroidEntryPoint import org.tasks.R @@ -18,7 +17,6 @@ class AttributionActivity : ThemedInjectingAppCompatActivity() { super.onCreate(savedInstanceState) val binding = ActivityAttributionsBinding.inflate(layoutInflater) setContentView(binding.root) - ButterKnife.bind(this) with(binding.toolbar.toolbar) { setTitle(R.string.third_party_licenses) setNavigationIcon(R.drawable.ic_outline_arrow_back_24px) diff --git a/app/src/main/java/org/tasks/caldav/BaseCaldavAccountSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/BaseCaldavAccountSettingsActivity.kt index 5831f5758..30081147b 100644 --- a/app/src/main/java/org/tasks/caldav/BaseCaldavAccountSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/BaseCaldavAccountSettingsActivity.kt @@ -12,11 +12,9 @@ import android.view.inputmethod.InputMethodManager import androidx.annotation.StringRes import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat +import androidx.core.widget.addTextChangedListener import androidx.lifecycle.lifecycleScope import at.bitfire.dav4jvm.exception.HttpException -import butterknife.ButterKnife -import butterknife.OnFocusChange -import butterknife.OnTextChanged import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.Snackbar import com.todoroo.astrid.data.Task @@ -59,7 +57,6 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv super.onCreate(savedInstanceState) binding = ActivityCaldavAccountSettingsBinding.inflate(layoutInflater) setContentView(binding.root) - ButterKnife.bind(this) caldavAccount = if (savedInstanceState == null) intent.getParcelableExtra(EXTRA_CALDAV_DATA) else savedInstanceState.getParcelable(EXTRA_CALDAV_DATA) if (caldavAccount == null || caldavAccount!!.id == Task.NO_ID) { binding.nameLayout.visibility = View.GONE @@ -108,6 +105,19 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv } .show() } + binding.name.addTextChangedListener( + onTextChanged = { _, _, _, _ -> binding.nameLayout.error = null } + ) + binding.url.addTextChangedListener( + onTextChanged = { _, _, _, _ -> binding.urlLayout.error = null } + ) + binding.user.addTextChangedListener( + onTextChanged = { _, _, _, _ -> binding.userLayout.error = null } + ) + binding.password.addTextChangedListener( + onTextChanged = { _, _, _, _ -> binding.passwordLayout.error = null } + ) + binding.password.setOnFocusChangeListener { _, hasFocus -> onPasswordFocused(hasFocus) } } @get:StringRes @@ -132,28 +142,7 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv return binding.progressBar.progressBar.visibility == View.VISIBLE } - @OnTextChanged(R.id.name) - fun onNameChanged() { - binding.nameLayout.error = null - } - - @OnTextChanged(R.id.url) - fun onUrlChanged() { - binding.urlLayout.error = null - } - - @OnTextChanged(R.id.user) - fun onUserChanged() { - binding.userLayout.error = null - } - - @OnTextChanged(R.id.password) - fun onPasswordChanged() { - binding.passwordLayout.error = null - } - - @OnFocusChange(R.id.password) - fun onPasswordFocused(hasFocus: Boolean) { + private fun onPasswordFocused(hasFocus: Boolean) { if (hasFocus) { if (PASSWORD_MASK == binding.password.text.toString()) { binding.password.setText("") diff --git a/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt index bebf003c3..ee6227a10 100644 --- a/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/BaseCaldavCalendarSettingsActivity.kt @@ -8,9 +8,8 @@ import android.view.View import android.view.inputmethod.InputMethodManager import android.widget.LinearLayout import android.widget.ProgressBar +import androidx.core.widget.addTextChangedListener import at.bitfire.dav4jvm.exception.HttpException -import butterknife.BindView -import butterknife.OnTextChanged import com.google.android.material.snackbar.Snackbar import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout @@ -26,6 +25,7 @@ import org.tasks.activities.BaseListSettingsActivity import org.tasks.data.CaldavAccount import org.tasks.data.CaldavCalendar import org.tasks.data.CaldavDao +import org.tasks.databinding.ActivityCaldavCalendarSettingsBinding import org.tasks.ui.DisplayableException import java.net.ConnectException import javax.inject.Inject @@ -34,24 +34,26 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { @Inject lateinit var caldavDao: CaldavDao @Inject lateinit var taskDeleter: TaskDeleter - @BindView(R.id.root_layout) - lateinit var root: LinearLayout - - @BindView(R.id.name) - lateinit var name: TextInputEditText - - @BindView(R.id.name_layout) - lateinit var nameLayout: TextInputLayout - - @BindView(R.id.progress_bar) - lateinit var progressView: ProgressBar + private lateinit var root: LinearLayout + private lateinit var name: TextInputEditText + protected lateinit var nameLayout: TextInputLayout + protected lateinit var progressView: ProgressBar protected var caldavCalendar: CaldavCalendar? = null protected lateinit var caldavAccount: CaldavAccount - override val layout: Int - get() = R.layout.activity_caldav_calendar_settings + override fun bind() = ActivityCaldavCalendarSettingsBinding.inflate(layoutInflater).let { + root = it.rootLayout + name = it.name.apply { + addTextChangedListener( + onTextChanged = { _, _, _, _ -> nameLayout.error = null } + ) + } + nameLayout = it.nameLayout + progressView = it.progressBar.progressBar + it.root + } override fun onCreate(savedInstanceState: Bundle?) { val intent = intent @@ -83,11 +85,6 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() { override val toolbarTitle: String get() = if (isNew) getString(R.string.new_list) else caldavCalendar!!.name ?: "" - @OnTextChanged(R.id.name) - fun onNameChanged() { - nameLayout.error = null - } - override suspend fun save() { if (requestInProgress()) { return diff --git a/app/src/main/java/org/tasks/caldav/CaldavCalendarSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/CaldavCalendarSettingsActivity.kt index 3d8d3ecc7..322212210 100644 --- a/app/src/main/java/org/tasks/caldav/CaldavCalendarSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/CaldavCalendarSettingsActivity.kt @@ -34,8 +34,6 @@ class CaldavCalendarSettingsActivity : BaseCaldavCalendarSettingsActivity() { private val viewModel: CaldavCalendarViewModel by viewModels() - override val layout = R.layout.activity_caldav_calendar_settings - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt b/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt index 76146bd5a..28075f2a2 100644 --- a/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/caldav/LocalListSettingsActivity.kt @@ -11,9 +11,6 @@ import org.tasks.data.CaldavDao @AndroidEntryPoint class LocalListSettingsActivity : BaseCaldavCalendarSettingsActivity() { - override val layout: Int - get() = R.layout.activity_caldav_calendar_settings - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/org/tasks/dialogs/ColorPalettePicker.kt b/app/src/main/java/org/tasks/dialogs/ColorPalettePicker.kt index 045b9e694..6fe73bf5b 100644 --- a/app/src/main/java/org/tasks/dialogs/ColorPalettePicker.kt +++ b/app/src/main/java/org/tasks/dialogs/ColorPalettePicker.kt @@ -10,13 +10,11 @@ import android.os.Parcelable import android.view.LayoutInflater import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment -import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.billing.Inventory import org.tasks.billing.PurchaseActivity +import org.tasks.databinding.DialogIconPickerBinding import org.tasks.dialogs.ColorPickerAdapter.Palette import org.tasks.dialogs.ColorWheelPicker.Companion.newColorWheel import org.tasks.themes.ColorProvider @@ -68,16 +66,12 @@ class ColorPalettePicker : DialogFragment() { @Inject lateinit var inventory: Inventory @Inject lateinit var colorProvider: ColorProvider - @BindView(R.id.icons) lateinit var recyclerView: RecyclerView - private lateinit var colors: List private lateinit var palette: Palette var callback: ColorPickedCallback? = null override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val inflater = LayoutInflater.from(context) - val view = inflater.inflate(R.layout.dialog_icon_picker, null) - ButterKnife.bind(this, view) + val binding = DialogIconPickerBinding.inflate(LayoutInflater.from(context)) palette = requireArguments().getSerializable(EXTRA_PALETTE) as Palette colors = when (palette) { Palette.COLORS -> colorProvider.getThemeColors() @@ -89,13 +83,15 @@ class ColorPalettePicker : DialogFragment() { } val iconPickerAdapter = ColorPickerAdapter(requireActivity(), inventory, this::onSelected) - recyclerView.layoutManager = IconLayoutManager(context) - recyclerView.adapter = iconPickerAdapter + with(binding.icons) { + layoutManager = IconLayoutManager(context) + adapter = iconPickerAdapter + } iconPickerAdapter.submitList(colors) val builder = dialogBuilder .newDialog() - .setView(view) + .setView(binding.root) if (palette == Palette.COLORS || palette == Palette.WIDGET) { builder.setNeutralButton(R.string.color_wheel) { _, _ -> val selected = arguments?.getInt(EXTRA_SELECTED) ?: 0 diff --git a/app/src/main/java/org/tasks/dialogs/ColorPickerAdapter.kt b/app/src/main/java/org/tasks/dialogs/ColorPickerAdapter.kt index 9bc170138..d016ee900 100644 --- a/app/src/main/java/org/tasks/dialogs/ColorPickerAdapter.kt +++ b/app/src/main/java/org/tasks/dialogs/ColorPickerAdapter.kt @@ -6,6 +6,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import org.tasks.R import org.tasks.billing.Inventory +import org.tasks.databinding.DialogIconPickerCellBinding import org.tasks.dialogs.ColorPalettePicker.Pickable class ColorPickerAdapter( @@ -21,10 +22,12 @@ class ColorPickerAdapter( WIDGET } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IconPickerHolder { - val view = activity.layoutInflater.inflate(R.layout.dialog_icon_picker_cell, parent, false) - return IconPickerHolder(activity, view, onSelected) - } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = + IconPickerHolder( + activity, + DialogIconPickerCellBinding.inflate(activity.layoutInflater, parent, false), + onSelected + ) override fun onBindViewHolder(holder: IconPickerHolder, position: Int) { val pickable = getItem(position) diff --git a/app/src/main/java/org/tasks/dialogs/DateTimePicker.kt b/app/src/main/java/org/tasks/dialogs/DateTimePicker.kt index ec1e5aff9..e4337853e 100644 --- a/app/src/main/java/org/tasks/dialogs/DateTimePicker.kt +++ b/app/src/main/java/org/tasks/dialogs/DateTimePicker.kt @@ -9,8 +9,6 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope -import butterknife.ButterKnife -import butterknife.OnClick import com.todoroo.andlib.utility.DateUtilities import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.data.Task @@ -93,20 +91,33 @@ class DateTimePicker : BaseDateTimePicker() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { binding = DialogDateTimePickerBinding.inflate(theme.getLayoutInflater(requireContext())) setupShortcutsAndCalendar() - ButterKnife.bind(this, binding.root) - binding.shortcuts.nextWeekButton.text = + with (binding.shortcuts) { + nextWeekButton.text = getString( - when (newDateTime().plusWeeks(1).dayOfWeek) { - SUNDAY -> R.string.next_sunday - MONDAY -> R.string.next_monday - TUESDAY -> R.string.next_tuesday - WEDNESDAY -> R.string.next_wednesday - THURSDAY -> R.string.next_thursday - FRIDAY -> R.string.next_friday - SATURDAY -> R.string.next_saturday - else -> throw IllegalArgumentException() - } + when (newDateTime().plusWeeks(1).dayOfWeek) { + SUNDAY -> R.string.next_sunday + MONDAY -> R.string.next_monday + TUESDAY -> R.string.next_tuesday + WEDNESDAY -> R.string.next_wednesday + THURSDAY -> R.string.next_thursday + FRIDAY -> R.string.next_friday + SATURDAY -> R.string.next_saturday + else -> throw IllegalArgumentException() + } ) + noDateButton.setOnClickListener { clearDate() } + noTime.setOnClickListener { clearTime() } + todayButton.setOnClickListener { setToday() } + tomorrowButton.setOnClickListener { setTomorrow() } + nextWeekButton.setOnClickListener { setNextWeek() } + morningButton.setOnClickListener { setMorning() } + afternoonButton.setOnClickListener { setAfternoon() } + eveningButton.setOnClickListener { setEvening() } + nightButton.setOnClickListener { setNight() } + currentDateSelection.setOnClickListener { currentDate() } + currentTimeSelection.setOnClickListener { currentTime() } + pickTimeButton.setOnClickListener { pickTime() } + } binding.calendarView.setOnDateChangeListener { _, y, m, d -> returnDate(day = DateTime(y, m + 1, d).millis) refreshButtons() @@ -163,40 +174,18 @@ class DateTimePicker : BaseDateTimePicker() { } } - @OnClick(R.id.no_date_button) - fun clearDate() = returnDate(day = 0, time = 0) - - @OnClick(R.id.no_time) - fun clearTime() = returnDate(time = 0) - - @OnClick(R.id.today_button) - fun setToday() = returnDate(day = today.startOfDay().millis) - - @OnClick(R.id.tomorrow_button) - fun setTomorrow() = returnDate(day = tomorrow.startOfDay().millis) - - @OnClick(R.id.next_week_button) - fun setNextWeek() = returnDate(day = nextWeek.startOfDay().millis) - - @OnClick(R.id.morning_button) - fun setMorning() = returnSelectedTime(morning) - - @OnClick(R.id.afternoon_button) - fun setAfternoon() = returnSelectedTime(afternoon) - - @OnClick(R.id.evening_button) - fun setEvening() = returnSelectedTime(evening) - - @OnClick(R.id.night_button) - fun setNight() = returnSelectedTime(night) - - @OnClick(R.id.current_date_selection) - fun currentDate() = returnDate(day = customDate) - - @OnClick(R.id.current_time_selection) - fun currentTime() = returnSelectedTime(customTime) + private fun clearDate() = returnDate(day = 0, time = 0) + private fun clearTime() = returnDate(time = 0) + private fun setToday() = returnDate(day = today.startOfDay().millis) + private fun setTomorrow() = returnDate(day = tomorrow.startOfDay().millis) + private fun setNextWeek() = returnDate(day = nextWeek.startOfDay().millis) + private fun setMorning() = returnSelectedTime(morning) + private fun setAfternoon() = returnSelectedTime(afternoon) + private fun setEvening() = returnSelectedTime(evening) + private fun setNight() = returnSelectedTime(night) + private fun currentDate() = returnDate(day = customDate) + private fun currentTime() = returnSelectedTime(customTime) - @OnClick(R.id.pick_time_button) fun pickTime() { val time = if (selectedTime == MULTIPLE_TIMES || !Task.hasDueTime(today.withMillisOfDay(selectedTime).millis)) { diff --git a/app/src/main/java/org/tasks/dialogs/GeofenceDialog.java b/app/src/main/java/org/tasks/dialogs/GeofenceDialog.java index a64fbd614..32a14b687 100644 --- a/app/src/main/java/org/tasks/dialogs/GeofenceDialog.java +++ b/app/src/main/java/org/tasks/dialogs/GeofenceDialog.java @@ -9,22 +9,25 @@ import android.content.Intent; import android.os.Bundle; import android.os.Parcelable; import android.view.LayoutInflater; -import android.view.View; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; -import butterknife.BindView; -import butterknife.ButterKnife; + import com.google.android.material.slider.Slider; import com.google.android.material.switchmaterial.SwitchMaterial; -import dagger.hilt.android.AndroidEntryPoint; -import javax.inject.Inject; + import org.tasks.R; import org.tasks.data.Geofence; import org.tasks.data.Location; +import org.tasks.databinding.LocationDetailsBinding; import org.tasks.locale.Locale; import org.tasks.preferences.PermissionChecker; +import javax.inject.Inject; + +import dagger.hilt.android.AndroidEntryPoint; + @AndroidEntryPoint public class GeofenceDialog extends DialogFragment { @@ -39,14 +42,9 @@ public class GeofenceDialog extends DialogFragment { @Inject Locale locale; @Inject PermissionChecker permissionChecker; - @BindView(R.id.location_arrival) - SwitchMaterial arrivalView; - - @BindView(R.id.location_departure) - SwitchMaterial departureView; - - @BindView(R.id.slider) - Slider slider; + private SwitchMaterial arrivalView; + private SwitchMaterial departureView; + private Slider slider; public static GeofenceDialog newGeofenceDialog(Location location) { GeofenceDialog dialog = new GeofenceDialog(); @@ -66,8 +64,10 @@ public class GeofenceDialog extends DialogFragment { : savedInstanceState.getParcelable(EXTRA_GEOFENCE); LayoutInflater layoutInflater = LayoutInflater.from(context); - View view = layoutInflater.inflate(R.layout.location_details, null); - ButterKnife.bind(this, view); + LocationDetailsBinding binding = LocationDetailsBinding.inflate(layoutInflater); + arrivalView = binding.locationArrival; + departureView = binding.locationDeparture; + slider = binding.slider; arrivalView.setChecked(geofence.isArrival()); departureView.setChecked(geofence.isDeparture()); slider.setLabelFormatter( @@ -79,7 +79,7 @@ public class GeofenceDialog extends DialogFragment { slider.setValue(Math.round((geofence.getRadius() / STEP) * STEP)); return dialogBuilder .newDialog(original.getDisplayName()) - .setView(view) + .setView(binding.getRoot()) .setNegativeButton(R.string.cancel, null) .setOnCancelListener(this::sendResult) .setPositiveButton(R.string.ok, this::sendResult) diff --git a/app/src/main/java/org/tasks/dialogs/IconPickerAdapter.java b/app/src/main/java/org/tasks/dialogs/IconPickerAdapter.java index 10a15d57a..d161b7d13 100644 --- a/app/src/main/java/org/tasks/dialogs/IconPickerAdapter.java +++ b/app/src/main/java/org/tasks/dialogs/IconPickerAdapter.java @@ -4,13 +4,16 @@ import static org.tasks.preferences.ResourceResolver.getData; import android.app.Activity; import android.view.ViewGroup; + import androidx.annotation.NonNull; import androidx.core.content.res.ResourcesCompat; import androidx.recyclerview.widget.DiffUtil.ItemCallback; import androidx.recyclerview.widget.ListAdapter; + import org.tasks.Callback; import org.tasks.R; import org.tasks.billing.Inventory; +import org.tasks.databinding.DialogIconPickerCellBinding; import org.tasks.themes.CustomIcons; class IconPickerAdapter extends ListAdapter { @@ -34,7 +37,7 @@ class IconPickerAdapter extends ListAdapter { public IconPickerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new IconPickerHolder( activity, - activity.getLayoutInflater().inflate(R.layout.dialog_icon_picker_cell, parent, false), + DialogIconPickerCellBinding.inflate(activity.getLayoutInflater(), parent, false), onSelected); } diff --git a/app/src/main/java/org/tasks/dialogs/IconPickerDialog.java b/app/src/main/java/org/tasks/dialogs/IconPickerDialog.java index cccfeca2e..11255f2b7 100644 --- a/app/src/main/java/org/tasks/dialogs/IconPickerDialog.java +++ b/app/src/main/java/org/tasks/dialogs/IconPickerDialog.java @@ -6,7 +6,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; -import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -16,12 +15,11 @@ import androidx.recyclerview.widget.RecyclerView; import org.tasks.R; import org.tasks.billing.Inventory; import org.tasks.billing.PurchaseActivity; +import org.tasks.databinding.DialogIconPickerBinding; import org.tasks.themes.CustomIcons; import javax.inject.Inject; -import butterknife.BindView; -import butterknife.ButterKnife; import dagger.hilt.android.AndroidEntryPoint; @AndroidEntryPoint @@ -29,9 +27,6 @@ public class IconPickerDialog extends DialogFragment { private static final String EXTRA_CURRENT = "extra_current"; - @BindView(R.id.icons) - RecyclerView recyclerView; - @Inject DialogBuilder dialogBuilder; @Inject Activity context; @Inject Inventory inventory; @@ -48,23 +43,23 @@ public class IconPickerDialog extends DialogFragment { @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { - LayoutInflater inflater = LayoutInflater.from(context); - View view = inflater.inflate(R.layout.dialog_icon_picker, null); - - ButterKnife.bind(this, view); - + DialogIconPickerBinding binding = DialogIconPickerBinding.inflate(LayoutInflater.from(context)); Bundle arguments = getArguments(); int current = arguments.getInt(EXTRA_CURRENT); IconPickerAdapter iconPickerAdapter = - new IconPickerAdapter((Activity) context, inventory, current, this::onSelected); + new IconPickerAdapter(context, inventory, current, this::onSelected); + RecyclerView recyclerView = binding.icons; recyclerView.setLayoutManager(new IconLayoutManager(context)); recyclerView.setAdapter(iconPickerAdapter); iconPickerAdapter.submitList(CustomIcons.getIconList()); AlertDialogBuilder builder = - dialogBuilder.newDialog().setNegativeButton(R.string.cancel, null).setView(view); + dialogBuilder + .newDialog() + .setNegativeButton(R.string.cancel, null) + .setView(binding.getRoot()); if (!inventory.getHasPro()) { builder.setPositiveButton( R.string.upgrade_to_pro, diff --git a/app/src/main/java/org/tasks/dialogs/IconPickerHolder.java b/app/src/main/java/org/tasks/dialogs/IconPickerHolder.java index 3f3387849..e41e589b9 100644 --- a/app/src/main/java/org/tasks/dialogs/IconPickerHolder.java +++ b/app/src/main/java/org/tasks/dialogs/IconPickerHolder.java @@ -1,40 +1,36 @@ package org.tasks.dialogs; import android.content.Context; -import android.view.View; import android.widget.Toast; -import androidx.annotation.NonNull; + import androidx.appcompat.widget.AppCompatImageView; import androidx.recyclerview.widget.RecyclerView; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; + import org.tasks.Callback; import org.tasks.R; +import org.tasks.databinding.DialogIconPickerCellBinding; import org.tasks.themes.DrawableUtil; public class IconPickerHolder extends RecyclerView.ViewHolder { private final Context context; private final Callback onClick; - - @BindView(R.id.icon) - AppCompatImageView imageView; + private final AppCompatImageView imageView; private int index; private boolean isEnabled; - IconPickerHolder(Context context, @NonNull View view, Callback onClick) { - super(view); + IconPickerHolder(Context context, DialogIconPickerCellBinding binding, Callback onClick) { + super(binding.getRoot()); - ButterKnife.bind(this, view); + imageView = binding.icon; + imageView.setOnClickListener(v -> onClick()); this.context = context; this.onClick = onClick; } - @OnClick(R.id.icon) - void onClick() { + private void onClick() { if (isEnabled) { onClick.call(index); } else { diff --git a/app/src/main/java/org/tasks/dialogs/RecordAudioDialog.java b/app/src/main/java/org/tasks/dialogs/RecordAudioDialog.java index 4820efb3e..93e522680 100644 --- a/app/src/main/java/org/tasks/dialogs/RecordAudioDialog.java +++ b/app/src/main/java/org/tasks/dialogs/RecordAudioDialog.java @@ -8,27 +8,29 @@ import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; import android.widget.Chronometer; + import androidx.annotation.NonNull; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; + import com.todoroo.astrid.voice.AACRecorder; -import dagger.hilt.android.AndroidEntryPoint; -import java.io.IOException; -import javax.inject.Inject; + import org.tasks.R; +import org.tasks.databinding.AacRecordActivityBinding; import org.tasks.preferences.FragmentPermissionRequestor; import org.tasks.preferences.PermissionChecker; import org.tasks.preferences.PermissionRequestor; import org.tasks.preferences.Preferences; import org.tasks.themes.Theme; +import java.io.IOException; + +import javax.inject.Inject; + +import dagger.hilt.android.AndroidEntryPoint; + @AndroidEntryPoint public class RecordAudioDialog extends DialogFragment implements AACRecorder.AACRecorderCallbacks { @@ -38,9 +40,7 @@ public class RecordAudioDialog extends DialogFragment implements AACRecorder.AAC @Inject FragmentPermissionRequestor permissionRequestor; @Inject PermissionChecker permissionChecker; - @BindView(R.id.timer) - Chronometer timer; - + private Chronometer timer; private AACRecorder recorder; static RecordAudioDialog newRecordAudioDialog(Fragment target, int requestCode) { @@ -52,10 +52,10 @@ public class RecordAudioDialog extends DialogFragment implements AACRecorder.AAC @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - LayoutInflater layoutInflater = theme.getLayoutInflater(getContext()); - View view = layoutInflater.inflate(R.layout.aac_record_activity, null); - ButterKnife.bind(this, view); - + AacRecordActivityBinding binding = + AacRecordActivityBinding.inflate(theme.getLayoutInflater(getContext())); + timer = binding.timer; + binding.stopRecording.setOnClickListener(v -> stopRecording()); recorder = new ViewModelProvider(this).get(AACRecorder.class); recorder.init(this, preferences); @@ -67,7 +67,7 @@ public class RecordAudioDialog extends DialogFragment implements AACRecorder.AAC return dialogBuilder .newDialog(R.string.audio_recording_title) - .setView(view) + .setView(binding.getRoot()) .create(); } @@ -88,8 +88,7 @@ public class RecordAudioDialog extends DialogFragment implements AACRecorder.AAC stopRecording(); } - @OnClick(R.id.stop_recording) - void stopRecording() { + private void stopRecording() { recorder.stopRecording(); timer.stop(); } diff --git a/app/src/main/java/org/tasks/dialogs/StartDatePicker.kt b/app/src/main/java/org/tasks/dialogs/StartDatePicker.kt index ae290da12..6d90682fb 100644 --- a/app/src/main/java/org/tasks/dialogs/StartDatePicker.kt +++ b/app/src/main/java/org/tasks/dialogs/StartDatePicker.kt @@ -8,8 +8,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import butterknife.ButterKnife -import butterknife.OnClick import com.todoroo.andlib.utility.DateUtilities import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.data.Task @@ -71,7 +69,6 @@ class StartDatePicker : BaseDateTimePicker() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { binding = DialogStartDatePickerBinding.inflate(theme.getLayoutInflater(requireContext())) setupShortcutsAndCalendar() - ButterKnife.bind(this, binding.root) binding.calendarView.setOnDateChangeListener { _, y, m, d -> returnDate(day = DateTime(y, m + 1, d).millis) refreshButtons() @@ -82,7 +79,21 @@ class StartDatePicker : BaseDateTimePicker() { ?: requireArguments().getInt(EXTRA_TIME) .takeIf { Task.hasDueTime(it.toLong()) } ?: NO_TIME - + with(binding.shortcuts) { + noDateButton.setOnClickListener { clearDate() } + noTime.setOnClickListener { clearTime() } + dueDateButton.setOnClickListener { setToday() } + dayBeforeDueButton.setOnClickListener { setTomorrow() } + weekBeforeDueButton.setOnClickListener { setNextWeek() } + morningButton.setOnClickListener { setMorning() } + afternoonButton.setOnClickListener { setAfternoon() } + eveningButton.setOnClickListener { setEvening() } + nightButton.setOnClickListener { setNight() } + dueTimeButton.setOnClickListener { setDueTime() } + currentDateSelection.setOnClickListener { currentDate() } + currentTimeSelection.setOnClickListener { currentTime() } + pickTimeButton.setOnClickListener { pickTime() } + } return binding.root } @@ -128,50 +139,25 @@ class StartDatePicker : BaseDateTimePicker() { } } - @OnClick(R.id.no_date_button) - fun clearDate() = returnDate(day = 0, time = 0) - - @OnClick(R.id.no_time) - fun clearTime() = returnDate( + private fun clearDate() = returnDate(day = 0, time = 0) + private fun clearTime() = returnDate( day = when (selectedDay) { DUE_TIME -> DUE_DATE else -> selectedDay }, time = 0 ) - - @OnClick(R.id.due_date_button) - fun setToday() = returnDate(day = DUE_DATE) - - @OnClick(R.id.day_before_due_button) - fun setTomorrow() = returnDate(day = DAY_BEFORE_DUE) - - @OnClick(R.id.week_before_due_button) - fun setNextWeek() = returnDate(day = WEEK_BEFORE_DUE) - - @OnClick(R.id.morning_button) - fun setMorning() = returnSelectedTime(morning) - - @OnClick(R.id.afternoon_button) - fun setAfternoon() = returnSelectedTime(afternoon) - - @OnClick(R.id.evening_button) - fun setEvening() = returnSelectedTime(evening) - - @OnClick(R.id.night_button) - fun setNight() = returnSelectedTime(night) - - @OnClick(R.id.due_time_button) - fun setDueTime() = returnDate(day = DUE_TIME, time = NO_TIME) - - @OnClick(R.id.current_date_selection) - fun currentDate() = returnDate(day = customDate) - - @OnClick(R.id.current_time_selection) - fun currentTime() = returnSelectedTime(customTime) - - @OnClick(R.id.pick_time_button) - fun pickTime() { + private fun setToday() = returnDate(day = DUE_DATE) + private fun setTomorrow() = returnDate(day = DAY_BEFORE_DUE) + private fun setNextWeek() = returnDate(day = WEEK_BEFORE_DUE) + private fun setMorning() = returnSelectedTime(morning) + private fun setAfternoon() = returnSelectedTime(afternoon) + private fun setEvening() = returnSelectedTime(evening) + private fun setNight() = returnSelectedTime(night) + private fun setDueTime() = returnDate(day = DUE_TIME, time = NO_TIME) + private fun currentDate() = returnDate(day = customDate) + private fun currentTime() = returnSelectedTime(customTime) + private fun pickTime() { val time = if (selectedTime < 0 || !Task.hasDueTime(today.withMillisOfDay(selectedTime).millis)) { today.noon().millisOfDay } else { diff --git a/app/src/main/java/org/tasks/etebase/EtebaseAccountSettingsActivity.kt b/app/src/main/java/org/tasks/etebase/EtebaseAccountSettingsActivity.kt index dea6e544f..6932ea2e2 100644 --- a/app/src/main/java/org/tasks/etebase/EtebaseAccountSettingsActivity.kt +++ b/app/src/main/java/org/tasks/etebase/EtebaseAccountSettingsActivity.kt @@ -5,7 +5,6 @@ import android.os.Bundle import android.view.View import androidx.activity.viewModels import androidx.appcompat.widget.Toolbar -import butterknife.OnCheckedChanged import com.todoroo.astrid.data.Task import com.todoroo.astrid.helper.UUIDHelper import dagger.hilt.android.AndroidEntryPoint @@ -28,6 +27,9 @@ class EtebaseAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool super.onCreate(savedInstanceState) binding.repeat.visibility = View.GONE binding.showAdvanced.visibility = View.VISIBLE + binding.showAdvanced.setOnCheckedChangeListener { _, _ -> + updateUrlVisibility() + } updateUrlVisibility() } @@ -71,11 +73,6 @@ class EtebaseAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool saveAccountAndFinish() } - @OnCheckedChanged(R.id.show_advanced) - fun toggleUrl() { - updateUrlVisibility() - } - private fun updateUrlVisibility() { binding.urlLayout.visibility = if (binding.showAdvanced.isChecked) View.VISIBLE else View.GONE } diff --git a/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt b/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt index 5fc90015e..a85defcc1 100644 --- a/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt +++ b/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt @@ -7,10 +7,9 @@ import android.view.MenuItem import android.view.View import androidx.activity.viewModels import androidx.appcompat.widget.Toolbar +import androidx.core.widget.addTextChangedListener import androidx.lifecycle.lifecycleScope import at.bitfire.dav4jvm.exception.HttpException -import butterknife.ButterKnife -import butterknife.OnTextChanged import com.etesync.journalmanager.Constants.Companion.CURRENT_VERSION import com.etesync.journalmanager.Crypto.CryptoManager import com.etesync.journalmanager.Crypto.deriveKey @@ -45,7 +44,6 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O super.onCreate(savedInstanceState) binding = ActivityEtesyncEncryptionSettingsBinding.inflate(layoutInflater) setContentView(binding.root) - ButterKnife.bind(this) val intent = intent caldavAccount = intent.getParcelableExtra(EXTRA_ACCOUNT) userInfo = intent.getSerializableExtra(EXTRA_USER_INFO) as UserInfoManager.UserInfo @@ -64,6 +62,12 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O if (createUserInfoViewModel.inProgress) { showProgressIndicator() } + binding.repeatEncryptionPassword.addTextChangedListener( + onTextChanged = { _, _, _, _ -> onRepeatEncryptionPasswordChanged() } + ) + binding.encryptionPassword.addTextChangedListener( + onTextChanged = { _, _, _, _ -> onEncryptionPasswordChanged() } + ) } private fun showProgressIndicator() { @@ -153,13 +157,11 @@ class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.O return snackbar } - @OnTextChanged(R.id.repeat_encryption_password) - fun onRpeatEncryptionPasswordChanged() { + private fun onRepeatEncryptionPasswordChanged() { binding.repeatEncryptionPasswordLayout.error = null } - @OnTextChanged(R.id.encryption_password) - fun onEncryptionPasswordChanged() { + private fun onEncryptionPasswordChanged() { binding.encryptionPasswordLayout.error = null } diff --git a/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt b/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt index ee48aaa5b..02141f35b 100644 --- a/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt +++ b/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt @@ -9,7 +9,6 @@ import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat import androidx.core.util.Pair import androidx.lifecycle.lifecycleScope -import butterknife.OnCheckedChanged import com.etesync.journalmanager.Crypto.CryptoManager import com.etesync.journalmanager.Exceptions.IntegrityException import com.etesync.journalmanager.Exceptions.VersionTooNewException @@ -41,6 +40,7 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool binding.description.visibility = View.VISIBLE binding.description.setTextColor(ContextCompat.getColor(this, R.color.overdue)) binding.description.setText(description) + binding.showAdvanced.setOnCheckedChangeListener { _, _ -> updateUrlVisibility() } updateUrlVisibility() } @@ -108,11 +108,6 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool return false } - @OnCheckedChanged(R.id.show_advanced) - fun toggleUrl() { - updateUrlVisibility() - } - private fun updateUrlVisibility() { binding.urlLayout.visibility = if (binding.showAdvanced.isChecked) View.VISIBLE else View.GONE } diff --git a/app/src/main/java/org/tasks/fragments/CommentBarFragment.kt b/app/src/main/java/org/tasks/fragments/CommentBarFragment.kt index 381ca9c5c..a2b7e5539 100644 --- a/app/src/main/java/org/tasks/fragments/CommentBarFragment.kt +++ b/app/src/main/java/org/tasks/fragments/CommentBarFragment.kt @@ -14,12 +14,13 @@ import android.view.inputmethod.EditorInfo import android.widget.EditText import android.widget.ImageView import android.widget.LinearLayout -import butterknife.* +import androidx.core.widget.addTextChangedListener import com.todoroo.andlib.utility.AndroidUtilities import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.activities.CameraActivity +import org.tasks.databinding.FragmentCommentBarBinding import org.tasks.dialogs.DialogBuilder import org.tasks.files.ImageHelper import org.tasks.preferences.Device @@ -37,18 +38,10 @@ class CommentBarFragment : TaskEditControlFragment() { @Inject lateinit var preferences: Preferences @Inject lateinit var themeColor: ThemeColor - @BindView(R.id.commentButton) - lateinit var commentButton: View - - @BindView(R.id.commentField) - lateinit var commentField: EditText - - @BindView(R.id.picture) - lateinit var pictureButton: ImageView - - @BindView(R.id.updatesFooter) - lateinit var commentBar: LinearLayout - + private lateinit var commentButton: View + private lateinit var commentField: EditText + private lateinit var pictureButton: ImageView + private lateinit var commentBar: LinearLayout private lateinit var callback: CommentBarFragmentCallback private var pendingCommentPicture: Uri? = null @@ -59,8 +52,7 @@ class CommentBarFragment : TaskEditControlFragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - val view = inflater.inflate(layout, container, false) - ButterKnife.bind(this, view) + val view = bind(container) createView(savedInstanceState) return view } @@ -83,19 +75,33 @@ class CommentBarFragment : TaskEditControlFragment() { resetPictureButton() } - override val layout = R.layout.fragment_comment_bar + override fun bind(parent: ViewGroup?) = + FragmentCommentBarBinding.inflate(layoutInflater, parent, false).let { + commentButton = it.commentButton.apply { + setOnClickListener { addClicked() } + } + commentField = it.commentField.apply { + addTextChangedListener( + onTextChanged = { text, _, _, _ -> onTextChanged(text?.toString()) } + ) + setOnEditorActionListener { _, _, event -> onEditorAction(event) } + } + pictureButton = it.picture.apply { + setOnClickListener { onClickPicture() } + } + commentBar = it.updatesFooter + it.root + } override val icon = 0 override fun controlId() = TAG - @OnTextChanged(R.id.commentField) - fun onTextChanged(s: CharSequence) { + private fun onTextChanged(s: String?) { commentButton.visibility = if (pendingCommentPicture == null && isNullOrEmpty(s.toString())) View.GONE else View.VISIBLE } - @OnEditorAction(R.id.commentField) - fun onEditorAction(key: KeyEvent?): Boolean { + private fun onEditorAction(key: KeyEvent?): Boolean { val actionId = key?.action ?: 0 if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_NULL) { if (commentField.text.isNotEmpty() || pendingCommentPicture != null) { @@ -106,8 +112,7 @@ class CommentBarFragment : TaskEditControlFragment() { return false } - @OnClick(R.id.commentButton) - fun addClicked() { + private fun addClicked() { addComment() } @@ -119,8 +124,7 @@ class CommentBarFragment : TaskEditControlFragment() { } } - @OnClick(R.id.picture) - fun onClickPicture() { + private fun onClickPicture() { if (pendingCommentPicture == null) { showPictureLauncher(null) } else { diff --git a/app/src/main/java/org/tasks/location/LocationPickerActivity.kt b/app/src/main/java/org/tasks/location/LocationPickerActivity.kt index ac6a9ab4b..7326fbb0a 100644 --- a/app/src/main/java/org/tasks/location/LocationPickerActivity.kt +++ b/app/src/main/java/org/tasks/location/LocationPickerActivity.kt @@ -16,9 +16,6 @@ import androidx.lifecycle.Observer import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import butterknife.OnClick import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener @@ -41,6 +38,7 @@ import org.tasks.data.LocationDao import org.tasks.data.Place import org.tasks.data.Place.Companion.newPlace import org.tasks.data.PlaceUsage +import org.tasks.databinding.ActivityLocationPickerBinding import org.tasks.dialogs.DialogBuilder import org.tasks.extensions.Context.toast import org.tasks.injection.InjectingAppCompatActivity @@ -60,29 +58,14 @@ import kotlin.math.abs @AndroidEntryPoint class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemClickListener, MapFragmentCallback, OnLocationPicked, SearchView.OnQueryTextListener, OnPredictionPicked, MenuItem.OnActionExpandListener { - @BindView(R.id.toolbar) - lateinit var toolbar: Toolbar - - @BindView(R.id.app_bar_layout) - lateinit var appBarLayout: AppBarLayout - - @BindView(R.id.collapsing_toolbar_layout) - lateinit var toolbarLayout: CollapsingToolbarLayout - - @BindView(R.id.coordinator) - lateinit var coordinatorLayout: CoordinatorLayout - - @BindView(R.id.search) - lateinit var searchView: View - - @BindView(R.id.loading_indicator) - lateinit var loadingIndicator: ContentLoadingProgressBar - - @BindView(R.id.choose_recent_location) - lateinit var chooseRecentLocation: View - - @BindView(R.id.recent_locations) - lateinit var recyclerView: RecyclerView + private lateinit var toolbar: Toolbar + private lateinit var appBarLayout: AppBarLayout + private lateinit var toolbarLayout: CollapsingToolbarLayout + private lateinit var coordinatorLayout: CoordinatorLayout + private lateinit var searchView: View + private lateinit var loadingIndicator: ContentLoadingProgressBar + private lateinit var chooseRecentLocation: View + private lateinit var recyclerView: RecyclerView @Inject lateinit var theme: Theme @Inject lateinit var locationDao: LocationDao @@ -110,8 +93,18 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) theme.applyTheme(this) - setContentView(R.layout.activity_location_picker) - ButterKnife.bind(this) + val binding = ActivityLocationPickerBinding.inflate(layoutInflater) + setContentView(binding.root) + toolbar = binding.toolbar + appBarLayout = binding.appBarLayout + toolbarLayout = binding.collapsingToolbarLayout + coordinatorLayout = binding.coordinator + searchView = binding.search.apply { + setOnClickListener { searchPlace() } + } + loadingIndicator = binding.loadingIndicator + chooseRecentLocation = binding.chooseRecentLocation + recyclerView = binding.recentLocations val configuration = resources.configuration if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE && configuration.smallestScreenWidthDp < 480) { @@ -180,6 +173,9 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC recentsAdapter!!.setHasStableIds(true) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = if (search.isActionViewExpanded) searchAdapter else recentsAdapter + + binding.currentLocation.setOnClickListener { currentLocation() } + binding.selectThisLocation.setOnClickListener { selectLocation() } } override fun onMapReady(mapFragment: MapFragment) { @@ -211,8 +207,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC returnPlace(place) } - @OnClick(R.id.current_location) - fun onClick() { + private fun currentLocation() { if (permissionRequestor.requestForegroundLocation()) { moveToCurrentLocation(true) } @@ -236,8 +231,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC } } - @OnClick(R.id.select_this_location) - fun selectLocation() { + private fun selectLocation() { val mapPosition = map.mapPosition ?: return loadingIndicator.visibility = View.VISIBLE lifecycleScope.launch { @@ -251,8 +245,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC } } - @OnClick(R.id.search) - fun searchPlace() { + private fun searchPlace() { mapPosition = map.mapPosition expandToolbar(true) search.expandActionView() diff --git a/app/src/main/java/org/tasks/opentasks/OpenTasksListSettingsActivity.kt b/app/src/main/java/org/tasks/opentasks/OpenTasksListSettingsActivity.kt index ca1955dc7..fd0fd56e6 100644 --- a/app/src/main/java/org/tasks/opentasks/OpenTasksListSettingsActivity.kt +++ b/app/src/main/java/org/tasks/opentasks/OpenTasksListSettingsActivity.kt @@ -2,8 +2,6 @@ package org.tasks.opentasks import android.os.Bundle import android.view.View -import android.widget.RelativeLayout -import butterknife.BindView import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.caldav.BaseCaldavCalendarSettingsActivity @@ -13,9 +11,6 @@ import org.tasks.data.CaldavCalendar @AndroidEntryPoint class OpenTasksListSettingsActivity : BaseCaldavCalendarSettingsActivity() { - @BindView(R.id.color_row) - lateinit var colorRow: RelativeLayout - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/org/tasks/preferences/beast/BeastModeRecyclerAdapter.java b/app/src/main/java/org/tasks/preferences/beast/BeastModeRecyclerAdapter.java index 4ec59aab4..d09af5a62 100644 --- a/app/src/main/java/org/tasks/preferences/beast/BeastModeRecyclerAdapter.java +++ b/app/src/main/java/org/tasks/preferences/beast/BeastModeRecyclerAdapter.java @@ -3,15 +3,18 @@ package org.tasks.preferences.beast; import android.content.Context; import android.content.res.Resources; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; + import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; + +import org.tasks.R; +import org.tasks.databinding.PreferenceDraggableRowBinding; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; -import org.tasks.R; public class BeastModeRecyclerAdapter extends RecyclerView.Adapter { @@ -42,10 +45,10 @@ public class BeastModeRecyclerAdapter extends RecyclerView.Adapter repeatUntilAdapter; private ToggleButton[] weekButtons; @@ -159,7 +120,8 @@ public class CustomRecurrenceDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { LayoutInflater inflater = LayoutInflater.from(context); - View dialogView = inflater.inflate(R.layout.control_set_repeat, null); + ControlSetRepeatBinding binding = ControlSetRepeatBinding.inflate(inflater); + WeekButtonsBinding weekBinding = WeekButtonsBinding.bind(binding.getRoot()); Bundle arguments = getArguments(); dueDate = arguments.getLong(EXTRA_DATE, currentTimeMillis()); @@ -183,7 +145,45 @@ public class CustomRecurrenceDialog extends DialogFragment { DateFormatSymbols dfs = new DateFormatSymbols(locale.getLocale()); String[] shortWeekdays = dfs.getShortWeekdays(); - ButterKnife.bind(this, dialogView); + weekGroup1 = weekBinding.weekGroup; + weekGroup2 = weekBinding.weekGroup2; + monthGroup = binding.monthGroup; + repeatMonthlyDayOfNthWeek = binding.repeatMonthlyDayOfNthWeek; + repeatMonthlyDayOfLastWeek = binding.repeatMonthlyDayOfLastWeek; + repeatUntilSpinner = binding.repeatUntil; + repeatUntilSpinner.setOnItemSelectedListener(new OnItemSelected() { + @Override + public void onItemSelected(int position) { + onRepeatUntilChanged(position); + } + }); + intervalEditText = binding.intervalValue; + intervalEditText.addTextChangedListener(new OnTextChanged() { + @Override + public void onTextChanged(@Nullable CharSequence text) { + if (text != null) { + onRepeatValueChanged(text); + } + } + }); + intervalTextView = binding.intervalText; + repeatTimes = binding.repeatTimesValue; + repeatTimes.addTextChangedListener(new OnTextChanged() { + @Override + public void onTextChanged(@Nullable CharSequence text) { + if (text != null) { + onRepeatTimesValueChanged(text); + } + } + }); + repeatTimesText = binding.repeatTimesText; + AppCompatSpinner frequency = binding.frequency; + frequency.setOnItemSelectedListener(new OnItemSelected() { + @Override + public void onItemSelected(int position) { + onFrequencyChanged(position); + } + }); Calendar dayOfMonthCalendar = Calendar.getInstance(locale.getLocale()); dayOfMonthCalendar.setTimeInMillis(dueDate); @@ -233,14 +233,14 @@ public class CustomRecurrenceDialog extends DialogFragment { } if (monthGroup.getCheckedRadioButtonId() != R.id.repeat_monthly_day_of_last_week && monthGroup.getCheckedRadioButtonId() != R.id.repeat_monthly_day_of_nth_week) { - repeatMonthlySameDay.setChecked(true); + binding.repeatMonthlySameDay.setChecked(true); } ArrayAdapter frequencyAdapter = ArrayAdapter.createFromResource(context, R.array.repeat_frequency, R.layout.frequency_item); frequencyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - frequencySpinner.setAdapter(frequencyAdapter); - frequencySpinner.setSelection(FREQUENCIES.indexOf(rrule.getFrequency())); + frequency.setAdapter(frequencyAdapter); + frequency.setSelection(FREQUENCIES.indexOf(rrule.getFrequency())); intervalEditText.setText(locale.formatNumber(rrule.getInterval())); @@ -273,7 +273,15 @@ public class CustomRecurrenceDialog extends DialogFragment { repeatUntilSpinner.setAdapter(repeatUntilAdapter); updateRepeatUntilOptions(); - weekButtons = new ToggleButton[] {day1, day2, day3, day4, day5, day6, day7}; + weekButtons = new ToggleButton[]{ + weekBinding.weekDay1.button, + weekBinding.weekDay2.button, + weekBinding.weekDay3.button, + weekBinding.weekDay4.button, + weekBinding.weekDay5.button, + weekBinding.weekDay6.button, + weekBinding.weekDay7.button + }; // set up days of week Calendar dayOfWeekCalendar = Calendar.getInstance(locale.getLocale()); @@ -336,7 +344,7 @@ public class CustomRecurrenceDialog extends DialogFragment { return dialogBuilder .newDialog() - .setView(dialogView) + .setView(binding.getRoot()) .setPositiveButton(R.string.ok, this::onRuleSelected) .setNegativeButton(R.string.cancel, null) .show(); @@ -448,8 +456,7 @@ public class CustomRecurrenceDialog extends DialogFragment { } } - @OnItemSelected(R.id.repeat_until) - public void onRepeatUntilChanged(int position) { + private void onRepeatUntilChanged(int position) { if (repeatUntilOptions.size() == 4) { position--; } @@ -466,8 +473,7 @@ public class CustomRecurrenceDialog extends DialogFragment { } } - @OnItemSelected(R.id.frequency) - public void onFrequencyChanged(int position) { + private void onFrequencyChanged(int position) { Frequency frequency = FREQUENCIES.get(position); rrule.setFrequency(frequency.name()); int weekVisibility = frequency == WEEKLY ? View.VISIBLE : View.GONE; @@ -479,8 +485,7 @@ public class CustomRecurrenceDialog extends DialogFragment { updateIntervalTextView(); } - @OnTextChanged(R.id.intervalValue) - public void onRepeatValueChanged(CharSequence text) { + private void onRepeatValueChanged(CharSequence text) { Integer value = locale.parseInteger(text.toString()); if (value == null) { return; @@ -492,8 +497,7 @@ public class CustomRecurrenceDialog extends DialogFragment { } } - @OnTextChanged(R.id.repeatTimesValue) - public void onRepeatTimesValueChanged(CharSequence text) { + private void onRepeatTimesValueChanged(CharSequence text) { Integer value = locale.parseInteger(text.toString()); if (value == null) { return; diff --git a/app/src/main/java/org/tasks/tags/TagPickerActivity.kt b/app/src/main/java/org/tasks/tags/TagPickerActivity.kt index 1da169738..dfbcaf6c8 100644 --- a/app/src/main/java/org/tasks/tags/TagPickerActivity.kt +++ b/app/src/main/java/org/tasks/tags/TagPickerActivity.kt @@ -5,20 +5,17 @@ import android.content.Intent import android.os.Bundle import android.widget.EditText import androidx.activity.viewModels -import androidx.appcompat.widget.Toolbar +import androidx.core.widget.addTextChangedListener import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import butterknife.OnTextChanged import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.billing.Inventory import org.tasks.data.TagData +import org.tasks.databinding.ActivityTagPickerBinding import org.tasks.injection.ThemedInjectingAppCompatActivity import org.tasks.themes.ColorProvider import org.tasks.themes.Theme @@ -27,19 +24,13 @@ import javax.inject.Inject @AndroidEntryPoint class TagPickerActivity : ThemedInjectingAppCompatActivity() { - @BindView(R.id.toolbar) - lateinit var toolbar: Toolbar - @BindView(R.id.recycler_view) - lateinit var recyclerView: RecyclerView - @BindView(R.id.search_input) - lateinit var editText: EditText - @Inject lateinit var theme: Theme @Inject lateinit var inventory: Inventory @Inject lateinit var colorProvider: ColorProvider private val viewModel: TagPickerViewModel by viewModels() private var taskIds: ArrayList? = null + private lateinit var editText: EditText override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -53,8 +44,14 @@ class TagPickerActivity : ThemedInjectingAppCompatActivity() { ) } } - setContentView(R.layout.activity_tag_picker) - ButterKnife.bind(this) + val binding = ActivityTagPickerBinding.inflate(layoutInflater) + editText = binding.searchInput.apply { + addTextChangedListener( + onTextChanged = { text, _, _, _ -> onSearch(text) } + ) + } + setContentView(binding.root) + val toolbar = binding.toolbar toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px) toolbar.setNavigationOnClickListener { onBackPressed() } val themeColor = theme.themeColor @@ -64,6 +61,7 @@ class TagPickerActivity : ThemedInjectingAppCompatActivity() { val recyclerAdapter = TagRecyclerAdapter(this, viewModel, inventory, colorProvider) { tagData, vh -> onToggle(tagData, vh) } + val recyclerView = binding.recyclerView recyclerView.adapter = recyclerAdapter (recyclerView.itemAnimator as DefaultItemAnimator?)!!.supportsChangeAnimations = false recyclerView.layoutManager = LinearLayoutManager(this) @@ -80,9 +78,8 @@ class TagPickerActivity : ThemedInjectingAppCompatActivity() { } } - @OnTextChanged(R.id.search_input) - fun onSearch(text: CharSequence) { - viewModel.search(text.toString()) + private fun onSearch(text: CharSequence?) { + viewModel.search(text?.toString() ?: "") } override fun onBackPressed() { diff --git a/app/src/main/java/org/tasks/tags/TagPickerViewHolder.kt b/app/src/main/java/org/tasks/tags/TagPickerViewHolder.kt index 194d25e6d..f42224830 100644 --- a/app/src/main/java/org/tasks/tags/TagPickerViewHolder.kt +++ b/app/src/main/java/org/tasks/tags/TagPickerViewHolder.kt @@ -4,34 +4,27 @@ import android.content.Context import android.view.View import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.ButterKnife -import butterknife.OnCheckedChanged -import butterknife.OnClick import org.tasks.R import org.tasks.data.TagData -import org.tasks.tags.CheckBoxTriStates +import org.tasks.databinding.RowTagPickerBinding import org.tasks.themes.DrawableUtil class TagPickerViewHolder internal constructor( - private val context: Context, - view: View, - private val callback: (TagData, TagPickerViewHolder) -> Unit -) : RecyclerView.ViewHolder(view) { + private val context: Context, + binding: RowTagPickerBinding, + private val callback: (TagData, TagPickerViewHolder) -> Unit +) : RecyclerView.ViewHolder(binding.root) { val isChecked: Boolean get() = checkBox.isChecked - @BindView(R.id.text) - lateinit var text: TextView - - @BindView(R.id.checkbox) - lateinit var checkBox: CheckBoxTriStates - + private val text: TextView = binding.text + private val checkBox: CheckBoxTriStates = binding.checkbox.apply { + setOnCheckedChangeListener { _, _ -> onCheckedChanged() } + } private var tagData: TagData? = null - @OnClick(R.id.tag_row) - fun onClickRow() { + private fun onClickRow() { if (tagData!!.id == null) { callback(tagData!!, this) } else { @@ -39,8 +32,7 @@ class TagPickerViewHolder internal constructor( } } - @OnCheckedChanged(R.id.checkbox) - fun onCheckedChanged() { + private fun onCheckedChanged() { callback(tagData!!, this) } @@ -73,6 +65,6 @@ class TagPickerViewHolder internal constructor( } init { - ButterKnife.bind(this, view) + binding.tagRow.setOnClickListener { onClickRow() } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/tags/TagRecyclerAdapter.kt b/app/src/main/java/org/tasks/tags/TagRecyclerAdapter.kt index 45eb510c9..4ea39ac33 100644 --- a/app/src/main/java/org/tasks/tags/TagRecyclerAdapter.kt +++ b/app/src/main/java/org/tasks/tags/TagRecyclerAdapter.kt @@ -8,6 +8,7 @@ import androidx.recyclerview.widget.RecyclerView import org.tasks.R import org.tasks.billing.Inventory import org.tasks.data.TagData +import org.tasks.databinding.RowTagPickerBinding import org.tasks.themes.ColorProvider import org.tasks.themes.CustomIcons.getIconResId @@ -21,10 +22,12 @@ internal class TagRecyclerAdapter( private val differ: AsyncListDiffer = AsyncListDiffer(this, TagDiffCallback()) - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TagPickerViewHolder { - val view = LayoutInflater.from(context).inflate(R.layout.row_tag_picker, parent, false) - return TagPickerViewHolder(context, view, callback) - } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = + TagPickerViewHolder( + context, + RowTagPickerBinding.inflate(LayoutInflater.from(context), parent, false), + callback + ) override fun onBindViewHolder(holder: TagPickerViewHolder, position: Int) { val tagData = differ.currentList[position] diff --git a/app/src/main/java/org/tasks/tasklist/SubtaskViewHolder.java b/app/src/main/java/org/tasks/tasklist/SubtaskViewHolder.java index cca0acd09..4c0be2db6 100644 --- a/app/src/main/java/org/tasks/tasklist/SubtaskViewHolder.java +++ b/app/src/main/java/org/tasks/tasklist/SubtaskViewHolder.java @@ -6,16 +6,16 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.MarginLayoutParams; import android.widget.TextView; + import androidx.recyclerview.widget.RecyclerView; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; + import com.google.android.material.chip.Chip; import com.google.android.material.chip.ChipGroup; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.ui.CheckableImageView; -import org.tasks.R; + import org.tasks.data.TaskContainer; +import org.tasks.databinding.SubtaskAdapterRowBodyBinding; import org.tasks.ui.CheckBoxProvider; import org.tasks.ui.ChipProvider; @@ -28,31 +28,32 @@ public class SubtaskViewHolder extends RecyclerView.ViewHolder { private TaskContainer task; - @BindView(R.id.rowBody) - ViewGroup rowBody; - - @BindView(R.id.title) - TextView nameView; - - @BindView(R.id.completeBox) - CheckableImageView completeBox; - - @BindView(R.id.chip_group) - ChipGroup chipGroup; + private final ViewGroup rowBody; + private final TextView nameView; + private final CheckableImageView completeBox; + private final ChipGroup chipGroup; SubtaskViewHolder( - ViewGroup view, - Callbacks callbacks, - DisplayMetrics metrics, - ChipProvider chipProvider, - CheckBoxProvider checkBoxProvider) { - super(view); + SubtaskAdapterRowBodyBinding binding, + Callbacks callbacks, + DisplayMetrics metrics, + ChipProvider chipProvider, + CheckBoxProvider checkBoxProvider) { + super(binding.getRoot()); this.callbacks = callbacks; this.metrics = metrics; this.chipProvider = chipProvider; this.checkBoxProvider = checkBoxProvider; - ButterKnife.bind(this, view); + rowBody = binding.rowBody; + nameView = binding.title; + completeBox = binding.completeBox; + chipGroup = binding.chipGroup; + + nameView.setOnClickListener(v -> openSubtask()); + completeBox.setOnClickListener(v -> onCompleteBoxClick()); + + ViewGroup view = binding.getRoot(); view.setTag(this); for (int i = 0; i < view.getChildCount(); i++) { view.getChildAt(i).setTag(this); @@ -98,13 +99,11 @@ public class SubtaskViewHolder extends RecyclerView.ViewHolder { completeBox.invalidate(); } - @OnClick(R.id.title) - void openSubtask() { + private void openSubtask() { callbacks.openSubtask(task.getTask()); } - @OnClick(R.id.completeBox) - void onCompleteBoxClick() { + private void onCompleteBoxClick() { if (task == null) { return; } diff --git a/app/src/main/java/org/tasks/tasklist/SubtasksRecyclerAdapter.java b/app/src/main/java/org/tasks/tasklist/SubtasksRecyclerAdapter.java index 3c600d083..9a4066f0f 100644 --- a/app/src/main/java/org/tasks/tasklist/SubtasksRecyclerAdapter.java +++ b/app/src/main/java/org/tasks/tasklist/SubtasksRecyclerAdapter.java @@ -4,19 +4,22 @@ import android.app.Activity; import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.ViewGroup; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.AsyncDifferConfig; import androidx.recyclerview.widget.AsyncListDiffer; import androidx.recyclerview.widget.ListUpdateCallback; import androidx.recyclerview.widget.RecyclerView; -import java.util.List; -import org.tasks.R; + import org.tasks.data.TaskContainer; +import org.tasks.databinding.SubtaskAdapterRowBodyBinding; import org.tasks.tasklist.SubtaskViewHolder.Callbacks; import org.tasks.ui.CheckBoxProvider; import org.tasks.ui.ChipProvider; +import java.util.List; + public class SubtasksRecyclerAdapter extends RecyclerView.Adapter implements ListUpdateCallback { @@ -46,10 +49,13 @@ public class SubtasksRecyclerAdapter extends RecyclerView.Adapter textChanged(text) } + ) + } + it.root + } override val icon = R.drawable.ic_outline_notes_24px override fun controlId() = TAG - @OnTextChanged(R.id.notes) - fun textChanged(text: CharSequence) { - viewModel.description = text.toString().trim { it <= ' ' } + private fun textChanged(text: CharSequence?) { + viewModel.description = text?.toString()?.trim { it <= ' ' } } companion object { diff --git a/app/src/main/java/org/tasks/ui/ListFragment.kt b/app/src/main/java/org/tasks/ui/ListFragment.kt index 6467265f9..732290d22 100644 --- a/app/src/main/java/org/tasks/ui/ListFragment.kt +++ b/app/src/main/java/org/tasks/ui/ListFragment.kt @@ -3,21 +3,20 @@ package org.tasks.ui import android.app.Activity import android.content.Intent import android.os.Bundle -import butterknife.BindView +import android.view.ViewGroup import com.google.android.material.chip.ChipGroup import com.todoroo.astrid.api.CaldavFilter import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.GtasksFilter -import com.todoroo.astrid.service.TaskMover import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.activities.ListPicker +import org.tasks.databinding.ControlSetRemoteListBinding import javax.inject.Inject @AndroidEntryPoint class ListFragment : TaskEditControlFragment() { - @BindView(R.id.chip_group) - lateinit var chipGroup: ChipGroup + private lateinit var chipGroup: ChipGroup @Inject lateinit var chipProvider: ChipProvider @@ -42,7 +41,11 @@ class ListFragment : TaskEditControlFragment() { callback.onListChanged(filter) } - override val layout = R.layout.control_set_remote_list + override fun bind(parent: ViewGroup?) = + ControlSetRemoteListBinding.inflate(layoutInflater, parent, true).let { + chipGroup = it.chipGroup + it.root + } override val icon = R.drawable.ic_list_24px diff --git a/app/src/main/java/org/tasks/ui/LocationControlSet.kt b/app/src/main/java/org/tasks/ui/LocationControlSet.kt index a51c82c0b..19f8db0eb 100644 --- a/app/src/main/java/org/tasks/ui/LocationControlSet.kt +++ b/app/src/main/java/org/tasks/ui/LocationControlSet.kt @@ -8,17 +8,17 @@ import android.text.SpannableString import android.text.Spanned import android.text.style.ClickableSpan import android.view.View +import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.core.util.Pair -import butterknife.BindView -import butterknife.OnClick import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.data.Geofence import org.tasks.data.Location import org.tasks.data.Place +import org.tasks.databinding.LocationRowBinding import org.tasks.dialogs.DialogBuilder import org.tasks.dialogs.GeofenceDialog import org.tasks.extensions.Context.openUri @@ -39,14 +39,9 @@ class LocationControlSet : TaskEditControlFragment() { @Inject lateinit var permissionRequestor: FragmentPermissionRequestor @Inject lateinit var permissionChecker: PermissionChecker - @BindView(R.id.location_name) - lateinit var locationName: TextView - - @BindView(R.id.location_address) - lateinit var locationAddress: TextView - - @BindView(R.id.geofence_options) - lateinit var geofenceOptions: ImageView + private lateinit var locationName: TextView + private lateinit var locationAddress: TextView + private lateinit var geofenceOptions: ImageView override fun onResume() { super.onResume() @@ -123,8 +118,7 @@ class LocationControlSet : TaskEditControlFragment() { startActivityForResult(intent, REQUEST_LOCATION_REMINDER) } - @OnClick(R.id.geofence_options) - fun geofenceOptions() { + private fun geofenceOptions() { if (permissionChecker.canAccessBackgroundLocation()) { showGeofenceOptions() } else { @@ -139,7 +133,15 @@ class LocationControlSet : TaskEditControlFragment() { dialog.show(parentFragmentManager, FRAG_TAG_LOCATION_DIALOG) } - override val layout = R.layout.location_row + override fun bind(parent: ViewGroup?) = + LocationRowBinding.inflate(layoutInflater, parent, true).let { + locationName = it.locationName + locationAddress = it.locationAddress + geofenceOptions = it.geofenceOptions.apply { + setOnClickListener { geofenceOptions() } + } + it.root + } override val icon = R.drawable.ic_outline_place_24px diff --git a/app/src/main/java/org/tasks/ui/OnItemSelected.kt b/app/src/main/java/org/tasks/ui/OnItemSelected.kt new file mode 100644 index 000000000..86a80751c --- /dev/null +++ b/app/src/main/java/org/tasks/ui/OnItemSelected.kt @@ -0,0 +1,12 @@ +package org.tasks.ui + +import android.view.View +import android.widget.AdapterView + +abstract class OnItemSelected : AdapterView.OnItemSelectedListener { + final override fun onNothingSelected(parent: AdapterView<*>?) {} + final override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) = + onItemSelected(position) + + abstract fun onItemSelected(position: Int) +} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/ui/OnTextChanged.kt b/app/src/main/java/org/tasks/ui/OnTextChanged.kt new file mode 100644 index 000000000..44b948a0d --- /dev/null +++ b/app/src/main/java/org/tasks/ui/OnTextChanged.kt @@ -0,0 +1,13 @@ +package org.tasks.ui + +import android.text.Editable +import android.text.TextWatcher + +abstract class OnTextChanged : TextWatcher { + final override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + final override fun afterTextChanged(s: Editable?) {} + final override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = + onTextChanged(s) + + abstract fun onTextChanged(text: CharSequence?) +} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/ui/PriorityControlSet.kt b/app/src/main/java/org/tasks/ui/PriorityControlSet.kt index d591fd7d7..767ade5c0 100644 --- a/app/src/main/java/org/tasks/ui/PriorityControlSet.kt +++ b/app/src/main/java/org/tasks/ui/PriorityControlSet.kt @@ -2,12 +2,12 @@ package org.tasks.ui import android.content.res.ColorStateList import android.os.Bundle +import android.view.ViewGroup import androidx.appcompat.widget.AppCompatRadioButton -import butterknife.BindView -import butterknife.OnClick import com.todoroo.astrid.data.Task import dagger.hilt.android.AndroidEntryPoint import org.tasks.R +import org.tasks.databinding.ControlSetPriorityBinding import org.tasks.themes.ColorProvider import javax.inject.Inject @@ -15,20 +15,12 @@ import javax.inject.Inject class PriorityControlSet : TaskEditControlFragment() { @Inject lateinit var colorProvider: ColorProvider - @BindView(R.id.priority_high) - lateinit var priorityHigh: AppCompatRadioButton + private lateinit var priorityHigh: AppCompatRadioButton + private lateinit var priorityMedium: AppCompatRadioButton + private lateinit var priorityLow: AppCompatRadioButton + private lateinit var priorityNone: AppCompatRadioButton - @BindView(R.id.priority_medium) - lateinit var priorityMedium: AppCompatRadioButton - - @BindView(R.id.priority_low) - lateinit var priorityLow: AppCompatRadioButton - - @BindView(R.id.priority_none) - lateinit var priorityNone: AppCompatRadioButton - - @OnClick(R.id.priority_high, R.id.priority_medium, R.id.priority_low, R.id.priority_none) - fun onPriorityChanged() { + private fun onPriorityChanged() { viewModel.priority = getPriority() } @@ -45,7 +37,22 @@ class PriorityControlSet : TaskEditControlFragment() { tintRadioButton(priorityNone, 3) } - override val layout = R.layout.control_set_priority + override fun bind(parent: ViewGroup?) = + ControlSetPriorityBinding.inflate(layoutInflater, parent, true).let { + priorityHigh = it.priorityHigh.apply { + setOnClickListener { onPriorityChanged() } + } + priorityMedium = it.priorityMedium.apply { + setOnClickListener { onPriorityChanged() } + } + priorityLow = it.priorityLow.apply { + setOnClickListener { onPriorityChanged() } + } + priorityNone = it.priorityNone.apply { + setOnClickListener { onPriorityChanged() } + } + it.root + } override val icon = R.drawable.ic_outline_flag_24px diff --git a/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt b/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt index 221ef9797..c77689cc7 100644 --- a/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt +++ b/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt @@ -20,8 +20,6 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import butterknife.BindView -import butterknife.OnClick import com.todoroo.andlib.sql.Criterion import com.todoroo.andlib.sql.Join import com.todoroo.andlib.sql.QueryTemplate @@ -40,6 +38,7 @@ import org.tasks.LocalBroadcastManager import org.tasks.R import org.tasks.data.* import org.tasks.data.TaskDao.TaskCriteria.activeAndVisible +import org.tasks.databinding.ControlSetSubtasksBinding import org.tasks.extensions.Context.toast import org.tasks.locale.Locale import org.tasks.tasklist.SubtaskViewHolder @@ -48,11 +47,8 @@ import javax.inject.Inject @AndroidEntryPoint class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks { - @BindView(R.id.recycler_view) - lateinit var recyclerView: RecyclerView - - @BindView(R.id.new_subtasks) - lateinit var newSubtaskContainer: LinearLayout + private lateinit var recyclerView: RecyclerView + private lateinit var newSubtaskContainer: LinearLayout @Inject lateinit var activity: Activity @Inject lateinit var taskCompleter: TaskCompleter @@ -89,7 +85,13 @@ class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks } } - override val layout = R.layout.control_set_subtasks + override fun bind(parent: ViewGroup?) = + ControlSetSubtasksBinding.inflate(layoutInflater, parent, true).let { + recyclerView = it.recyclerView + newSubtaskContainer = it.newSubtasks + it.addSubtask.setOnClickListener { addSubtask() } + it.root + } override val icon = R.drawable.ic_subdirectory_arrow_right_black_24dp @@ -111,8 +113,7 @@ class SubtaskControlSet : TaskEditControlFragment(), SubtaskViewHolder.Callbacks localBroadcastManager.unregisterReceiver(refreshReceiver) } - @OnClick(R.id.add_subtask) - fun addSubtask() { + private fun addSubtask() { if (isGoogleTaskChild) { context?.toast(R.string.subtasks_multilevel_google_task) } else { diff --git a/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt b/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt index a96c297fa..7d611f9b0 100644 --- a/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt +++ b/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt @@ -8,7 +8,6 @@ import android.widget.ImageView import android.widget.LinearLayout import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider -import butterknife.ButterKnife import org.tasks.R abstract class TaskEditControlFragment : Fragment() { @@ -19,13 +18,12 @@ abstract class TaskEditControlFragment : Fragment() { val view = inflater.inflate(R.layout.control_set_template, null) viewModel = ViewModelProvider(requireParentFragment()).get(TaskEditViewModel::class.java) val content = view.findViewById(R.id.content) - inflater.inflate(layout, content) + bind(content) val icon = view.findViewById(R.id.icon) icon.setImageResource(this.icon) if (isClickable) { content.setOnClickListener { onRowClick() } } - ButterKnife.bind(this, view) createView(savedInstanceState) @@ -38,7 +36,7 @@ abstract class TaskEditControlFragment : Fragment() { protected open val isClickable: Boolean get() = false - protected abstract val layout: Int protected abstract val icon: Int abstract fun controlId(): Int + protected abstract fun bind(parent: ViewGroup?): View } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/widget/ShortcutConfigActivity.kt b/app/src/main/java/org/tasks/widget/ShortcutConfigActivity.kt index ed3120ab5..9a87f5de0 100644 --- a/app/src/main/java/org/tasks/widget/ShortcutConfigActivity.kt +++ b/app/src/main/java/org/tasks/widget/ShortcutConfigActivity.kt @@ -8,16 +8,13 @@ import android.os.Parcelable import android.view.View import android.widget.TextView import androidx.appcompat.widget.Toolbar -import butterknife.BindView -import butterknife.ButterKnife -import butterknife.OnClick -import butterknife.OnFocusChange import com.google.android.material.textfield.TextInputEditText import com.todoroo.astrid.api.Filter import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.Strings.isNullOrEmpty import org.tasks.activities.FilterSelectionActivity +import org.tasks.databinding.ActivityWidgetShortcutLayoutBinding import org.tasks.dialogs.ColorPalettePicker import org.tasks.dialogs.ColorPalettePicker.Companion.newColorPalette import org.tasks.dialogs.ColorPickerAdapter.Palette @@ -32,29 +29,31 @@ import javax.inject.Inject class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPalettePicker.ColorPickedCallback { @Inject lateinit var defaultFilterProvider: DefaultFilterProvider - @BindView(R.id.toolbar) - lateinit var toolbar: Toolbar - - @BindView(R.id.shortcut_list) - lateinit var shortcutList: TextInputEditText - - @BindView(R.id.shortcut_name) - lateinit var shortcutName: TextInputEditText - - @BindView(R.id.color) - lateinit var colorIcon: TextView - - @BindView(R.id.clear) - lateinit var clear: View + private lateinit var toolbar: Toolbar + private lateinit var shortcutList: TextInputEditText + private lateinit var shortcutName: TextInputEditText + private lateinit var colorIcon: TextView + private lateinit var clear: View private var selectedFilter: Filter? = null private var selectedTheme = 0 public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + val binding = ActivityWidgetShortcutLayoutBinding.inflate(layoutInflater) + binding.let { + toolbar = it.toolbar.toolbar + shortcutList = it.body.shortcutList.apply { + setOnClickListener { showListPicker() } + setOnFocusChangeListener { _, hasFocus -> onListFocusChange(hasFocus) } + } + shortcutName = it.body.shortcutName + colorIcon = it.body.color.color + clear = it.body.color.clear.clear + it.body.color.colorRow.setOnClickListener { showThemePicker() } + } + setContentView(binding.root) - setContentView(R.layout.activity_widget_shortcut_layout) - ButterKnife.bind(this) toolbar.setTitle(R.string.FSA_label) toolbar.navigationIcon = getDrawable(R.drawable.ic_outline_save_24px) toolbar.setNavigationOnClickListener { save() } @@ -88,24 +87,21 @@ class ShortcutConfigActivity : ThemedInjectingAppCompatActivity(), ColorPaletteP outState.putInt(EXTRA_THEME, selectedTheme) } - @OnFocusChange(R.id.shortcut_list) - fun onListFocusChange(focused: Boolean) { + private fun onListFocusChange(focused: Boolean) { if (focused) { shortcutList.clearFocus() showListPicker() } } - @OnClick(R.id.shortcut_list) - fun showListPicker() { + private fun showListPicker() { val intent = Intent(this, FilterSelectionActivity::class.java) intent.putExtra(FilterSelectionActivity.EXTRA_FILTER, selectedFilter) intent.putExtra(FilterSelectionActivity.EXTRA_RETURN_FILTER, true) startActivityForResult(intent, REQUEST_FILTER) } - @OnClick(R.id.color_row) - fun showThemePicker() { + private fun showThemePicker() { newColorPalette(null, 0, Palette.LAUNCHERS) .show(supportFragmentManager, FRAG_TAG_COLOR_PICKER) } diff --git a/app/src/main/res/layout/activity_caldav_calendar_settings.xml b/app/src/main/res/layout/activity_caldav_calendar_settings.xml index 75a9ef809..3a2710905 100644 --- a/app/src/main/res/layout/activity_caldav_calendar_settings.xml +++ b/app/src/main/res/layout/activity_caldav_calendar_settings.xml @@ -11,7 +11,9 @@ - + - + - + diff --git a/app/src/main/res/layout/activity_widget_shortcut_layout.xml b/app/src/main/res/layout/activity_widget_shortcut_layout.xml index 37c071032..f34292b29 100644 --- a/app/src/main/res/layout/activity_widget_shortcut_layout.xml +++ b/app/src/main/res/layout/activity_widget_shortcut_layout.xml @@ -7,13 +7,17 @@ android:focusableInTouchMode="true" android:orientation="vertical"> - + - + diff --git a/app/src/main/res/layout/beast_mode_pref_activity.xml b/app/src/main/res/layout/beast_mode_pref_activity.xml index 1ef56a09a..9a55aaf6b 100644 --- a/app/src/main/res/layout/beast_mode_pref_activity.xml +++ b/app/src/main/res/layout/beast_mode_pref_activity.xml @@ -4,7 +4,9 @@ android:layout_height="match_parent" android:orientation="vertical"> - + - + diff --git a/app/src/main/res/layout/fragment_task_list.xml b/app/src/main/res/layout/fragment_task_list.xml index ef1532da8..a0271bf42 100644 --- a/app/src/main/res/layout/fragment_task_list.xml +++ b/app/src/main/res/layout/fragment_task_list.xml @@ -18,7 +18,9 @@ android:layout_height="match_parent" android:orientation="vertical"> - + - + - + diff --git a/app/src/main/res/layout/list_settings_color.xml b/app/src/main/res/layout/list_settings_color.xml index e4bc58072..3d7e171f3 100644 --- a/app/src/main/res/layout/list_settings_color.xml +++ b/app/src/main/res/layout/list_settings_color.xml @@ -5,7 +5,9 @@ style="@style/TagSettingsRow" android:background="?attr/selectableItemBackground"> - + 1.2.0 +| \--- com.atlassian.commonmark:commonmark:0.13.0 -++--- com.jakewharton:butterknife:10.2.3 -+| \--- com.jakewharton:butterknife-runtime:10.2.3 -+| +--- com.jakewharton:butterknife-annotations:10.2.3 -+| | \--- androidx.annotation:annotation:1.0.0 -> 1.2.0 -+| \--- androidx.core:core:1.0.0 -> 1.5.0-rc01 (*) ++--- org.jetbrains.kotlin:kotlin-stdlib:1.4.31 (*) ++--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.3 +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.0 -> 1.4.31 (*) diff --git a/deps_googleplay.txt b/deps_googleplay.txt index c44bdb6e2..f9315fd4c 100644 --- a/deps_googleplay.txt +++ b/deps_googleplay.txt @@ -406,11 +406,6 @@ ++--- io.noties.markwon:core:4.6.2 +| +--- androidx.annotation:annotation:1.1.0 -> 1.2.0 +| \--- com.atlassian.commonmark:commonmark:0.13.0 -++--- com.jakewharton:butterknife:10.2.3 -+| \--- com.jakewharton:butterknife-runtime:10.2.3 -+| +--- com.jakewharton:butterknife-annotations:10.2.3 -+| | \--- androidx.annotation:annotation:1.0.0 -> 1.2.0 -+| \--- androidx.core:core:1.0.0 -> 1.5.0-rc01 (*) ++--- org.jetbrains.kotlin:kotlin-stdlib:1.4.31 (*) ++--- org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.3 +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.0 -> 1.4.31 (*)