From 12c61c94a3bb27c96c2a5105e546e3330ff9e3a1 Mon Sep 17 00:00:00 2001 From: Rituraj Sambherao <54317407+ritsam@users.noreply.github.com> Date: Fri, 20 Nov 2020 17:11:34 +0000 Subject: [PATCH] custom view Horizontal list of flags (EXPOSUREAPP-3736) (#1626) * countryList mofidication * Country Names list implemented * flag size adjustment * removing hardcoded sizes and spacings * ViewHolder changed and code cleanup * layouts adjusted * Finish CountryListView Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com> Co-authored-by: Matthias Urhahn <matthias.urhahn@sap.com> --- .../java/de/rki/coronawarnapp/ui/Country.kt | 5 +- .../rki/coronawarnapp/ui/view/CountryList.kt | 48 ------------ .../coronawarnapp/ui/view/CountryListView.kt | 78 +++++++++++++++++++ ..._list_participating_countries_overview.xml | 14 ++-- ...lude_submission_positive_other_warning.xml | 8 +- ...view_country_list_entry_flag_container.xml | 34 ++++++++ .../view_country_list_entry_flag_item.xml | 8 ++ 7 files changed, 136 insertions(+), 59 deletions(-) delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CountryList.kt create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CountryListView.kt create mode 100644 Corona-Warn-App/src/main/res/layout/view_country_list_entry_flag_container.xml create mode 100644 Corona-Warn-App/src/main/res/layout/view_country_list_entry_flag_item.xml diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/Country.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/Country.kt index 2c22c8b00..25c5d3f8f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/Country.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/Country.kt @@ -3,6 +3,7 @@ package de.rki.coronawarnapp.ui import androidx.annotation.DrawableRes import androidx.annotation.StringRes import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.util.ui.CachedString enum class Country( val code: String, @@ -40,5 +41,7 @@ enum class Country( RO("ro", R.string.country_name_ro, R.drawable.ic_country_ro), SE("se", R.string.country_name_se, R.drawable.ic_country_se), SI("si", R.string.country_name_si, R.drawable.ic_country_si), - SK("sk", R.string.country_name_sk, R.drawable.ic_country_sk) + SK("sk", R.string.country_name_sk, R.drawable.ic_country_sk); + + val label = CachedString { it.getString(labelRes) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CountryList.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CountryList.kt deleted file mode 100644 index a97986690..000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CountryList.kt +++ /dev/null @@ -1,48 +0,0 @@ -package de.rki.coronawarnapp.ui.view - -import android.content.Context -import android.util.AttributeSet -import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.TextView -import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.ui.Country -import java.text.Collator - -class CountryList(context: Context, attrs: AttributeSet) : - LinearLayout(context, attrs) { - - private var _list: List<Country>? = null - var list: List<Country>? - get() = _list - set(value) { - _list = value - buildList() - } - - init { - orientation = VERTICAL - } - - /** - * Cleans the view and rebuilds the list of countries. Presets already selected countries - */ - private fun buildList() { - this.removeAllViews() - list - ?.map { country -> - context.getString(country.labelRes) to country.iconRes - } - ?.sortedWith { a, b -> - Collator.getInstance().compare(a.first, b.first) - } - ?.forEachIndexed { index, (label, iconRes) -> - inflate(context, R.layout.view_country_list_entry, this) - val child = this.getChildAt(index) - child.apply { - findViewById<ImageView>(R.id.country_list_entry_image).setImageResource(iconRes) - findViewById<TextView>(R.id.country_list_entry_label).text = label - } - } - } -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CountryListView.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CountryListView.kt new file mode 100644 index 000000000..38163a84e --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CountryListView.kt @@ -0,0 +1,78 @@ +package de.rki.coronawarnapp.ui.view + +import android.content.Context +import android.util.AttributeSet +import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.TextView +import androidx.recyclerview.widget.GridLayoutManager +import androidx.recyclerview.widget.RecyclerView +import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.databinding.ViewCountryListEntryFlagItemBinding +import de.rki.coronawarnapp.ui.Country +import de.rki.coronawarnapp.ui.lists.BaseAdapter +import de.rki.coronawarnapp.ui.view.CountryFlagsAdapter.CountryFlagViewHolder +import de.rki.coronawarnapp.util.lists.BindableVH + +class CountryListView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { + + private val adapterCountryFlags = CountryFlagsAdapter() + private val grid: RecyclerView + private val countryNames: TextView + + var countries: List<Country> = emptyList() + set(value) { + field = value.also { countries -> + adapterCountryFlags.countryList = countries + countryNames.text = countries.joinToString(", ") { it.label.get(context) } + } + } + + init { + orientation = HORIZONTAL + inflate(context, R.layout.view_country_list_entry_flag_container, this) + + grid = findViewById<RecyclerView>(R.id.flagGrid).apply { + layoutManager = GridLayoutManager(context, FLAG_COLUMNS) + adapter = adapterCountryFlags + } + countryNames = findViewById(R.id.country_list_entry_label) + } + + // Helper to allow for null in data binding + fun setCountryList(countries: List<Country>?) { + this.countries = countries ?: emptyList() + } + + companion object { + private const val FLAG_COLUMNS = 8 + } +} + +private class CountryFlagsAdapter : BaseAdapter<CountryFlagViewHolder>() { + + var countryList: List<Country> = emptyList() + set(value) { + field = value + notifyDataSetChanged() + } + + override fun getItemCount(): Int = countryList.size + + override fun onCreateBaseVH(parent: ViewGroup, viewType: Int): CountryFlagViewHolder = CountryFlagViewHolder(parent) + + override fun onBindBaseVH(holder: CountryFlagViewHolder, position: Int) = holder.bind(countryList[position]) + + class CountryFlagViewHolder(val parent: ViewGroup) : VH( + R.layout.view_country_list_entry_flag_item, parent + ), BindableVH<Country, ViewCountryListEntryFlagItemBinding> { + + override val viewBinding: Lazy<ViewCountryListEntryFlagItemBinding> = lazy { + ViewCountryListEntryFlagItemBinding.bind(itemView) + } + + override val onBindData: ViewCountryListEntryFlagItemBinding.(key: Country) -> Unit = { item -> + countryListEntryImage.setImageResource(item.iconRes) + } + } +} diff --git a/Corona-Warn-App/src/main/res/layout/include_interop_list_participating_countries_overview.xml b/Corona-Warn-App/src/main/res/layout/include_interop_list_participating_countries_overview.xml index f6142d91d..6ecf73f51 100644 --- a/Corona-Warn-App/src/main/res/layout/include_interop_list_participating_countries_overview.xml +++ b/Corona-Warn-App/src/main/res/layout/include_interop_list_participating_countries_overview.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto"> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> <data> @@ -36,17 +37,18 @@ android:visibility="@{FormatterHelper.formatVisibilityText(countryListTitle)}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" + tools:text="@string/interoperability_onboarding_list_title" /> - <de.rki.coronawarnapp.ui.view.CountryList + <de.rki.coronawarnapp.ui.view.CountryListView android:id="@+id/countryList" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" + android:layout_marginTop="@dimen/spacing_tiny" + app:countryList="@{countryData}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/country_header_description" - app:list="@{countryData}" /> + app:layout_constraintTop_toBottomOf="@+id/country_header_description" /> <TextView android:id="@+id/label_country_selection_info" diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_positive_other_warning.xml b/Corona-Warn-App/src/main/res/layout/include_submission_positive_other_warning.xml index a3cc144f4..0dc277c24 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_positive_other_warning.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_positive_other_warning.xml @@ -67,22 +67,22 @@ app:layout_constraintStart_toStartOf="@id/guideline_start" app:layout_constraintTop_toBottomOf="@+id/submission_positive_other_warning_text" /> - <de.rki.coronawarnapp.ui.view.CountryList + <de.rki.coronawarnapp.ui.view.CountryListView android:id="@+id/countryList" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" + android:layout_marginTop="@dimen/spacing_tiny" app:layout_constraintEnd_toEndOf="@+id/submission_country_header_description" app:layout_constraintStart_toStartOf="@+id/submission_country_header_description" app:layout_constraintTop_toBottomOf="@+id/submission_country_header_description" - app:list="@{countryData}" /> + app:countryList="@{countryData}" /> <include android:id="@+id/submission_positive_location_card_16_years" layout="@layout/include_16_years" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_large" + android:layout_marginTop="@dimen/spacing_normal" android:focusable="true" app:body="@{@string/sixteen_description_text}" app:headline="@{@string/sixteen_title_text}" diff --git a/Corona-Warn-App/src/main/res/layout/view_country_list_entry_flag_container.xml b/Corona-Warn-App/src/main/res/layout/view_country_list_entry_flag_container.xml new file mode 100644 index 000000000..1d1e7b16c --- /dev/null +++ b/Corona-Warn-App/src/main/res/layout/view_country_list_entry_flag_container.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + android:orientation="vertical"> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/flagGrid" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <View + android:layout_width="match_parent" + android:layout_height="3dp" + android:layout_marginTop="@dimen/spacing_small" + android:background="@color/colorHairline" /> + + <TextView + android:id="@+id/country_list_entry_label" + style="@style/subtitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + tools:text="Deutschland, Frankreich" /> + + <View + android:layout_width="match_parent" + android:layout_height="3dp" + android:background="@color/colorHairline" /> +</LinearLayout> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/layout/view_country_list_entry_flag_item.xml b/Corona-Warn-App/src/main/res/layout/view_country_list_entry_flag_item.xml new file mode 100644 index 000000000..1d37e33e4 --- /dev/null +++ b/Corona-Warn-App/src/main/res/layout/view_country_list_entry_flag_item.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<ImageView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/country_list_entry_image" + android:layout_width="28dp" + android:layout_height="28dp" + android:layout_margin="4dp" + app:srcCompat="@drawable/ic_country_eu" /> -- GitLab