diff --git a/OfficeUIFabric.Demo/src/main/AndroidManifest.xml b/OfficeUIFabric.Demo/src/main/AndroidManifest.xml index f3df148..d06462f 100644 --- a/OfficeUIFabric.Demo/src/main/AndroidManifest.xml +++ b/OfficeUIFabric.Demo/src/main/AndroidManifest.xml @@ -23,7 +23,10 @@ - + diff --git a/OfficeUIFabric.Demo/src/main/res/layout/activity_people_picker_view.xml b/OfficeUIFabric.Demo/src/main/res/layout/activity_people_picker_view.xml index ee9d6f6..0e801de 100644 --- a/OfficeUIFabric.Demo/src/main/res/layout/activity_people_picker_view.xml +++ b/OfficeUIFabric.Demo/src/main/res/layout/activity_people_picker_view.xml @@ -2,24 +2,24 @@ + android:divider="@drawable/ms_row_divider" + android:orientation="vertical" + android:showDividers="middle"> + android:layout_height="wrap_content" + app:label="@string/people_picker_select_example" + app:personaChipClickStyle="select" /> + android:layout_height="wrap_content" + app:label="@string/people_picker_select_deselect_example" + app:personaChipClickStyle="select_deselect" /> \ No newline at end of file diff --git a/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerTextView.kt b/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerTextView.kt index 922c5a3..1edbd7c 100644 --- a/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerTextView.kt +++ b/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerTextView.kt @@ -58,7 +58,7 @@ internal class PeoplePickerTextView : TokenCompleteTextView { } /** - * Defines what happens when a user clicks on a [personaChip] token. + * Defines what happens when a user clicks on a [personaChip]. */ var personaChipClickStyle: PeoplePickerPersonaChipClickStyle = PeoplePickerPersonaChipClickStyle.Select set(value) { diff --git a/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerTextViewAdapter.kt b/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerTextViewAdapter.kt index b9db678..817495d 100644 --- a/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerTextViewAdapter.kt +++ b/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerTextViewAdapter.kt @@ -63,13 +63,12 @@ internal class PeoplePickerTextViewAdapter : ArrayAdapter, Filterable private fun createDivider(): InsetDrawable { val spacing = PersonaView.getSpacing(context, AvatarSize.LARGE) - val insetDrawable = InsetDrawable( + return InsetDrawable( ContextCompat.getDrawable(context, R.drawable.ms_row_divider), spacing.insetLeft, 0, spacing.cellPadding, 0 ) - return insetDrawable } } \ No newline at end of file diff --git a/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerView.kt b/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerView.kt index 0730902..4bedc01 100644 --- a/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerView.kt +++ b/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/peoplepicker/PeoplePickerView.kt @@ -5,6 +5,8 @@ package com.microsoft.officeuifabric.peoplepicker import android.content.Context +import android.content.res.Configuration +import android.graphics.Rect import android.util.AttributeSet import android.view.ViewGroup import android.widget.Filter @@ -19,13 +21,10 @@ import kotlinx.android.synthetic.main.view_people_picker.view.* typealias PeoplePickerPersonaChipClickStyle = TokenCompleteTextView.TokenClickStyle /** - * [PeoplePickerView] is a customizable [TemplateView] comprised of a label and [PeoplePickerTextView]. + * [PeoplePickerView] is a customizable view comprised of a label and [PeoplePickerTextView]. * * TODO Future work: * - Handle cases where [pickedPersonas] is modified programmatically. - * - Use Outlook's adjustDropDownPositionAndSize and getMaxAvailableHeight methods in ContactPickerView - * to resize the drop down to the available space in the view. This will make the list less jumpy, - * which is most noticeable when it appears above the [PeoplePickerTextView]. */ class PeoplePickerView : TemplateView { /** @@ -177,6 +176,54 @@ class PeoplePickerView : TemplateView { peoplePickerTextView?.addObject(persona) } + // Dropdown + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + adjustDropDownHeight() + } + + override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { + super.onLayout(changed, left, top, right, bottom) + adjustDropDownHeight() + } + + private fun adjustDropDownHeight() { + val dropDownHeight = getMaxAvailableHeight() + if (peoplePickerTextView?.dropDownHeight == dropDownHeight) + return + peoplePickerTextView?.dropDownHeight = dropDownHeight + if (peoplePickerTextView?.isPopupShowing == true) + // Force popup layout to refresh + peoplePickerTextView?.showDropDown() + } + + /** + * Adapted from Android's PopupWindow. + */ + private fun getMaxAvailableHeight(): Int { + val displayFrame = Rect() + getWindowVisibleDisplayFrame(displayFrame) + + val anchorLocationOnScreen = IntArray(2) + getLocationOnScreen(anchorLocationOnScreen) + + val anchorTop = anchorLocationOnScreen[1] + val yOffset = resources.getDimension(R.dimen.uifabric_people_picker_dropdown_vertical_offset).toInt() + val distanceToBottom = displayFrame.bottom - (anchorTop + height) - yOffset + val distanceToTop = anchorTop - displayFrame.top + yOffset + var returnedHeight = Math.max(distanceToBottom, distanceToTop) + + val background = peoplePickerTextView?.dropDownBackground + if (background != null) { + val backgroundPadding = Rect() + background.getPadding(backgroundPadding) + returnedHeight -= backgroundPadding.top + backgroundPadding.bottom + } + + return returnedHeight + } + // Filter private class PersonaFilter(val view: PeoplePickerView) : Filter() { @@ -193,17 +240,17 @@ class PeoplePickerView : TemplateView { val availablePersonas = view.availablePersonas val suggestedPersonas: ArrayList - if (availablePersonas == null) - suggestedPersonas = ArrayList() - else - if (constraint != null) { + suggestedPersonas = when { + availablePersonas == null -> ArrayList() + constraint != null -> { val searchTerm = constraint.toString().toLowerCase() val filteredResults = availablePersonas.filter { it.name.toLowerCase().contains(searchTerm) && !view.pickedPersonas.contains(it) } - suggestedPersonas = ArrayList(filteredResults) - } else - suggestedPersonas = availablePersonas + ArrayList(filteredResults) + } + else -> availablePersonas + } return FilterResults().apply { values = suggestedPersonas count = suggestedPersonas.size @@ -218,8 +265,7 @@ class PeoplePickerView : TemplateView { view.peoplePickerTextViewAdapter?.personas = it } } - } - else { + } else { view.peoplePickerTextViewAdapter?.personas = results.values as ArrayList } } diff --git a/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/persona/PersonaChipView.kt b/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/persona/PersonaChipView.kt index 88102eb..37e0b5a 100644 --- a/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/persona/PersonaChipView.kt +++ b/OfficeUIFabric/src/main/java/com/microsoft/officeuifabric/persona/PersonaChipView.kt @@ -164,7 +164,7 @@ class PersonaChipView : TemplateView { private fun setDisabledState() { avatarView?.alpha = DISABLED_BACKGROUND_OPACITY - updateStateStyles(R.drawable.persona_chip_background_normal, R.color.uifabric_chip_disabled_text) + updateStateStyles(R.drawable.persona_chip_background_normal, R.color.uifabric_persona_chip_disabled_text) } private fun setNormalState() { @@ -173,15 +173,15 @@ class PersonaChipView : TemplateView { updateCloseIconVisibility(false) } if (hasError) { - updateStateStyles(R.drawable.persona_chip_background_normal_error, R.color.uifabric_chip_error_text) + updateStateStyles(R.drawable.persona_chip_background_normal_error, R.color.uifabric_persona_chip_error_text) } else { - updateStateStyles(R.drawable.persona_chip_background_normal, R.color.uifabric_chip_normal_text) + updateStateStyles(R.drawable.persona_chip_background_normal, R.color.uifabric_persona_chip_normal_text) } } private fun setPressedState() { - updateStateStyles(R.drawable.persona_chip_background_pressed, R.color.uifabric_chip_normal_text) + updateStateStyles(R.drawable.persona_chip_background_pressed, R.color.uifabric_persona_chip_normal_text) } private fun setSelectedState() { @@ -189,9 +189,9 @@ class PersonaChipView : TemplateView { updateCloseIconVisibility(true) } if (hasError) { - updateStateStyles(R.drawable.persona_chip_background_active_error, R.color.uifabric_chip_active_text) + updateStateStyles(R.drawable.persona_chip_background_active_error, R.color.uifabric_persona_chip_active_text) } else { - updateStateStyles(R.drawable.persona_chip_background_active, R.color.uifabric_chip_active_text) + updateStateStyles(R.drawable.persona_chip_background_active, R.color.uifabric_persona_chip_active_text) } } diff --git a/OfficeUIFabric/src/main/res/drawable/people_picker_popup_background.xml b/OfficeUIFabric/src/main/res/drawable/people_picker_popup_background.xml new file mode 100644 index 0000000..b7bcad1 --- /dev/null +++ b/OfficeUIFabric/src/main/res/drawable/people_picker_popup_background.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/OfficeUIFabric/src/main/res/drawable/people_picker_popup_background_above.xml b/OfficeUIFabric/src/main/res/drawable/people_picker_popup_background_above.xml new file mode 100644 index 0000000..9c250cf --- /dev/null +++ b/OfficeUIFabric/src/main/res/drawable/people_picker_popup_background_above.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/OfficeUIFabric/src/main/res/drawable/people_picker_popup_background_below.xml b/OfficeUIFabric/src/main/res/drawable/people_picker_popup_background_below.xml new file mode 100644 index 0000000..1419ac2 --- /dev/null +++ b/OfficeUIFabric/src/main/res/drawable/people_picker_popup_background_below.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_active.xml b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_active.xml index 8074cd3..69eaf62 100644 --- a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_active.xml +++ b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_active.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_active_error.xml b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_active_error.xml index 97e7201..e0a8c05 100644 --- a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_active_error.xml +++ b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_active_error.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_normal.xml b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_normal.xml index 5b5688e..8819295 100644 --- a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_normal.xml +++ b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_normal.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_normal_error.xml b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_normal_error.xml index b807063..62b5313 100644 --- a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_normal_error.xml +++ b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_normal_error.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_pressed.xml b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_pressed.xml index 29704f3..f0a6587 100644 --- a/OfficeUIFabric/src/main/res/drawable/persona_chip_background_pressed.xml +++ b/OfficeUIFabric/src/main/res/drawable/persona_chip_background_pressed.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/OfficeUIFabric/src/main/res/layout/view_people_picker.xml b/OfficeUIFabric/src/main/res/layout/view_people_picker.xml index c7c89e3..fa9f35f 100644 --- a/OfficeUIFabric/src/main/res/layout/view_people_picker.xml +++ b/OfficeUIFabric/src/main/res/layout/view_people_picker.xml @@ -29,14 +29,16 @@ android:id="@+id/people_picker_text_view" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@color/uifabric_white" + android:background="@color/uifabric_people_picker_text_view_background" android:gravity="center_vertical" android:dropDownWidth="match_parent" android:dropDownVerticalOffset="@dimen/uifabric_people_picker_dropdown_vertical_offset" android:imeOptions="flagNoExtractUi|actionDone" android:minHeight="@dimen/uifabric_min_touch_size" - android:paddingTop="@dimen/uifabric_people_picker_token_padding" - android:paddingBottom="@dimen/uifabric_people_picker_token_padding" + android:paddingTop="@dimen/uifabric_people_picker_text_view_padding" + android:paddingBottom="@dimen/uifabric_people_picker_text_view_padding" + android:popupBackground="@drawable/people_picker_popup_background" + android:popupElevation="@dimen/uifabric_people_picker_popup_elevation" android:textAppearance="@style/TextAppearance.UIFabric.PeoplePickerText" android:textColorHint="@android:color/transparent" /> diff --git a/OfficeUIFabric/src/main/res/layout/view_persona_chip.xml b/OfficeUIFabric/src/main/res/layout/view_persona_chip.xml index ceb3af4..1fc864a 100644 --- a/OfficeUIFabric/src/main/res/layout/view_persona_chip.xml +++ b/OfficeUIFabric/src/main/res/layout/view_persona_chip.xml @@ -5,23 +5,23 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" - android:layout_height="@dimen/uifabric_chip_height" + android:layout_height="@dimen/uifabric_persona_chip_height" android:baselineAligned="true" android:orientation="horizontal" - android:padding="@dimen/uifabric_chip_padding"> + android:padding="@dimen/uifabric_persona_chip_padding"> #393939 - - @color/uifabric_background_gray - @color/uifabric_black - - #0D000000 - @color/uifabric_primary - @color/uifabric_white - - #FFF3F4 - - #E8484C - - #A80000 - @color/uifabric_gray - @color/uifabric_primary @color/uifabric_gray @@ -86,6 +71,25 @@ @color/uifabric_primary @color/uifabric_gray + + @color/uifabric_white + @color/uifabric_white + + + @color/uifabric_background_gray + @color/uifabric_black + + #0D000000 + @color/uifabric_primary + @color/uifabric_white + + #FFF3F4 + + #E8484C + + #A80000 + @color/uifabric_gray + @color/uifabric_border_gray diff --git a/OfficeUIFabric/src/main/res/values/dimens.xml b/OfficeUIFabric/src/main/res/values/dimens.xml index ee36e72..d7d9116 100644 --- a/OfficeUIFabric/src/main/res/values/dimens.xml +++ b/OfficeUIFabric/src/main/res/values/dimens.xml @@ -40,8 +40,9 @@ 8dp - 6dp + 0dp 0dp + 6dp 16dp @@ -51,9 +52,9 @@ 8dp - 32dp - 6dp - 6dp + 32dp + 6dp + 6dp .5dp