diff options
| author | Aleksandr Granin <aleksandr@mullvad.net> | 2021-03-12 14:58:28 +0100 |
|---|---|---|
| committer | Aleksandr Granin <aleksandr@mullvad.net> | 2021-03-12 14:58:28 +0100 |
| commit | 5cf2e320362a65ac8790f578bd1765c6e47d4eb7 (patch) | |
| tree | 8e5a7ce6ddfd37ab5ccddaeeaffd8e5e0de647ae /android/src | |
| parent | 1db49ed3e79d82697f7e3490249ef2cce463c2be (diff) | |
| parent | 6a247fe70f7c8b5db2a95c674ca8ce3a21edc84a (diff) | |
| download | mullvadvpn-5cf2e320362a65ac8790f578bd1765c6e47d4eb7.tar.xz mullvadvpn-5cf2e320362a65ac8790f578bd1765c6e47d4eb7.zip | |
Merge branch 'core-listitem-views'
Diffstat (limited to 'android/src')
22 files changed, 575 insertions, 1 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemListener.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemListener.kt new file mode 100644 index 0000000000..72cc32196c --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ListItemListener.kt @@ -0,0 +1,7 @@ +package net.mullvad.mullvadvpn.ui + +import net.mullvad.mullvadvpn.model.ListItemData + +interface ListItemListener { + fun onItemAction(item: ListItemData) +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ActionListItemView.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ActionListItemView.kt new file mode 100644 index 0000000000..69581c245f --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ActionListItemView.kt @@ -0,0 +1,119 @@ +package net.mullvad.mullvadvpn.ui.listitemview + +import android.content.Context +import android.content.res.Resources +import android.util.AttributeSet +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.core.view.isVisible +import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.model.WidgetState + +open class ActionListItemView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = R.attr.actionListItemViewStyle, + defStyleRes: Int = 0 +) : ListItemView(context, attrs, defStyleAttr, defStyleRes) { + + protected var widgetController: WidgetViewController<*>? = null + protected val itemText: TextView = findViewById(R.id.itemText) + protected val itemIcon: ImageView = findViewById(R.id.itemIcon) + protected val widgetContainer: ViewGroup = findViewById(R.id.widgetContainer) + + protected val clickListener = OnClickListener { + itemData.action?.let { _ -> + listItemListener?.onItemAction(itemData) + } + } + + override val layoutRes: Int + get() = R.layout.list_item_action + + override val heightRes: Int + get() = R.dimen.cell_height + + override fun onUpdate() { + updateImage() + updateText() + updateWidget() + updateAction() + } + + protected open fun updateImage() { + try { + itemData.iconRes?.let { + itemIcon.isVisible = true + itemIcon.setImageResource(it) + return + } + } catch (ignore: Resources.NotFoundException) { + itemIcon.isVisible = true + itemIcon.setImageResource(R.drawable.ic_icons_missing) + return + } + + itemIcon.isVisible = false + itemIcon.setImageDrawable(null) + } + + protected open fun updateText() { + itemData.textRes?.let { + itemText.setText(it) + return + } + itemData.text?.let { + itemText.setText(it) + return + } + itemText.text = "" + } + + protected open fun updateAction() { + if (itemData.action == null) { + setOnClickListener(null) + isClickable = false + isFocusable = false + } else { + setOnClickListener(clickListener) + isClickable = true + isFocusable = true + } + } + + protected open fun updateWidget() { + itemData.widget.let { state -> + when (state) { + is WidgetState.ImageState -> { + if (widgetController !is WidgetViewController.StandardController) { + widgetContainer.removeAllViews() + widgetContainer.isVisible = true + widgetController = WidgetViewController.StandardController(widgetContainer) + } + (widgetController as WidgetViewController.StandardController).updateState(state) + } + is WidgetState.SwitchState -> { + if (widgetController !is WidgetViewController.SwitchController) { + widgetContainer.removeAllViews() + widgetContainer.isVisible = true + widgetController = WidgetViewController.SwitchController(widgetContainer) + } + (widgetController as WidgetViewController.SwitchController).updateState(state) + } + null -> { + if (widgetController != null) { + widgetController = null + widgetContainer.removeAllViews() + widgetContainer.isVisible = false + } + } + } + } + } + + override fun onAttachedToWindow() { + super.onAttachedToWindow() + widgetContainer.requestLayout() + } +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/DividerGroupListItemView.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/DividerGroupListItemView.kt new file mode 100644 index 0000000000..61bb5bf400 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/DividerGroupListItemView.kt @@ -0,0 +1,15 @@ +package net.mullvad.mullvadvpn.ui.listitemview + +import android.content.Context +import androidx.appcompat.view.ContextThemeWrapper +import net.mullvad.mullvadvpn.R + +class DividerGroupListItemView(context: Context) : + ListItemView(ContextThemeWrapper(context, R.style.ListItem_DividerGroup)) { + + override val layoutRes: Int + get() = R.layout.list_item_group_divider + + override val heightRes: Int + get() = R.dimen.vertical_space +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ListItemView.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ListItemView.kt new file mode 100644 index 0000000000..d1149d1afd --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ListItemView.kt @@ -0,0 +1,41 @@ +package net.mullvad.mullvadvpn.ui.listitemview + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import androidx.annotation.DimenRes +import androidx.annotation.LayoutRes +import androidx.constraintlayout.widget.ConstraintLayout +import net.mullvad.mullvadvpn.model.ListItemData +import net.mullvad.mullvadvpn.ui.ListItemListener + +abstract class ListItemView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, + defStyleRes: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) { + @get:LayoutRes + protected abstract val layoutRes: Int + @get:DimenRes + protected abstract val heightRes: Int? + protected lateinit var itemData: ListItemData + var listItemListener: ListItemListener? = null + + init { + val view = LayoutInflater.from(context).inflate(layoutRes, this, true) + val height = if (heightRes != null) { + resources.getDimensionPixelSize(heightRes!!) + } else { + LayoutParams.WRAP_CONTENT + } + view.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, height) + } + + fun update(data: ListItemData) { + itemData = data + onUpdate() + } + + protected open fun onUpdate() {} +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/PlainListItemView.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/PlainListItemView.kt new file mode 100644 index 0000000000..f472c444df --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/PlainListItemView.kt @@ -0,0 +1,30 @@ +package net.mullvad.mullvadvpn.ui.listitemview + +import android.content.Context +import android.widget.TextView +import androidx.appcompat.view.ContextThemeWrapper +import net.mullvad.mullvadvpn.R + +class PlainListItemView(context: Context) : + ListItemView(ContextThemeWrapper(context, R.style.ListItem_PlainText)) { + override val layoutRes: Int + get() = R.layout.list_item_plain_text + override val heightRes: Int? = null + private val plainText: TextView = findViewById(R.id.plain_text) + + override fun onUpdate() { + updateText() + } + + private fun updateText() { + itemData.textRes?.let { + plainText.setText(it) + return + } + itemData.text?.let { + plainText.text = it + return + } + plainText.text = "" + } +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ProgressListItemView.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ProgressListItemView.kt new file mode 100644 index 0000000000..724caf0c61 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/ProgressListItemView.kt @@ -0,0 +1,15 @@ +package net.mullvad.mullvadvpn.ui.listitemview + +import android.content.Context +import androidx.appcompat.view.ContextThemeWrapper +import net.mullvad.mullvadvpn.R + +class ProgressListItemView(context: Context) : + ListItemView(ContextThemeWrapper(context, R.style.ListItem_DividerGroup)) { + + override val layoutRes: Int + get() = R.layout.list_item_progress + + override val heightRes: Int + get() = R.dimen.progress_size +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/TwoActionListItemView.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/TwoActionListItemView.kt new file mode 100644 index 0000000000..8f349c0548 --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/TwoActionListItemView.kt @@ -0,0 +1,33 @@ +package net.mullvad.mullvadvpn.ui.listitemview + +import android.content.Context +import android.view.ViewGroup +import androidx.appcompat.view.ContextThemeWrapper +import net.mullvad.mullvadvpn.R + +class TwoActionListItemView(context: Context) : + ActionListItemView(ContextThemeWrapper(context, R.style.ListItem_Action_Double)) { + override val layoutRes: Int + get() = R.layout.list_item_two_action + private val container: ViewGroup = findViewById(R.id.container_without_widget) + + init { + isClickable = false + isFocusable = false + } + + override fun updateAction() { + if (itemData.action == null) { + container.setOnClickListener(null) + container.isClickable = false + container.isFocusable = false + } else { + container.setOnClickListener(clickListener) + container.isClickable = true + container.isFocusable = true + } + widgetContainer.setOnClickListener(clickListener) + widgetContainer.isClickable = true + widgetContainer.isFocusable = true + } +} diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/WidgetViewController.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/WidgetViewController.kt new file mode 100644 index 0000000000..f1ec04bd1d --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/listitemview/WidgetViewController.kt @@ -0,0 +1,39 @@ +package net.mullvad.mullvadvpn.ui.listitemview + +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.ImageView +import androidx.annotation.LayoutRes +import androidx.appcompat.widget.SwitchCompat +import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.model.WidgetState + +sealed class WidgetViewController<T : WidgetState>(val parent: ViewGroup) { + @get:LayoutRes + protected abstract val layoutRes: Int + + init { + LayoutInflater.from(parent.context).inflate(layoutRes, parent) + } + + abstract fun updateState(state: T) + + class StandardController(parent: ViewGroup) : + WidgetViewController<WidgetState.ImageState>(parent) { + override val layoutRes: Int + get() = R.layout.list_item_widget_image + private val imageView: ImageView = parent.findViewById(R.id.widgetImage) + override fun updateState(state: WidgetState.ImageState) = + imageView.setImageResource(state.imageRes) + } + + class SwitchController(parent: ViewGroup) : + WidgetViewController<WidgetState.SwitchState>(parent) { + override val layoutRes: Int + get() = R.layout.list_item_widget_switch + private val switch: SwitchCompat = parent.findViewById(R.id.widgetSwitch) + override fun updateState(state: WidgetState.SwitchState) { + switch.isChecked = state.isChecked + } + } +} diff --git a/android/src/main/res/drawable/ic_icons_missing.xml b/android/src/main/res/drawable/ic_icons_missing.xml new file mode 100644 index 0000000000..726a5c7f74 --- /dev/null +++ b/android/src/main/res/drawable/ic_icons_missing.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:fillColor="#D8D8D8" + android:fillType="nonZero" + android:pathData="M16.327,10.25l1.422,-2.519c0.124,-0.246 0.031,-0.547 -0.2,-0.673 -0.225,-0.12 -0.503,-0.048 -0.642,0.174l-1.453,2.567c-2.21,-0.959 -4.698,-0.959 -6.908,0L7.093,7.232c-0.147,-0.23 -0.448,-0.301 -0.672,-0.159 -0.216,0.143 -0.286,0.428 -0.17,0.658l1.422,2.52C5.277,11.652 3.716,14.18 3.5,17h17c-0.216,-2.82 -1.777,-5.347 -4.173,-6.75zM8.137,14.821c-0.534,0 -0.967,-0.443 -0.967,-0.99 0,-0.547 0.433,-0.99 0.966,-0.99 0.534,0 0.966,0.443 0.966,0.99 0,0.547 -0.432,0.99 -0.966,0.99zM15.864,14.821c-0.534,0 -0.966,-0.443 -0.966,-0.99 0,-0.547 0.432,-0.99 0.966,-0.99 0.533,0 0.966,0.443 0.966,0.99 0,0.547 -0.433,0.99 -0.966,0.99zM12,24C5.373,24 0,18.627 0,12S5.373,0 12,0s12,5.373 12,12 -5.373,12 -12,12z" /> +</vector> diff --git a/android/src/main/res/layout/list_item_action.xml b/android/src/main/res/layout/list_item_action.xml new file mode 100644 index 0000000000..9b9fc806f0 --- /dev/null +++ b/android/src/main/res/layout/list_item_action.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + style="@style/ListItem.Action" + tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> + <include layout="@layout/list_item_base" /> + <FrameLayout android:id="@+id/widgetContainer" + android:layout_width="wrap_content" + android:layout_height="0dp" + android:paddingStart="@dimen/widget_padding" + android:paddingEnd="@dimen/widget_padding" + android:visibility="invisible" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/itemText" + app:layout_constraintTop_toTopOf="parent" /> + <androidx.constraintlayout.widget.Guideline android:id="@+id/endGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_end="@dimen/cell_right_padding" /> + <androidx.constraintlayout.widget.Barrier android:id="@+id/widgetBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierDirection="start" + app:constraint_referenced_ids="widgetContainer,endGuideline" /> +</merge> diff --git a/android/src/main/res/layout/list_item_base.xml b/android/src/main/res/layout/list_item_base.xml new file mode 100644 index 0000000000..0c22feef21 --- /dev/null +++ b/android/src/main/res/layout/list_item_base.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="@dimen/cell_height" + tools:background="@color/green" + tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> + <androidx.appcompat.widget.AppCompatImageView android:id="@+id/itemIcon" + android:layout_width="@dimen/icon_size" + android:layout_height="@dimen/icon_size" + android:layout_marginEnd="@dimen/cell_inner_spacing" + android:background="@null" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/itemText" + app:layout_constraintStart_toStartOf="@id/startGuideline" + app:layout_constraintTop_toTopOf="parent" + tools:visibility="gone" + tools:src="@drawable/launch_logo" /> + <androidx.appcompat.widget.AppCompatTextView android:id="@+id/itemText" + android:layout_width="0dp" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:textAppearance="@style/TextAppearance.Mullvad.Title1" + android:textStyle="bold" + android:background="@null" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/widgetBarrier" + app:layout_constraintStart_toEndOf="@id/itemIcon" + app:layout_constraintTop_toTopOf="parent" + tools:background="@color/white20" + tools:text="WireGuard MTU" /> + <androidx.constraintlayout.widget.Guideline android:id="@+id/startGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_begin="@dimen/screen_vertical_margin" /> + <androidx.constraintlayout.widget.Barrier android:id="@+id/widgetBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:tag="base" + app:barrierDirection="start" + app:constraint_referenced_ids="parent" /> +</merge> diff --git a/android/src/main/res/layout/list_item_group_divider.xml b/android/src/main/res/layout/list_item_group_divider.xml new file mode 100644 index 0000000000..9546d55c98 --- /dev/null +++ b/android/src/main/res/layout/list_item_group_divider.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="@dimen/vertical_space" + tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout" /> diff --git a/android/src/main/res/layout/list_item_plain_text.xml b/android/src/main/res/layout/list_item_plain_text.xml new file mode 100644 index 0000000000..f17bc6ed5e --- /dev/null +++ b/android/src/main/res/layout/list_item_plain_text.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> + <androidx.appcompat.widget.AppCompatTextView android:id="@+id/plain_text" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:paddingTop="0dp" + android:paddingBottom="0dp" + android:textAppearance="@style/TextAppearance.Mullvad.Small" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="@id/endGuideline" + app:layout_constraintStart_toStartOf="@id/startGuideline" + app:layout_constraintTop_toTopOf="parent" + tools:text="Choose the apps you want to exclude from the VPN tunnel." /> + <androidx.constraintlayout.widget.Guideline android:id="@+id/startGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_begin="@dimen/screen_vertical_margin" /> + <androidx.constraintlayout.widget.Guideline android:id="@+id/endGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_end="@dimen/screen_vertical_margin" /> +</merge> diff --git a/android/src/main/res/layout/list_item_progress.xml b/android/src/main/res/layout/list_item_progress.xml new file mode 100644 index 0000000000..221947ea85 --- /dev/null +++ b/android/src/main/res/layout/list_item_progress.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> + <ProgressBar android:id="@+id/loading_spinner" + android:layout_width="@dimen/progress_size" + android:layout_height="@dimen/progress_size" + android:indeterminate="true" + android:indeterminateDrawable="@drawable/icon_spinner" + android:indeterminateDuration="600" + android:indeterminateOnly="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> +</merge> diff --git a/android/src/main/res/layout/list_item_two_action.xml b/android/src/main/res/layout/list_item_two_action.xml new file mode 100644 index 0000000000..81e6a5c652 --- /dev/null +++ b/android/src/main/res/layout/list_item_two_action.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="@dimen/cell_height" + tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"> + <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/container_without_widget" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="?android:attr/selectableItemBackground" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/widgetBarrier" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + <include layout="@layout/list_item_base" /> + </androidx.constraintlayout.widget.ConstraintLayout> + <FrameLayout android:id="@+id/widgetContainer" + android:layout_width="wrap_content" + android:layout_height="0dp" + android:background="?android:attr/selectableItemBackground" + android:paddingStart="@dimen/widget_padding" + android:paddingEnd="@dimen/widget_padding" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + android:visibility="visible" + app:layout_constraintStart_toEndOf="@id/container_without_widget" + app:layout_constraintTop_toTopOf="parent" /> + <androidx.constraintlayout.widget.Guideline android:id="@+id/endGuideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_end="@dimen/cell_right_padding" /> + <androidx.constraintlayout.widget.Barrier android:id="@+id/widgetBarrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierDirection="start" + app:constraint_referenced_ids="widgetContainer,endGuideline" /> +</merge> diff --git a/android/src/main/res/layout/list_item_widget_edit_text.xml b/android/src/main/res/layout/list_item_widget_edit_text.xml new file mode 100644 index 0000000000..13b24c9d80 --- /dev/null +++ b/android/src/main/res/layout/list_item_widget_edit_text.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.appcompat.widget.AppCompatEditText xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:background="@drawable/cell_input_background" + android:digits="0123456789" + android:gravity="center" + android:hint="@string/hint_default" + android:imeOptions="flagNoPersonalizedLearning" + android:inputType="number" + android:maxWidth="130dp" + android:maxLength="4" + android:minWidth="@dimen/cell_input_width" + android:paddingHorizontal="8dp" + android:paddingVertical="4dp" + android:singleLine="true" + android:textColor="@color/white" + android:textColorHint="@color/white80" + android:textCursorDrawable="@drawable/cell_input_cursor" + android:textSize="@dimen/text_medium_plus" /> diff --git a/android/src/main/res/layout/list_item_widget_image.xml b/android/src/main/res/layout/list_item_widget_image.xml new file mode 100644 index 0000000000..95034e46e3 --- /dev/null +++ b/android/src/main/res/layout/list_item_widget_image.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.appcompat.widget.AppCompatImageView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/widgetImage" + android:layout_width="@dimen/icon_size" + android:layout_height="@dimen/icon_size" + android:layout_gravity="center" + android:tint="@color/white40" + android:tintMode="multiply" + tools:src="@drawable/icon_extlink" /> diff --git a/android/src/main/res/layout/list_item_widget_switch.xml b/android/src/main/res/layout/list_item_widget_switch.xml new file mode 100644 index 0000000000..9c4e342660 --- /dev/null +++ b/android/src/main/res/layout/list_item_widget_switch.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.appcompat.widget.SwitchCompat xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/widgetSwitch" + style="@style/AppTheme.Switch" + android:layout_gravity="center" + android:clickable="false" + android:focusable="false" + android:background="@null" + android:focusableInTouchMode="false" + tools:checked="false" /> diff --git a/android/src/main/res/values/attrs.xml b/android/src/main/res/values/attrs.xml index 21db41e41c..8eefb1c173 100644 --- a/android/src/main/res/values/attrs.xml +++ b/android/src/main/res/values/attrs.xml @@ -55,4 +55,8 @@ <attr name="withToken" format="boolean" /> </declare-styleable> + <attr name="actionListItemViewStyle" + type="reference" /> + <attr name="applicationListItemViewStyle" + type="reference" /> </resources> diff --git a/android/src/main/res/values/dimensions.xml b/android/src/main/res/values/dimensions.xml index 0f0bd9ad43..3d42e74afd 100644 --- a/android/src/main/res/values/dimensions.xml +++ b/android/src/main/res/values/dimensions.xml @@ -42,6 +42,9 @@ <dimen name="button_separation">18dp</dimen> <dimen name="screen_vertical_margin">22dp</dimen> <dimen name="app_list_item_icon_size">35dp</dimen> + <dimen name="progress_size">60dp</dimen> + <dimen name="icon_size">24dp</dimen> + <dimen name="widget_padding">16dp</dimen> <!-- Switch Dimens--> <dimen name="switch_width">46dp</dimen> <dimen name="switch_height">30dp</dimen> diff --git a/android/src/main/res/values/integers.xml b/android/src/main/res/values/integers.xml index 1ae43d4d23..3089382d18 100644 --- a/android/src/main/res/values/integers.xml +++ b/android/src/main/res/values/integers.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <integer name="transition_animation_duration">450</integer> + <integer name="transition_animation_duration">@android:integer/config_mediumAnimTime</integer> </resources> diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml index d85ee24363..2a2734505a 100644 --- a/android/src/main/res/values/styles.xml +++ b/android/src/main/res/values/styles.xml @@ -6,6 +6,8 @@ <item name="android:statusBarColor">@color/blue</item> <item name="android:windowBackground">@color/blue</item> <item name="switchStyle">@style/AppTheme.Switch</item> + <item name="actionListItemViewStyle">@style/ListItem.Action</item> + <item name="applicationListItemViewStyle">@style/ListItem.Action.Application</item> </style> <style name="InputText" parent="Widget.AppCompat.EditText"> @@ -56,6 +58,57 @@ parent="SettingsHeader"> <item name="android:textSize">@dimen/text_medium</item> </style> + <style name="TextAppearance.Mullvad" + parent="TextAppearance.AppCompat" /> + <style name="TextAppearance.Mullvad.Title1"> + <item name="android:textColor">@color/white</item> + <item name="android:textSize">@dimen/text_medium_plus</item> + </style> + <style name="TextAppearance.Mullvad.Title2"> + <item name="android:textColor">@color/white</item> + <item name="android:textSize">@dimen/text_medium</item> + </style> + <style name="TextAppearance.Mullvad.Small"> + <item name="android:textColor">@color/white60</item> + <item name="android:textSize">@dimen/text_small</item> + </style> + <style name="ListItem"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + </style> + <style name="ListItem.DividerGroup"> + <item name="android:layout_height">@dimen/vertical_space</item> + </style> + <style name="ListItem.PlainText"> + <item name="android:focusable">false</item> + <item name="android:clickable">false</item> + <item name="android:paddingTop">5dp</item> + </style> + <style name="ListItem.Action"> + <item name="android:height">@dimen/cell_height</item> + <item name="android:layout_height">@dimen/cell_height</item> + <item name="android:background">@drawable/cell_button_background</item> + <item name="android:clickable">true</item> + <item name="android:focusable">true</item> + </style> + <style name="ListItem.Action.Application"> + <item name="android:background">@drawable/app_list_item_background</item> + </style> + <style name="ListItem.Action.Double"> + <item name="android:clickable">false</item> + <item name="android:focusable">false</item> + </style> + <style name="TextAppearance.Mullvad.CollapsingToolbar"> + <item name="android:textColor">@color/white</item> + </style> + <style name="TextAppearance.Mullvad.CollapsingToolbar.Expanded"> + <item name="android:textSize">30sp</item> + <item name="android:textStyle">bold</item> + </style> + <style name="TextAppearance.Mullvad.CollapsingToolbar.Collapsed"> + <item name="android:textSize">20sp</item> + <item name="android:textStyle">bold</item> + </style> <!-- Switch Style --> <style name="AppTheme.Switch"> <item name="android:layout_width">@dimen/switch_width</item> |
