Merge pull request #562 from android-password-store/msf/ui-rework
Redesign some UI elements
This commit is contained in:
commit
fc2a11699a
8 changed files with 157 additions and 131 deletions
|
@ -10,11 +10,10 @@ import android.view.ViewGroup
|
||||||
import androidx.appcompat.widget.AppCompatImageView
|
import androidx.appcompat.widget.AppCompatImageView
|
||||||
import androidx.appcompat.widget.AppCompatTextView
|
import androidx.appcompat.widget.AppCompatTextView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
||||||
import com.zeapo.pwdstore.R
|
import com.zeapo.pwdstore.R
|
||||||
import com.zeapo.pwdstore.utils.PasswordItem
|
import com.zeapo.pwdstore.utils.PasswordItem
|
||||||
import com.zeapo.pwdstore.widget.MultiselectableLinearLayout
|
import com.zeapo.pwdstore.widget.MultiselectableConstraintLayout
|
||||||
|
import java.io.File
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.TreeSet
|
import java.util.TreeSet
|
||||||
|
|
||||||
|
@ -81,12 +80,20 @@ abstract class EntryRecyclerAdapter internal constructor(val values: ArrayList<P
|
||||||
holder.name.text = pass.toString()
|
holder.name.text = pass.toString()
|
||||||
if (pass.type == PasswordItem.TYPE_CATEGORY) {
|
if (pass.type == PasswordItem.TYPE_CATEGORY) {
|
||||||
holder.type.visibility = View.GONE
|
holder.type.visibility = View.GONE
|
||||||
holder.typeImage.setImageResource(R.drawable.ic_folder_tinted_24dp)
|
holder.typeImage.setImageResource(R.drawable.ic_multiple_files_tinted_24dp)
|
||||||
|
holder.folderIndicator.visibility = View.VISIBLE
|
||||||
|
val childCount = (pass.file.list { current, name -> File(current, name).isFile } ?: emptyArray<File>()).size
|
||||||
|
if (childCount > 0) {
|
||||||
|
holder.childCount.visibility = View.VISIBLE
|
||||||
|
holder.childCount.text = "$childCount"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
holder.typeImage.setImageResource(R.drawable.ic_action_secure)
|
holder.typeImage.setImageResource(R.drawable.ic_action_secure)
|
||||||
holder.name.text = pass.toString()
|
holder.name.text = pass.toString()
|
||||||
holder.type.visibility = View.VISIBLE
|
holder.type.visibility = View.VISIBLE
|
||||||
holder.type.text = pass.fullPathToParent.replace("(^/)|(/$)".toRegex(), "")
|
holder.type.text = pass.fullPathToParent.replace("(^/)|(/$)".toRegex(), "")
|
||||||
|
holder.childCount.visibility = View.GONE
|
||||||
|
holder.folderIndicator.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.view.setOnClickListener(getOnClickListener(holder, pass))
|
holder.view.setOnClickListener(getOnClickListener(holder, pass))
|
||||||
|
@ -96,7 +103,7 @@ abstract class EntryRecyclerAdapter internal constructor(val values: ArrayList<P
|
||||||
// after removal, everything is rebound for some reason; views are shuffled?
|
// after removal, everything is rebound for some reason; views are shuffled?
|
||||||
val selected = selectedItems.contains(position)
|
val selected = selectedItems.contains(position)
|
||||||
holder.view.isSelected = selected
|
holder.view.isSelected = selected
|
||||||
(holder.itemView as MultiselectableLinearLayout).setMultiSelected(selected)
|
(holder.itemView as MultiselectableConstraintLayout).setMultiSelected(selected)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun getOnClickListener(holder: ViewHolder, pass: PasswordItem): View.OnClickListener
|
protected abstract fun getOnClickListener(holder: ViewHolder, pass: PasswordItem): View.OnClickListener
|
||||||
|
@ -122,5 +129,7 @@ abstract class EntryRecyclerAdapter internal constructor(val values: ArrayList<P
|
||||||
val name: AppCompatTextView = view.findViewById(R.id.label)
|
val name: AppCompatTextView = view.findViewById(R.id.label)
|
||||||
val type: AppCompatTextView = view.findViewById(R.id.type)
|
val type: AppCompatTextView = view.findViewById(R.id.type)
|
||||||
val typeImage: AppCompatImageView = view.findViewById(R.id.type_image)
|
val typeImage: AppCompatImageView = view.findViewById(R.id.type_image)
|
||||||
|
val childCount: AppCompatTextView = view.findViewById(R.id.child_count)
|
||||||
|
val folderIndicator: AppCompatImageView = view.findViewById(R.id.folder_indicator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,15 +7,15 @@ package com.zeapo.pwdstore.widget
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.LinearLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import com.zeapo.pwdstore.R
|
import com.zeapo.pwdstore.R
|
||||||
|
|
||||||
class MultiselectableLinearLayout @JvmOverloads constructor(
|
class MultiselectableConstraintLayout @JvmOverloads constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
attrs: AttributeSet? = null,
|
attrs: AttributeSet? = null,
|
||||||
defStyleAttr: Int = 0,
|
defStyleAttr: Int = 0,
|
||||||
defStyleRes: Int = 0
|
defStyleRes: Int = 0
|
||||||
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) {
|
) : ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) {
|
||||||
private var multiselected: Boolean = false
|
private var multiselected: Boolean = false
|
||||||
|
|
||||||
override fun onCreateDrawableState(extraSpace: Int): IntArray {
|
override fun onCreateDrawableState(extraSpace: Int): IntArray {
|
||||||
|
@ -35,14 +35,6 @@ class MultiselectableLinearLayout @JvmOverloads constructor(
|
||||||
isActivated = on
|
isActivated = on
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSingleSelected(on: Boolean) {
|
|
||||||
if (multiselected) {
|
|
||||||
multiselected = false
|
|
||||||
refreshDrawableState()
|
|
||||||
}
|
|
||||||
isActivated = on
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val STATE_MULTISELECTED = intArrayOf(R.attr.state_multiselected)
|
private val STATE_MULTISELECTED = intArrayOf(R.attr.state_multiselected)
|
||||||
}
|
}
|
|
@ -6,5 +6,5 @@
|
||||||
android:tint="?attr/passwordIconColor">
|
android:tint="?attr/passwordIconColor">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FFFFFFFF"
|
android:fillColor="#FFFFFFFF"
|
||||||
android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z"/>
|
android:pathData="M8.59,16.59L13.17,12 8.59,7.41 10,6l6,6 -6,6 -1.41,-1.41z"/>
|
||||||
</vector>
|
</vector>
|
10
app/src/main/res/drawable/ic_multiple_files_tinted_24dp.xml
Normal file
10
app/src/main/res/drawable/ic_multiple_files_tinted_24dp.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:viewportWidth="492.924"
|
||||||
|
android:viewportHeight="492.924"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?passwordIconColor">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M405.825 0H188.709c-19.016 0.008 -34.5 15.49 -34.518 34.521v16.297h-16.303c-19.017 0.01 -34.5 15.498 -34.514 34.521v16.309H87.082c-19.029 0.006 -34.494 15.482 -34.514 34.522l0.02 322.238c-0.02 19.043 15.465 34.525 34.494 34.516h152.538c10.65 0 20.871 -4.203 28.438 -11.696l39.516 -39.124h47.415c19.063 0.01 34.546 -15.473 34.532 -34.512v-16.314h16.303c19.048 0.008 34.53 -15.477 34.512 -34.508l0.019 -322.248C440.336 15.482 424.873 0.008 405.825 0zM311.457 391.963h-39.962c-4.777 0 -9.305 0.967 -13.438 2.719c-12.382 5.248 -21.079 17.529 -21.093 31.811v0.01v0.022l0.014 39.137H87.082c-3.98 0 -7.243 -3.25 -7.256 -7.252V136.17c0 -4 3.275 -7.268 7.256 -7.268l217.119 0.01c3.998 0 7.255 3.258 7.255 7.242V391.963zM362.264 407.592c-0.02 3.99 -3.276 7.248 -7.274 7.248h-19.497c1.148 -1.226 3.24 -3.777 3.24 -9.225c0 -67.361 0 -269.445 0 -269.445c-0.018 -19.033 -15.5 -34.516 -34.549 -34.522H130.647V85.334c0 -3.984 3.244 -7.242 7.222 -7.242l217.121 -0.01c3.998 0 7.274 3.268 7.274 7.258V407.592zM413.084 356.77c-0.02 3.992 -3.275 7.25 -7.26 7.25h-16.303l0.014 -278.68c-0.014 -19.029 -15.482 -34.512 -34.546 -34.521H181.467V34.514c0 -3.992 3.258 -7.242 7.223 -7.242l217.135 -0.008c3.984 0 7.26 3.258 7.26 7.258V356.77z" />
|
||||||
|
</vector>
|
|
@ -1,81 +1,80 @@
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:background="?attr/colorPrimary"
|
android:background="?attr/colorPrimary"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical">
|
||||||
tools:context="com.zeapo.pwdstore.PasswordStore">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1">
|
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/app_icon"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/imageView"
|
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:src="@mipmap/ic_launcher"
|
android:src="@mipmap/ic_launcher"
|
||||||
android:contentDescription="@string/app_icon_hint"
|
android:contentDescription="@string/app_icon_hint"
|
||||||
android:layout_centerVertical="true"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
android:layout_centerHorizontal="true" />
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/app_name"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
android:text="@string/app_name"
|
android:text="@string/app_name"
|
||||||
android:layout_below="@+id/imageView"
|
android:layout_below="@+id/app_icon"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textStyle="bold"/>
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/app_icon"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
<Button
|
<com.google.android.material.button.MaterialButton
|
||||||
|
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:onClick="openSettings"
|
android:onClick="openSettings"
|
||||||
style="?android:attr/borderlessButtonStyle"
|
|
||||||
android:text="@string/action_settings"
|
android:text="@string/action_settings"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
android:layout_marginEnd="@dimen/activity_horizontal_margin"
|
||||||
android:layout_marginTop="@dimen/activity_vertical_margin"
|
|
||||||
android:textAllCaps="true"
|
android:textAllCaps="true"
|
||||||
tools:ignore="RelativeOverlap" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
</RelativeLayout>
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<RelativeLayout
|
<com.google.android.material.button.MaterialButton
|
||||||
android:layout_width="match_parent"
|
style="@style/Widget.MaterialComponents.Button"
|
||||||
android:layout_height="48dp"
|
android:id="@+id/use_local_directory"
|
||||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
|
||||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
|
||||||
android:background="?android:attr/windowBackground">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="?android:attr/borderlessButtonStyle"
|
|
||||||
android:backgroundTint="?android:attr/windowBackground"
|
|
||||||
android:onClick="createNewRepository"
|
android:onClick="createNewRepository"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
android:text="@string/initialize"
|
android:text="@string/initialize"
|
||||||
android:layout_alignTop="@+id/main_clone_button"
|
android:textSize="12sp"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_marginTop="48dp"
|
||||||
android:textSize="12sp" />
|
app:backgroundTint="?attr/colorSecondary"
|
||||||
<Button
|
app:rippleColor="?attr/colorControlHighlight"
|
||||||
android:id="@+id/main_clone_button"
|
app:layout_constraintTop_toBottomOf="@id/app_name"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
tools:ignore="UnusedAttribute" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
style="@style/Widget.MaterialComponents.Button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="?android:attr/borderlessButtonStyle"
|
|
||||||
android:backgroundTint="?android:attr/windowBackground"
|
|
||||||
android:onClick="cloneExistingRepository"
|
android:onClick="cloneExistingRepository"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
android:text="@string/clone"
|
android:text="@string/clone"
|
||||||
android:layout_alignParentBottom="true"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
tools:ignore="RelativeOverlap" />
|
app:backgroundTint="?attr/colorSecondary"
|
||||||
|
app:rippleColor="?attr/colorControlHighlight"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/use_local_directory"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<com.zeapo.pwdstore.widget.MultiselectableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<com.zeapo.pwdstore.widget.MultiselectableConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/password_row_background">
|
android:background="@drawable/password_row_background"
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingTop="12dp"
|
android:paddingTop="12dp"
|
||||||
android:paddingBottom="12dp">
|
android:paddingBottom="12dp">
|
||||||
|
|
||||||
|
@ -22,7 +18,7 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
tools:src="@drawable/ic_folder_tinted_24dp" />
|
tools:src="@drawable/ic_multiple_files_tinted_24dp" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/type"
|
android:id="@+id/type"
|
||||||
|
@ -45,8 +41,28 @@
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
app:layout_constraintStart_toEndOf="@id/type_image"
|
app:layout_constraintStart_toEndOf="@id/type_image"
|
||||||
app:layout_constraintTop_toBottomOf="@id/type"
|
app:layout_constraintTop_toBottomOf="@id/type"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/type_image"
|
||||||
tools:text="FILE_NAME" />
|
tools:text="FILE_NAME" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/child_count"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="18sp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/folder_indicator"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
tools:text="12" />
|
||||||
|
|
||||||
</com.zeapo.pwdstore.widget.MultiselectableLinearLayout>
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/folder_indicator"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:src="@drawable/ic_keyboard_arrow_right_24dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
|
|
||||||
|
</com.zeapo.pwdstore.widget.MultiselectableConstraintLayout>
|
||||||
|
|
|
@ -14,5 +14,5 @@
|
||||||
<color name="window_background">@color/primary_color</color>
|
<color name="window_background">@color/primary_color</color>
|
||||||
<color name="password_icon_color">#FAFAFA</color>
|
<color name="password_icon_color">#FAFAFA</color>
|
||||||
<color name="color_surface">#FF111111</color>
|
<color name="color_surface">#FF111111</color>
|
||||||
<color name="list_multiselect_background">#1AEEEEEE</color>
|
<color name="list_multiselect_background">#66EEEEEE</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -16,5 +16,5 @@
|
||||||
<color name="password_icon_color">#757575</color>
|
<color name="password_icon_color">#757575</color>
|
||||||
<color name="color_control_normal">@color/primary_text_color</color>
|
<color name="color_control_normal">@color/primary_text_color</color>
|
||||||
<color name="color_surface">#FFFFFF</color>
|
<color name="color_surface">#FFFFFF</color>
|
||||||
<color name="list_multiselect_background">#EEEEEE</color>
|
<color name="list_multiselect_background">#668eacbb</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue