-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
319 additions
and
40 deletions.
There are no files selected for viewing
Submodule gn_mobile_core
updated
20 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,7 @@ open class Filter<T : Parcelable>( | |
* @author [S. Grimault](mailto:[email protected]) | ||
*/ | ||
enum class FilterType { | ||
NAME, | ||
AREA_OBSERVATION, | ||
TAXONOMY | ||
} | ||
|
52 changes: 52 additions & 0 deletions
52
occtax/src/main/java/fr/geonature/occtax/ui/input/taxa/FilterName.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package fr.geonature.occtax.ui.input.taxa | ||
|
||
import android.os.Parcel | ||
import android.os.Parcelable | ||
|
||
/** | ||
* Name filter. | ||
* | ||
* @author [S. Grimault](mailto:[email protected]) | ||
*/ | ||
class FilterName(value: Name) : Filter<FilterName.Name>( | ||
FilterType.NAME, | ||
value | ||
) { | ||
class Name(val type: NameType) : | ||
Parcelable { | ||
|
||
private constructor(source: Parcel) : this( | ||
NameType.valueOf(source.readString() ?: NameType.SCIENTIFIC.name) | ||
) | ||
|
||
override fun describeContents(): Int { | ||
return 0 | ||
} | ||
|
||
override fun writeToParcel(dest: Parcel?, flags: Int) { | ||
dest?.also { | ||
it.writeString(type.name) | ||
} | ||
} | ||
|
||
companion object CREATOR : Parcelable.Creator<Name> { | ||
override fun createFromParcel(parcel: Parcel): Name { | ||
return Name(parcel) | ||
} | ||
|
||
override fun newArray(size: Int): Array<Name?> { | ||
return arrayOfNulls(size) | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Taxon name types. | ||
* | ||
* @author [S. Grimault](mailto:[email protected]) | ||
*/ | ||
enum class NameType { | ||
SCIENTIFIC, | ||
COMMON | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
occtax/src/main/java/fr/geonature/occtax/ui/input/taxa/FilterNameRecyclerViewAdapter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package fr.geonature.occtax.ui.input.taxa | ||
|
||
import android.view.View | ||
import android.widget.Switch | ||
import fr.geonature.commons.ui.adapter.AbstractListItemRecyclerViewAdapter | ||
import fr.geonature.occtax.R | ||
|
||
/** | ||
* Default RecyclerView Adapter for [FilterName]. | ||
* | ||
* @author [S. Grimault](mailto:[email protected]) | ||
*/ | ||
class FilterNameRecyclerViewAdapter(val listener: FilterRecyclerViewAdapterListener<FilterName>) : | ||
AbstractListItemRecyclerViewAdapter<FilterName>() { | ||
|
||
init { | ||
setItems(listOf(FilterName(FilterName.Name(FilterName.NameType.SCIENTIFIC)))) | ||
} | ||
|
||
override fun getViewHolder(view: View, viewType: Int): AbstractViewHolder { | ||
return ViewHolder(view) | ||
} | ||
|
||
override fun getLayoutResourceId(position: Int, item: FilterName): Int { | ||
return R.layout.list_item_filter_name | ||
} | ||
|
||
override fun areItemsTheSame( | ||
oldItems: List<FilterName>, | ||
newItems: List<FilterName>, | ||
oldItemPosition: Int, | ||
newItemPosition: Int | ||
): Boolean { | ||
return oldItems[oldItemPosition] == newItems[newItemPosition] | ||
} | ||
|
||
override fun areContentsTheSame( | ||
oldItems: List<FilterName>, | ||
newItems: List<FilterName>, | ||
oldItemPosition: Int, | ||
newItemPosition: Int | ||
): Boolean { | ||
return oldItems[oldItemPosition] == newItems[newItemPosition] | ||
} | ||
|
||
fun setSelectedFilter(filter: FilterName) { | ||
this.setItems(listOf(filter)) | ||
|
||
notifyDataSetChanged() | ||
} | ||
|
||
inner class ViewHolder(itemView: View) : | ||
AbstractListItemRecyclerViewAdapter<FilterName>.AbstractViewHolder(itemView) { | ||
|
||
private val switch: Switch = itemView.findViewById(R.id.switch_name) | ||
|
||
override fun onBind(item: FilterName) { | ||
switch.setOnClickListener { | ||
listener.onSelectedFilters(if (switch.isChecked) FilterName(FilterName.Name(FilterName.NameType.COMMON)) else FilterName(FilterName.Name(FilterName.NameType.SCIENTIFIC))) | ||
} | ||
|
||
switch.isChecked = item.value.type == FilterName.NameType.COMMON | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,17 +13,29 @@ import fr.geonature.commons.ui.adapter.StickyHeaderItemDecorator | |
import fr.geonature.occtax.R | ||
|
||
/** | ||
* Default RecyclerView Adapter used by [TaxaFilterFragment], combining [FilterAreaObservationRecyclerViewAdapter] and [FilterTaxonomyRecyclerViewAdapter] | ||
* Default RecyclerView Adapter used by [TaxaFilterFragment], combining [FilterNameRecyclerViewAdapter], | ||
* [FilterAreaObservationRecyclerViewAdapter] and [FilterTaxonomyRecyclerViewAdapter]. | ||
* | ||
* @author [S. Grimault](mailto:[email protected]) | ||
* | ||
* @see FilterNameRecyclerViewAdapter | ||
* @see FilterAreaObservationRecyclerViewAdapter | ||
* @see FilterTaxonomyRecyclerViewAdapter | ||
*/ | ||
class FilterRecyclerViewAdapter(val listener: FilterRecyclerViewAdapterListener<Filter<*>>) : | ||
RecyclerView.Adapter<RecyclerView.ViewHolder>(), | ||
IStickyRecyclerViewAdapter<FilterRecyclerViewAdapter.HeaderViewHolder> { | ||
|
||
private val filterNameRecyclerViewAdapter: FilterNameRecyclerViewAdapter = | ||
FilterNameRecyclerViewAdapter(object : FilterRecyclerViewAdapterListener<FilterName> { | ||
override fun onSelectedFilters(vararg filter: FilterName) { | ||
val existingFilters = | ||
selectedFilters.filter { it.type != Filter.FilterType.NAME } | ||
selectedFilters.clear() | ||
selectedFilters.addAll(existingFilters + filter) | ||
listener.onSelectedFilters(*selectedFilters.toTypedArray()) | ||
} | ||
}) | ||
private val filterTitleAreaObservationRecyclerViewAdapter = FilterTitleRecyclerViewAdapter() | ||
private val filterAreaObservationRecyclerViewAdapter: FilterAreaObservationRecyclerViewAdapter = | ||
FilterAreaObservationRecyclerViewAdapter(object : | ||
|
@@ -49,6 +61,7 @@ class FilterRecyclerViewAdapter(val listener: FilterRecyclerViewAdapterListener< | |
} | ||
}) | ||
private val mergeAdapter = MergeAdapter( | ||
filterNameRecyclerViewAdapter, | ||
filterTitleAreaObservationRecyclerViewAdapter, | ||
filterAreaObservationRecyclerViewAdapter, | ||
filterTitleTaxonomyRecyclerViewAdapter, | ||
|
@@ -167,28 +180,30 @@ class FilterRecyclerViewAdapter(val listener: FilterRecyclerViewAdapterListener< | |
} | ||
|
||
override fun getHeaderPositionForItem(itemPosition: Int): Int { | ||
if (itemPosition == 0) { | ||
return 0 | ||
// the first adapter has no header | ||
if (itemPosition < filterNameRecyclerViewAdapter.itemCount) { | ||
|
||
return -1 | ||
} | ||
|
||
// if first adapter have some items | ||
if (filterAreaObservationRecyclerViewAdapter.itemCount > 0 && itemPosition < (filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount)) { | ||
return 0 | ||
// if filter area observation have some items | ||
if (filterAreaObservationRecyclerViewAdapter.itemCount > 0 && itemPosition < (filterNameRecyclerViewAdapter.itemCount + filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount)) { | ||
return filterNameRecyclerViewAdapter.itemCount | ||
} | ||
|
||
if (itemPosition == filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount - 1) { | ||
if (itemPosition == filterNameRecyclerViewAdapter.itemCount + filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount - 1) { | ||
return itemPosition | ||
} | ||
|
||
val currentFilterTaxonomy = | ||
filterTaxonomyRecyclerViewAdapter.items.getOrNull(itemPosition - (filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount)) | ||
?: return filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount | ||
filterTaxonomyRecyclerViewAdapter.items.getOrNull(itemPosition - (filterNameRecyclerViewAdapter.itemCount + filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount)) | ||
?: return filterNameRecyclerViewAdapter.itemCount + filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount | ||
|
||
return filterTaxonomyRecyclerViewAdapter.items.indexOfFirst { | ||
it.value.kingdom == currentFilterTaxonomy.value.kingdom && it.value.group == Taxonomy.ANY | ||
}.takeIf { it >= 0 } | ||
?.plus(filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount) | ||
?: filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount - 1 | ||
?.plus(filterNameRecyclerViewAdapter.itemCount + filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount) | ||
?: filterNameRecyclerViewAdapter.itemCount + filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount - 1 | ||
} | ||
|
||
override fun onBindHeaderViewHolder(holder: HeaderViewHolder, headerPosition: Int) { | ||
|
@@ -216,6 +231,10 @@ class FilterRecyclerViewAdapter(val listener: FilterRecyclerViewAdapterListener< | |
this.selectedFilters.clear() | ||
this.selectedFilters.addAll(filter) | ||
|
||
(filter.find { it.type == Filter.FilterType.NAME } as FilterName?)?.also { | ||
this.filterNameRecyclerViewAdapter.setSelectedFilter(it) | ||
} | ||
|
||
this.filterAreaObservationRecyclerViewAdapter.setSelectedFilters(*filter.filter { it.type == Filter.FilterType.AREA_OBSERVATION } | ||
.map { FilterAreaObservation(it.value as FilterAreaObservation.AreaObservation) } | ||
.toTypedArray()) | ||
|
@@ -247,24 +266,18 @@ class FilterRecyclerViewAdapter(val listener: FilterRecyclerViewAdapterListener< | |
Typeface.BOLD | ||
) | ||
|
||
if (position == 0) { | ||
label.text = filterTitleAreaObservationRecyclerViewAdapter.items.getOrNull(0) | ||
?: filterTitleTaxonomyRecyclerViewAdapter.items.getOrNull(0) | ||
return | ||
} | ||
|
||
if (filterAreaObservationRecyclerViewAdapter.itemCount > 0 && position < (filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount)) { | ||
if (filterAreaObservationRecyclerViewAdapter.itemCount > 0 && position < (filterNameRecyclerViewAdapter.itemCount + filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount)) { | ||
label.text = filterTitleAreaObservationRecyclerViewAdapter.items.getOrNull(0) | ||
return | ||
} | ||
|
||
if (position == filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount - 1) { | ||
if (position == filterNameRecyclerViewAdapter.itemCount + filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount - 1) { | ||
label.text = filterTitleTaxonomyRecyclerViewAdapter.items.getOrNull(0) | ||
return | ||
} | ||
|
||
val taxonomyAsHeader = | ||
filterTaxonomyRecyclerViewAdapter.items.getOrNull(position - (filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount)) | ||
filterTaxonomyRecyclerViewAdapter.items.getOrNull(position - (filterNameRecyclerViewAdapter.itemCount + filterAreaObservationRecyclerViewAdapter.itemCount + filterTitleAreaObservationRecyclerViewAdapter.itemCount + filterTitleTaxonomyRecyclerViewAdapter.itemCount)) | ||
|
||
if (taxonomyAsHeader == null) { | ||
label.text = filterTitleTaxonomyRecyclerViewAdapter.items.getOrNull(0) | ||
|
Oops, something went wrong.