Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve entity browser design #6152

Merged
merged 3 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import org.odk.collect.entities.databinding.ListLayoutBinding
import org.odk.collect.lists.RecyclerViewUtils
import org.odk.collect.lists.RecyclerViewUtils.matchParentWidth

class EntitiesFragment(private val viewModelFactory: ViewModelProvider.Factory) : Fragment() {
Expand All @@ -29,6 +30,7 @@ class EntitiesFragment(private val viewModelFactory: ViewModelProvider.Factory)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val binding = ListLayoutBinding.bind(view)
binding.list.layoutManager = LinearLayoutManager(requireContext())
binding.list.addItemDecoration(RecyclerViewUtils.verticalLineDivider(requireContext()))

val list = EntitiesFragmentArgs.fromBundle(requireArguments()).list
entitiesViewModel.getEntities(list).observe(viewLifecycleOwner) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class EntityItemView(context: Context) : FrameLayout(context) {
binding.label.text = entity.label
binding.properties.text = entity.properties
.sortedBy { it.first }
.joinToString(separator = ", ") { "${it.first}: ${it.second}" }
.joinToString(separator = "\n") { "${it.first}: ${it.second}" }
binding.offlinePill.isVisible = entity.state == Entity.State.OFFLINE
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.odk.collect.entities.databinding.AddEntitiesDialogLayoutBinding
import org.odk.collect.entities.databinding.EntityListItemLayoutBinding
import org.odk.collect.entities.databinding.ListLayoutBinding
import org.odk.collect.lists.RecyclerViewUtils

class EntityListsFragment(
private val viewModelFactory: ViewModelProvider.Factory,
Expand All @@ -41,6 +42,7 @@ class EntityListsFragment(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val binding = ListLayoutBinding.bind(view)
binding.list.layoutManager = LinearLayoutManager(requireContext())
binding.list.addItemDecoration(RecyclerViewUtils.verticalLineDivider(requireContext()))

entitiesViewModel.lists.observe(viewLifecycleOwner) {
binding.list.adapter = ListsAdapter(it, findNavController())
Expand Down Expand Up @@ -72,6 +74,7 @@ private class ListsMenuProvider(
val binding = AddEntitiesDialogLayoutBinding.inflate(LayoutInflater.from(context))
MaterialAlertDialogBuilder(context)
.setView(binding.root)
.setTitle(org.odk.collect.strings.R.string.add_entity_list)
.setPositiveButton(org.odk.collect.strings.R.string.add) { _, _ ->
entitiesViewModel.addEntityList(binding.entityListName.text.toString())
}
Expand Down
44 changes: 27 additions & 17 deletions entities/src/main/res/layout/entity_item_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,46 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:paddingHorizontal="@dimen/margin_standard"
android:paddingTop="@dimen/margin_standard">
android:background="?android:attr/selectableItemBackground">

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="@dimen/margin_standard" />

<org.odk.collect.material.MaterialPill
android:id="@+id/offline_pill"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_standard"
app:icon="@drawable/ic_baseline_wifi_off_24"
app:layout_constraintStart_toStartOf="@id/guideline_start"
app:layout_constraintTop_toTopOf="parent"
app:pillBackgroundColor="?colorSurfaceContainerHighest"
app:text="@string/offline" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/label"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_small"
android:textAppearance="?textAppearanceTitleMedium"
app:layout_constraintEnd_toStartOf="@id/offline_pill"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="@id/guideline_start"
app:layout_constraintTop_toBottomOf="@id/offline_pill"
tools:text="Label" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/properties"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_extra_small"
android:layout_marginBottom="@dimen/margin_standard"
android:textAppearance="?textAppearanceBodyMedium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@id/guideline_start"
app:layout_constraintTop_toBottomOf="@id/label"
tools:text="property1: value1, property2: value2" />

<org.odk.collect.material.MaterialPill
android:id="@+id/offline_pill"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:icon="@drawable/ic_baseline_visibility_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/label"
app:text="@string/offline" />
tools:text="property1: value1" />

</androidx.constraintlayout.widget.ConstraintLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class EntityItemViewTest {
)

val propertiesView = view.binding.properties
assertThat(propertiesView.text, equalTo("length: 2:50, name: S.D.O.S"))
assertThat(propertiesView.text, equalTo("length: 2:50\nname: S.D.O.S"))
}

@Test
Expand Down
5 changes: 5 additions & 0 deletions icons/src/main/res/drawable/ic_baseline_wifi_off_24.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M22.99,9C19.15,5.16 13.8,3.76 8.84,4.78l2.52,2.52c3.47,-0.17 6.99,1.05 9.63,3.7l2,-2zM18.99,13c-1.29,-1.29 -2.84,-2.13 -4.49,-2.56l3.53,3.53 0.96,-0.97zM2,3.05L5.07,6.1C3.6,6.82 2.22,7.78 1,9l1.99,2c1.24,-1.24 2.67,-2.16 4.2,-2.77l2.24,2.24C7.81,10.89 6.27,11.73 5,13v0.01L6.99,15c1.36,-1.36 3.14,-2.04 4.92,-2.06L18.98,20l1.27,-1.26L3.29,1.79 2,3.05zM9,17l3,3 3,-3c-1.65,-1.66 -4.34,-1.66 -6,0z"/>

</vector>
47 changes: 30 additions & 17 deletions material/src/main/java/org/odk/collect/material/MaterialPill.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.odk.collect.material

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.drawable.ColorDrawable
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
Expand Down Expand Up @@ -29,21 +30,22 @@ open class MaterialPill(context: Context, attrs: AttributeSet?) :
binding.text.text = text
}

private val shapeAppearanceModel =
ShapeAppearanceModel.builder(context, getShapeAppearance(context), -1).build()

val binding = PillBinding.inflate(LayoutInflater.from(context), this, true)

init {
background = createMaterialShapeDrawable(getDefaultBackgroundColor(context))

context.withStyledAttributes(attrs, R.styleable.MaterialPill) {
text = getString(R.styleable.MaterialPill_text)

val iconId = getResourceId(R.styleable.MaterialPill_icon, -1)
if (iconId != -1) {
setIcon(iconId)
}

val backgroundColor = getColor(
R.styleable.MaterialPill_pillBackgroundColor,
getDefaultBackgroundColor(context)
)
setPillBackgroundColor(backgroundColor)
}
}

Expand All @@ -61,26 +63,37 @@ open class MaterialPill(context: Context, attrs: AttributeSet?) :
}

fun setPillBackgroundColor(@ColorInt color: Int) {
background = createMaterialShapeDrawable(color)
if (isInEditMode) {
/**
* For some reason `ShapeAppearanceModel` can't be built in Android Studio's design
* preview (even when using a Material 3 theme). It could be that some of the
* attibutes used here are not available in the basic themes, but are set in the real
* ones we use. For now, just setting a "unshaped" background is an easier option than
* deep diving.
*/
background = ColorDrawable(color)
return
}

val shapeAppearance = getThemeAttributeValue(
context,
com.google.android.material.R.attr.shapeAppearanceCornerSmall
)

val shapeAppearanceModel =
ShapeAppearanceModel.builder(context, shapeAppearance, -1).build()

background = MaterialShapeDrawable(shapeAppearanceModel).also {
it.fillColor = ColorStateList.valueOf(color)
}
}

fun setTextColor(@ColorInt color: Int) {
binding.text.setTextColor(color)
}

private fun getShapeAppearance(context: Context) = getThemeAttributeValue(
context,
com.google.android.material.R.attr.shapeAppearanceCornerSmall
)

private fun getDefaultBackgroundColor(context: Context) = getThemeAttributeValue(
context,
com.google.android.material.R.attr.colorPrimaryContainer
)

private fun createMaterialShapeDrawable(@ColorInt color: Int): MaterialShapeDrawable {
return MaterialShapeDrawable(shapeAppearanceModel).also {
it.fillColor = ColorStateList.valueOf(color)
}
}
}
1 change: 1 addition & 0 deletions material/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
<declare-styleable name="MaterialPill">
<attr name="icon" />
<attr name="text" format="string" />
<attr name="pillBackgroundColor" format="reference"/>
</declare-styleable>
</resources>