summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-09-01 07:13:47 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-09-01 07:13:47 -0300
commitda5205bb189c74d2d15200cba0164c9dba484812 (patch)
treead13764f6bb87ebd67c419207eea3174a85f6efb
parent8334f1ca8dcf1e5fb4e062fd45c0e96ad3759c70 (diff)
parent0686e984c70ae6a6d92f9dcbb90828197e74f4e7 (diff)
downloadmullvadvpn-da5205bb189c74d2d15200cba0164c9dba484812.tar.xz
mullvadvpn-da5205bb189c74d2d15200cba0164c9dba484812.zip
Merge branch 'change-account-input-border-rendering'
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt6
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInputContainer.kt99
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInputOutlineProvider.kt15
-rw-r--r--android/src/main/res/drawable/account_input_background.xml24
-rw-r--r--android/src/main/res/drawable/account_input_border.xml5
-rw-r--r--android/src/main/res/drawable/account_input_border_error.xml4
-rw-r--r--android/src/main/res/drawable/account_input_border_focused.xml4
-rw-r--r--android/src/main/res/drawable/account_input_corner.xml9
-rw-r--r--android/src/main/res/drawable/account_input_corner_error.xml11
-rw-r--r--android/src/main/res/drawable/account_input_corner_focused.xml11
-rw-r--r--android/src/main/res/drawable/login_button_background.xml24
-rw-r--r--android/src/main/res/layout/account_input_container.xml59
-rw-r--r--android/src/main/res/layout/login.xml52
-rw-r--r--android/src/main/res/values/dimensions.xml1
14 files changed, 215 insertions, 109 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt
index f1723b2d34..76ac2a86cf 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInput.kt
@@ -90,11 +90,7 @@ class AccountInput(val parentView: View, context: Context) {
)
}
- container.apply {
- clipToOutline = true
- outlineProvider = AccountInputOutlineProvider(context)
- setOnClickListener { shouldShowAccountHistory = true }
- }
+ container.setOnClickListener { shouldShowAccountHistory = true }
}
private fun initialState() {
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInputContainer.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInputContainer.kt
index 22aa7d3234..4ef365e876 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInputContainer.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInputContainer.kt
@@ -1,33 +1,91 @@
package net.mullvad.mullvadvpn.ui
import android.content.Context
+import android.graphics.drawable.Drawable
import android.util.AttributeSet
-import android.widget.LinearLayout
+import android.view.LayoutInflater
+import android.widget.ImageView
+import android.widget.RelativeLayout
import net.mullvad.mullvadvpn.R
-class AccountInputContainer : LinearLayout {
+class AccountInputContainer : RelativeLayout {
enum class BorderState {
UNFOCUSED,
FOCUSED,
ERROR
}
- private val errorBorder = resources.getDrawable(R.drawable.account_input_border_error, null)
- private val focusedBorder = resources.getDrawable(R.drawable.account_input_border_focused, null)
+ // The horizontal and vertical drawables are identical, but they must be separate objects
+ // because the view that uses them changes the bounds of the drawable. If they are shared
+ // between the horizontal and vertical views either the drawable becomes a vertical line or a
+ // horizontal line, and as a consequence either the horizontal or the vertical borders don't
+ // show correctly, respectively.
+ private class StateDrawables(
+ val corner: Drawable,
+ val horizontalBorder: Drawable,
+ val verticalBorder: Drawable
+ )
+
+ private val unfocusedDrawables = StateDrawables(
+ resources.getDrawable(R.drawable.account_input_corner, null),
+ resources.getDrawable(R.drawable.account_input_border, null),
+ resources.getDrawable(R.drawable.account_input_border, null)
+ )
+
+ private val focusedDrawables = StateDrawables(
+ resources.getDrawable(R.drawable.account_input_corner_focused, null),
+ resources.getDrawable(R.drawable.account_input_border_focused, null),
+ resources.getDrawable(R.drawable.account_input_border_focused, null)
+ )
+
+ private val errorDrawables = StateDrawables(
+ resources.getDrawable(R.drawable.account_input_corner_error, null),
+ resources.getDrawable(R.drawable.account_input_border_error, null),
+ resources.getDrawable(R.drawable.account_input_border_error, null)
+ )
+
+ private val container =
+ context.getSystemService(Context.LAYOUT_INFLATER_SERVICE).let { service ->
+ val inflater = service as LayoutInflater
+
+ inflater.inflate(R.layout.account_input_container, this)
+ }
+
+ private val topLeftCorner: ImageView = container.findViewById(R.id.top_left_corner)
+ private val topRightCorner: ImageView = container.findViewById(R.id.top_right_corner)
+ private val bottomLeftCorner: ImageView = container.findViewById(R.id.bottom_left_corner)
+ private val bottomRightCorner: ImageView = container.findViewById(R.id.bottom_right_corner)
+
+ private val topBorder: ImageView = container.findViewById(R.id.top_border)
+ private val leftBorder: ImageView = container.findViewById(R.id.left_border)
+ private val rightBorder: ImageView = container.findViewById(R.id.right_border)
+ private val bottomBorder: ImageView = container.findViewById(R.id.bottom_border)
var borderState = BorderState.UNFOCUSED
set(value) {
field = value
- overlay.clear()
-
when (value) {
- BorderState.UNFOCUSED -> {}
- BorderState.FOCUSED -> overlay.add(focusedBorder)
- BorderState.ERROR -> overlay.add(errorBorder)
+ BorderState.UNFOCUSED -> setBorder(unfocusedDrawables)
+ BorderState.FOCUSED -> setBorder(focusedDrawables)
+ BorderState.ERROR -> setBorder(errorDrawables)
}
}
+ init {
+ val borderElevation = elevation + 0.1f
+
+ topLeftCorner.elevation = borderElevation
+ topRightCorner.elevation = borderElevation
+ bottomLeftCorner.elevation = borderElevation
+ bottomRightCorner.elevation = borderElevation
+
+ topBorder.elevation = borderElevation
+ leftBorder.elevation = borderElevation
+ rightBorder.elevation = borderElevation
+ bottomBorder.elevation = borderElevation
+ }
+
constructor(context: Context) : super(context) {}
constructor(context: Context, attributes: AttributeSet) : super(context, attributes) {}
@@ -43,21 +101,16 @@ class AccountInputContainer : LinearLayout {
) : super(context, attributes, defaultStyleAttribute, defaultStyleResource) {
}
- protected override fun onLayout(
- changed: Boolean,
- left: Int,
- top: Int,
- right: Int,
- bottom: Int
- ) {
- super.onLayout(changed, left, top, right, bottom)
+ private fun setBorder(drawables: StateDrawables) {
+ topLeftCorner.setImageDrawable(drawables.corner)
+ topRightCorner.setImageDrawable(drawables.corner)
+ bottomLeftCorner.setImageDrawable(drawables.corner)
+ bottomRightCorner.setImageDrawable(drawables.corner)
- if (changed) {
- val width = right - left
- val height = bottom - top
+ leftBorder.setImageDrawable(drawables.verticalBorder)
+ rightBorder.setImageDrawable(drawables.verticalBorder)
- errorBorder.setBounds(0, 0, width, height)
- focusedBorder.setBounds(0, 0, width, height)
- }
+ topBorder.setImageDrawable(drawables.horizontalBorder)
+ bottomBorder.setImageDrawable(drawables.horizontalBorder)
}
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInputOutlineProvider.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInputOutlineProvider.kt
deleted file mode 100644
index df35f447fb..0000000000
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/AccountInputOutlineProvider.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package net.mullvad.mullvadvpn.ui
-
-import android.content.Context
-import android.graphics.Outline
-import android.view.View
-import android.view.ViewOutlineProvider
-import net.mullvad.mullvadvpn.R
-
-class AccountInputOutlineProvider(private val context: Context) : ViewOutlineProvider() {
- private val cornerRadius = context.resources.getDimension(R.dimen.account_input_corner_radius)
-
- override fun getOutline(view: View, outline: Outline) {
- outline.setRoundRect(0, 0, view.width, view.height, cornerRadius)
- }
-}
diff --git a/android/src/main/res/drawable/account_input_background.xml b/android/src/main/res/drawable/account_input_background.xml
index 63c5c6901f..d31775f404 100644
--- a/android/src/main/res/drawable/account_input_background.xml
+++ b/android/src/main/res/drawable/account_input_background.xml
@@ -2,25 +2,13 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<item android:state_enabled="false">
- <inset android:insetTop="1dp"
- android:insetBottom="1dp"
- android:insetLeft="1dp"
- android:insetRight="1dp">
- <shape android:shape="rectangle">
- <corners android:radius="@dimen/account_input_corner_radius" />
- <solid android:color="@color/white20" />
- </shape>
- </inset>
+ <shape android:shape="rectangle">
+ <solid android:color="@color/white20" />
+ </shape>
</item>
<item android:state_enabled="true">
- <inset android:insetTop="1dp"
- android:insetBottom="1dp"
- android:insetLeft="1dp">
- <shape android:shape="rectangle">
- <corners android:bottomLeftRadius="@dimen/account_input_corner_radius"
- android:topLeftRadius="@dimen/account_input_corner_radius" />
- <solid android:color="@color/white" />
- </shape>
- </inset>
+ <shape android:shape="rectangle">
+ <solid android:color="@color/white" />
+ </shape>
</item>
</selector>
diff --git a/android/src/main/res/drawable/account_input_border.xml b/android/src/main/res/drawable/account_input_border.xml
new file mode 100644
index 0000000000..7aa3362f35
--- /dev/null
+++ b/android/src/main/res/drawable/account_input_border.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@color/blue" />
+</shape>
diff --git a/android/src/main/res/drawable/account_input_border_error.xml b/android/src/main/res/drawable/account_input_border_error.xml
index d2112104ef..7b0b225c85 100644
--- a/android/src/main/res/drawable/account_input_border_error.xml
+++ b/android/src/main/res/drawable/account_input_border_error.xml
@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <corners android:radius="@dimen/account_input_corner_radius" />
- <stroke android:width="2dp"
- android:color="@color/red" />
+ <solid android:color="@color/red" />
</shape>
diff --git a/android/src/main/res/drawable/account_input_border_focused.xml b/android/src/main/res/drawable/account_input_border_focused.xml
index 551399bb0a..fa32039e1d 100644
--- a/android/src/main/res/drawable/account_input_border_focused.xml
+++ b/android/src/main/res/drawable/account_input_border_focused.xml
@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <corners android:radius="@dimen/account_input_corner_radius" />
- <stroke android:width="2dp"
- android:color="@color/darkBlue" />
+ <solid android:color="@color/darkBlue" />
</shape>
diff --git a/android/src/main/res/drawable/account_input_corner.xml b/android/src/main/res/drawable/account_input_corner.xml
new file mode 100644
index 0000000000..aed002b4ec
--- /dev/null
+++ b/android/src/main/res/drawable/account_input_corner.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="@dimen/account_input_corner_radius"
+ android:height="@dimen/account_input_corner_radius"
+ android:viewportWidth="4.0"
+ android:viewportHeight="4.0">
+ <path android:fillColor="@color/blue"
+ android:pathData="M 0 4 H 2 A 2 2 0 0 1 4 2 V 0 H 0 Z" />
+</vector>
diff --git a/android/src/main/res/drawable/account_input_corner_error.xml b/android/src/main/res/drawable/account_input_corner_error.xml
new file mode 100644
index 0000000000..c3acb16404
--- /dev/null
+++ b/android/src/main/res/drawable/account_input_corner_error.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="@dimen/account_input_corner_radius"
+ android:height="@dimen/account_input_corner_radius"
+ android:viewportWidth="4.0"
+ android:viewportHeight="4.0">
+ <path android:fillColor="@color/blue"
+ android:pathData="M 0 4 H 1 A 3 3 0 0 1 4 1 V 0 H 0 Z" />
+ <path android:fillColor="@color/red"
+ android:pathData="M 0 4 A 4 4 0 0 1 4 0 V 2 A 2 2 0 0 0 2 4 Z" />
+</vector>
diff --git a/android/src/main/res/drawable/account_input_corner_focused.xml b/android/src/main/res/drawable/account_input_corner_focused.xml
new file mode 100644
index 0000000000..1370463d49
--- /dev/null
+++ b/android/src/main/res/drawable/account_input_corner_focused.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="@dimen/account_input_corner_radius"
+ android:height="@dimen/account_input_corner_radius"
+ android:viewportWidth="4.0"
+ android:viewportHeight="4.0">
+ <path android:fillColor="@color/blue"
+ android:pathData="M 0 4 H 1 A 3 3 0 0 1 4 1 V 0 H 0 Z" />
+ <path android:fillColor="@color/darkBlue"
+ android:pathData="M 0 4 A 4 4 0 0 1 4 0 V 2 A 2 2 0 0 0 2 4 Z" />
+</vector>
diff --git a/android/src/main/res/drawable/login_button_background.xml b/android/src/main/res/drawable/login_button_background.xml
index d8243a7075..c1041ef523 100644
--- a/android/src/main/res/drawable/login_button_background.xml
+++ b/android/src/main/res/drawable/login_button_background.xml
@@ -2,25 +2,13 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<item android:state_enabled="false">
- <inset android:insetTop="1dp"
- android:insetBottom="1dp"
- android:insetRight="1dp">
- <shape android:shape="rectangle">
- <corners android:bottomRightRadius="@dimen/account_input_corner_radius"
- android:topRightRadius="@dimen/account_input_corner_radius" />
- <solid android:color="@color/white" />
- </shape>
- </inset>
+ <shape android:shape="rectangle">
+ <solid android:color="@color/white" />
+ </shape>
</item>
<item android:state_enabled="true">
- <inset android:insetTop="1dp"
- android:insetBottom="1dp"
- android:insetRight="1dp">
- <shape android:shape="rectangle">
- <corners android:bottomRightRadius="@dimen/account_input_corner_radius"
- android:topRightRadius="@dimen/account_input_corner_radius" />
- <solid android:color="@color/green" />
- </shape>
- </inset>
+ <shape android:shape="rectangle">
+ <solid android:color="@color/green" />
+ </shape>
</item>
</selector>
diff --git a/android/src/main/res/layout/account_input_container.xml b/android/src/main/res/layout/account_input_container.xml
new file mode 100644
index 0000000000..43e0fbea8b
--- /dev/null
+++ b/android/src/main/res/layout/account_input_container.xml
@@ -0,0 +1,59 @@
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- corners -->
+ <ImageView android:id="@+id/top_left_corner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true"
+ android:src="@drawable/account_input_corner" />
+ <ImageView android:id="@+id/top_right_corner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:rotation="90"
+ android:src="@drawable/account_input_corner" />
+ <ImageView android:id="@+id/bottom_right_corner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentRight="true"
+ android:rotation="180"
+ android:src="@drawable/account_input_corner" />
+ <ImageView android:id="@+id/bottom_left_corner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:rotation="270"
+ android:src="@drawable/account_input_corner" />
+ <!-- sides -->
+ <ImageView android:id="@+id/left_border"
+ android:layout_width="@dimen/account_input_border_width"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_below="@id/top_left_corner"
+ android:layout_above="@id/bottom_left_corner"
+ android:src="@drawable/account_input_border" />
+ <ImageView android:id="@+id/right_border"
+ android:layout_width="@dimen/account_input_border_width"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_below="@id/top_right_corner"
+ android:layout_above="@id/bottom_right_corner"
+ android:src="@drawable/account_input_border" />
+ <ImageView android:id="@+id/top_border"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/account_input_border_width"
+ android:layout_toLeftOf="@id/top_right_corner"
+ android:layout_toRightOf="@id/top_left_corner"
+ android:layout_alignParentTop="true"
+ android:src="@drawable/account_input_border" />
+ <ImageView android:id="@+id/bottom_border"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/account_input_border_width"
+ android:layout_toLeftOf="@id/bottom_right_corner"
+ android:layout_toRightOf="@id/bottom_left_corner"
+ android:layout_alignParentBottom="true"
+ android:src="@drawable/account_input_border" />
+</merge>
diff --git a/android/src/main/res/layout/login.xml b/android/src/main/res/layout/login.xml
index bfa0d88e23..87e240928c 100644
--- a/android/src/main/res/layout/login.xml
+++ b/android/src/main/res/layout/login.xml
@@ -66,30 +66,34 @@
android:text="@string/login_description" />
<net.mullvad.mullvadvpn.ui.AccountInputContainer android:id="@+id/account_input_container"
android:layout_width="match_parent"
- android:layout_height="48dp"
- android:orientation="horizontal">
- <EditText android:id="@+id/account_input"
- android:digits="0123456789"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingHorizontal="12dp"
- android:background="@drawable/account_input_background"
- android:inputType="number"
- android:singleLine="true"
- android:imeOptions="flagNoPersonalizedLearning"
- android:textCursorDrawable="@drawable/text_input_cursor"
- android:hint="@string/login_hint"
- android:textColorHint="@color/blue40"
- android:textColor="@color/blue"
- android:textSize="@dimen/text_medium_plus"
- android:textStyle="bold" />
- <ImageButton android:id="@+id/login_button"
- android:layout_width="48dp"
- android:layout_height="match_parent"
- android:layout_weight="0"
- android:background="@drawable/login_button_background"
- android:src="@drawable/login_button_arrow" />
+ android:layout_height="48dp">
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="48dp"
+ android:layout_alignParentTop="true"
+ android:orientation="horizontal">
+ <EditText android:id="@+id/account_input"
+ android:digits="0123456789"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:paddingHorizontal="12dp"
+ android:background="@drawable/account_input_background"
+ android:inputType="number"
+ android:singleLine="true"
+ android:imeOptions="flagNoPersonalizedLearning"
+ android:textCursorDrawable="@drawable/text_input_cursor"
+ android:hint="@string/login_hint"
+ android:textColorHint="@color/blue40"
+ android:textColor="@color/blue"
+ android:textSize="@dimen/text_medium_plus"
+ android:textStyle="bold" />
+ <ImageButton android:id="@+id/login_button"
+ android:layout_width="48dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:background="@drawable/login_button_background"
+ android:src="@drawable/login_button_arrow" />
+ </LinearLayout>
</net.mullvad.mullvadvpn.ui.AccountInputContainer>
<ListView android:id="@+id/account_history_list"
android:layout_width="fill_parent"
diff --git a/android/src/main/res/values/dimensions.xml b/android/src/main/res/values/dimensions.xml
index d06f80e517..1d87dc8350 100644
--- a/android/src/main/res/values/dimensions.xml
+++ b/android/src/main/res/values/dimensions.xml
@@ -5,6 +5,7 @@
<dimen name="list_item_divider">1dp</dimen>
<dimen name="dialog_margin">14dp</dimen>
<dimen name="account_input_corner_radius">4dp</dimen>
+ <dimen name="account_input_border_width">2dp</dimen>
<dimen name="edit_text_corner_radius">4dp</dimen>
<dimen name="normal_button_height">44dp</dimen>
<dimen name="tall_button_height">64dp</dimen>