diff --git a/androidshared/src/main/java/org/odk/collect/androidshared/ui/multiclicksafe/MultiClickSafeMaterialButton.kt b/androidshared/src/main/java/org/odk/collect/androidshared/ui/multiclicksafe/MultiClickSafeMaterialButton.kt
index e270628f7f4..9e67063e79d 100644
--- a/androidshared/src/main/java/org/odk/collect/androidshared/ui/multiclicksafe/MultiClickSafeMaterialButton.kt
+++ b/androidshared/src/main/java/org/odk/collect/androidshared/ui/multiclicksafe/MultiClickSafeMaterialButton.kt
@@ -2,24 +2,25 @@ package org.odk.collect.androidshared.ui.multiclicksafe
import android.content.Context
import android.util.AttributeSet
+import androidx.core.content.withStyledAttributes
import com.google.android.material.button.MaterialButton
+import org.odk.collect.androidshared.R
import org.odk.collect.androidshared.ui.multiclicksafe.MultiClickGuard.allowClick
-open class MultiClickSafeMaterialButton : MaterialButton {
- constructor(context: Context) : super(context)
+open class MultiClickSafeMaterialButton @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : MaterialButton(context, attrs, defStyleAttr) {
+ private lateinit var screenName: String
- constructor(context: Context, attrs: AttributeSet?) : super(
- context,
- attrs
- )
-
- constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
- context,
- attrs,
- defStyleAttr
- )
+ init {
+ context.withStyledAttributes(attrs, R.styleable.MultiClickSafeMaterialButton) {
+ screenName = getString(R.styleable.MultiClickSafeMaterialButton_screenName) ?: javaClass.name
+ }
+ }
override fun performClick(): Boolean {
- return allowClick() && super.performClick()
+ return allowClick(screenName) && super.performClick()
}
}
diff --git a/androidshared/src/main/res/values/attrs.xml b/androidshared/src/main/res/values/attrs.xml
new file mode 100644
index 00000000000..8345d36d90e
--- /dev/null
+++ b/androidshared/src/main/res/values/attrs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/collect_app/src/main/java/org/odk/collect/android/mainmenu/MainMenuButton.kt b/collect_app/src/main/java/org/odk/collect/android/mainmenu/MainMenuButton.kt
index 2914e14bc77..dc3acda24f9 100644
--- a/collect_app/src/main/java/org/odk/collect/android/mainmenu/MainMenuButton.kt
+++ b/collect_app/src/main/java/org/odk/collect/android/mainmenu/MainMenuButton.kt
@@ -5,12 +5,12 @@ import android.graphics.Typeface
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
+import androidx.core.content.withStyledAttributes
import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.badge.BadgeUtils
import com.google.android.material.badge.ExperimentalBadgeUtils
import org.odk.collect.android.R
import org.odk.collect.android.databinding.MainMenuButtonBinding
-import org.odk.collect.android.utilities.ApplicationConstants
import org.odk.collect.androidshared.system.ContextUtils.getThemeAttributeValue
import org.odk.collect.androidshared.ui.multiclicksafe.MultiClickGuard
@@ -20,25 +20,16 @@ class MainMenuButton(context: Context, attrs: AttributeSet?) : FrameLayout(conte
private val binding = MainMenuButtonBinding.inflate(LayoutInflater.from(context), this, true)
private val badge: BadgeDrawable
- private val highlightable: Boolean
+ private var highlightable: Boolean = false
init {
- context.theme.obtainStyledAttributes(
- attrs,
- R.styleable.MainMenuButton,
- 0,
- 0
- ).apply {
- try {
- val buttonIcon = this.getResourceId(R.styleable.MainMenuButton_icon, 0)
- val buttonName = this.getString(R.styleable.MainMenuButton_name)
- highlightable = this.getBoolean(R.styleable.MainMenuButton_highlightable, false)
+ context.withStyledAttributes(attrs, R.styleable.MainMenuButton) {
+ val buttonIcon = this.getResourceId(R.styleable.MainMenuButton_icon, 0)
+ val buttonName = this.getString(R.styleable.MainMenuButton_name)
+ highlightable = this.getBoolean(R.styleable.MainMenuButton_highlightable, false)
- binding.icon.setImageResource(buttonIcon)
- binding.name.text = buttonName
- } finally {
- recycle()
- }
+ binding.icon.setImageResource(buttonIcon)
+ binding.name.text = buttonName
}
badge = BadgeDrawable.create(context).apply {
@@ -51,7 +42,7 @@ class MainMenuButton(context: Context, attrs: AttributeSet?) : FrameLayout(conte
get() = binding.name.text.toString()
override fun performClick(): Boolean {
- return MultiClickGuard.allowClick(ApplicationConstants.ScreenName.MAIN_MENU.name) && super.performClick()
+ return MultiClickGuard.allowClick(context.getString(R.string.main_menu_screen)) && super.performClick()
}
fun setNumberOfForms(number: Int) {
diff --git a/collect_app/src/main/java/org/odk/collect/android/mainmenu/StartNewFormButton.kt b/collect_app/src/main/java/org/odk/collect/android/mainmenu/StartNewFormButton.kt
index ee4c5cf31a7..1fc3abb04be 100644
--- a/collect_app/src/main/java/org/odk/collect/android/mainmenu/StartNewFormButton.kt
+++ b/collect_app/src/main/java/org/odk/collect/android/mainmenu/StartNewFormButton.kt
@@ -5,7 +5,6 @@ import android.util.AttributeSet
import android.widget.FrameLayout
import android.widget.TextView
import org.odk.collect.android.R
-import org.odk.collect.android.utilities.ApplicationConstants
import org.odk.collect.androidshared.ui.multiclicksafe.MultiClickGuard
class StartNewFormButton(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
@@ -20,6 +19,6 @@ class StartNewFormButton(context: Context, attrs: AttributeSet?) : FrameLayout(c
get() = findViewById(R.id.name).text.toString()
override fun performClick(): Boolean {
- return MultiClickGuard.allowClick(ApplicationConstants.ScreenName.MAIN_MENU.name) && super.performClick()
+ return MultiClickGuard.allowClick(context.getString(R.string.main_menu_screen)) && super.performClick()
}
}
diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/ApplicationConstants.java b/collect_app/src/main/java/org/odk/collect/android/utilities/ApplicationConstants.java
index 5aa30edf7c0..9ea64e46145 100644
--- a/collect_app/src/main/java/org/odk/collect/android/utilities/ApplicationConstants.java
+++ b/collect_app/src/main/java/org/odk/collect/android/utilities/ApplicationConstants.java
@@ -84,8 +84,4 @@ public abstract static class Namespaces {
public static final String XML_OPENROSA_NAMESPACE = "http://openrosa.org/xforms";
public static final String XML_OPENDATAKIT_NAMESPACE = "http://www.opendatakit.org/xforms";
}
-
- public enum ScreenName {
- MAIN_MENU
- }
}
diff --git a/collect_app/src/main/res/layout/form_download_list.xml b/collect_app/src/main/res/layout/form_download_list.xml
index 57bc6849ecc..71c14f50b39 100644
--- a/collect_app/src/main/res/layout/form_download_list.xml
+++ b/collect_app/src/main/res/layout/form_download_list.xml
@@ -63,7 +63,7 @@ the License.
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
-
-
-
-
-
+ app:iconGravity="textStart"
+ app:screenName="@string/form_end_screen" />
+ app:iconGravity="textStart"
+ app:screenName="@string/form_end_screen" />
diff --git a/collect_app/src/main/res/layout/instance_uploader_list.xml b/collect_app/src/main/res/layout/instance_uploader_list.xml
index 01156949beb..c68d84782e9 100644
--- a/collect_app/src/main/res/layout/instance_uploader_list.xml
+++ b/collect_app/src/main/res/layout/instance_uploader_list.xml
@@ -60,7 +60,7 @@ the License.
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
-
-
+
+ mainMenuScreen
+ formEndScreen
+
diff --git a/lists/src/main/java/org/odk/collect/lists/EmptyListView.kt b/lists/src/main/java/org/odk/collect/lists/EmptyListView.kt
index f3458013e89..cc5af9d3108 100644
--- a/lists/src/main/java/org/odk/collect/lists/EmptyListView.kt
+++ b/lists/src/main/java/org/odk/collect/lists/EmptyListView.kt
@@ -5,6 +5,7 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import androidx.annotation.DrawableRes
+import androidx.core.content.withStyledAttributes
import org.odk.collect.lists.databinding.EmptyListViewBinding
class EmptyListView(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
@@ -13,23 +14,14 @@ class EmptyListView(context: Context, attrs: AttributeSet?) : FrameLayout(contex
private val binding = EmptyListViewBinding.inflate(LayoutInflater.from(context), this, true)
init {
- context.theme.obtainStyledAttributes(
- attrs,
- R.styleable.EmptyListView,
- 0,
- 0
- ).apply {
- try {
- val icon = this.getResourceId(R.styleable.EmptyListView_icon, 0)
- val title = this.getString(R.styleable.EmptyListView_title)
- val subtitle = this.getString(R.styleable.EmptyListView_subtitle)
-
- binding.icon.setImageResource(icon)
- binding.title.text = title
- binding.subtitle.text = subtitle
- } finally {
- recycle()
- }
+ context.withStyledAttributes(attrs, R.styleable.EmptyListView) {
+ val icon = this.getResourceId(R.styleable.EmptyListView_icon, 0)
+ val title = this.getString(R.styleable.EmptyListView_title)
+ val subtitle = this.getString(R.styleable.EmptyListView_subtitle)
+
+ binding.icon.setImageResource(icon)
+ binding.title.text = title
+ binding.subtitle.text = subtitle
}
}
diff --git a/lists/src/main/res/layout/multi_select_controls_layout.xml b/lists/src/main/res/layout/multi_select_controls_layout.xml
index 19a1eb37657..db1cb3bc672 100644
--- a/lists/src/main/res/layout/multi_select_controls_layout.xml
+++ b/lists/src/main/res/layout/multi_select_controls_layout.xml
@@ -9,7 +9,7 @@
android:layout_height="wrap_content"
style="@style/Widget.AndroidShared.ButtonBar">
-
-