Merged PR 188108: PeoplePicker intro
- This control has a list of personas with onclicklisteners, which we can later use to control selection. Right now the example just shows a snackbar on "click". No interaction states from design yet. - Fixed a padding bug I missed in the PersonaView PR - Added all the example images from the sketch toolkit so we can have more robust demos ![Screenshot_1538759233.png](https://onedrive.visualstudio.com/4dcbf0bc-c3cd-49c8-a7c3-ec1924691d9b/_apis/git/repositories/32fa6338-45ea-42a0-aca0-484938e1962a/pullRequests/188108/attachments/Screenshot_1538759233.png) Related work items: #640377
|
@ -38,8 +38,11 @@ class DemoActivity : AppCompatActivity() {
|
|||
putSerializable(DemoFragment.DEMO_ID, demoID)
|
||||
}
|
||||
}
|
||||
|
||||
val isDemoScrollable = (fragment as? DemoFragment)?.needsScrollableContainer() ?: true
|
||||
|
||||
supportFragmentManager.beginTransaction()
|
||||
.add(R.id.demo_detail_container, fragment)
|
||||
.add(if (isDemoScrollable) R.id.demo_detail_scrollable_container else R.id.demo_detail_container, fragment)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ open class DemoFragment : Fragment() {
|
|||
|
||||
private var demo: Demo? = null
|
||||
|
||||
open fun needsScrollableContainer(): Boolean = true
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
arguments?.let {
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
package com.microsoft.officeuifabricdemo
|
||||
|
||||
import android.support.v4.app.Fragment
|
||||
import com.microsoft.officeuifabricdemo.demos.AvatarFragment
|
||||
import com.microsoft.officeuifabricdemo.demos.ButtonFragment
|
||||
import com.microsoft.officeuifabricdemo.demos.PersonaFragment
|
||||
import com.microsoft.officeuifabricdemo.demos.TemplateViewFragment
|
||||
import com.microsoft.officeuifabricdemo.demos.TypographyFragment
|
||||
import com.microsoft.officeuifabricdemo.demos.*
|
||||
import java.util.*
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
val DEMOS = arrayListOf(
|
||||
Demo("Avatar", AvatarFragment::class),
|
||||
Demo("Button", ButtonFragment::class),
|
||||
Demo("PeoplePicker", PeoplePickerFragment::class),
|
||||
Demo("Persona", PersonaFragment::class),
|
||||
Demo("TemplateView", TemplateViewFragment::class),
|
||||
Demo("Typography", TypographyFragment::class)
|
||||
|
|
|
@ -29,10 +29,10 @@ class AvatarFragment : DemoFragment() {
|
|||
// Avatar drawables with bitmap
|
||||
loadBitmapFromPicasso(avatar_example_picasso)
|
||||
loadBitmapFromGlide(avatar_example_glide)
|
||||
avatar_example_local.setImageResource(R.drawable.avatar_male)
|
||||
avatar_example_local.setImageResource(R.drawable.avatar_erik_nason)
|
||||
|
||||
// Avatar drawable with initials
|
||||
avatar_example_initials.setInfo(getString(R.string.avatar_female_name), getString(R.string.avatar_female_email))
|
||||
avatar_example_initials.setInfo(getString(R.string.persona_name_kat_larsson), getString(R.string.persona_email_kat_larsson))
|
||||
|
||||
// Add AvatarView with code
|
||||
createNewAvatarFromCode()
|
||||
|
@ -40,13 +40,13 @@ class AvatarFragment : DemoFragment() {
|
|||
|
||||
private fun loadBitmapFromPicasso(imageView: ImageView) {
|
||||
Picasso.get()
|
||||
.load(R.drawable.avatar_female)
|
||||
.load(R.drawable.avatar_celeste_burton)
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
private fun loadBitmapFromGlide(imageView: ImageView) {
|
||||
Glide.with(this)
|
||||
.load(R.drawable.avatar_female)
|
||||
.load(R.drawable.avatar_isaac_fielder)
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ class AvatarFragment : DemoFragment() {
|
|||
val context = context ?: return
|
||||
val avatarView = AvatarView(context)
|
||||
avatarView.avatarSize = AvatarSize.XXLARGE
|
||||
avatarView.setInfo(getString(R.string.avatar_male_name), getString(R.string.avatar_male_email))
|
||||
avatarView.setInfo(getString(R.string.persona_name_mauricio_august), getString(R.string.persona_email_mauricio_august))
|
||||
avatarView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
avatarView.id = R.id.avatar_example_code
|
||||
avatar_layout.addView(avatarView)
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
/**
|
||||
* Copyright © 2018 Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
package com.microsoft.officeuifabricdemo.demos
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.support.design.widget.Snackbar
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.microsoft.officeuifabric.peoplepicker.PersonaListAdapter
|
||||
import com.microsoft.officeuifabric.persona.IPersona
|
||||
import com.microsoft.officeuifabric.persona.Persona
|
||||
import com.microsoft.officeuifabricdemo.DemoFragment
|
||||
import com.microsoft.officeuifabricdemo.R
|
||||
import kotlinx.android.synthetic.main.fragment_people_picker.*
|
||||
|
||||
class PeoplePickerFragment : DemoFragment() {
|
||||
private lateinit var personaList: ArrayList<IPersona>
|
||||
|
||||
override fun needsScrollableContainer(): Boolean = false
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
preparePersonaList()
|
||||
return inflater.inflate(R.layout.fragment_people_picker, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
people_picker_example.personaList = personaList
|
||||
people_picker_example.onItemClicked = object : PersonaListAdapter.Callback {
|
||||
override fun onItemClicked(persona: IPersona) {
|
||||
val snackbar = Snackbar.make(
|
||||
view,
|
||||
"You clicked on the cell for ${persona.name}, ${persona.subtitle}",
|
||||
Snackbar.LENGTH_SHORT
|
||||
)
|
||||
snackbar.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun preparePersonaList() {
|
||||
val context = context ?: return
|
||||
personaList = arrayListOf(
|
||||
createPersona(
|
||||
getString(R.string.persona_name_amanda_brady),
|
||||
getString(R.string.persona_subtitle_manager),
|
||||
R.drawable.avatar_amanda_brady
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_lydia_bauer),
|
||||
getString(R.string.persona_subtitle_researcher)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_daisy_phillips),
|
||||
getString(R.string.persona_subtitle_designer),
|
||||
imageDrawable = ContextCompat.getDrawable(context, R.drawable.avatar_daisy_phillips)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_allan_munger) + getString(R.string.persona_truncation),
|
||||
getString(R.string.persona_subtitle_manager)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_mauricio_august),
|
||||
getString(R.string.persona_subtitle_designer),
|
||||
imageBitmap = BitmapFactory.decodeResource(resources, R.drawable.avatar_mauricio_august)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_ashley_mccarthy),
|
||||
getString(R.string.persona_subtitle_engineer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_miguel_garcia),
|
||||
getString(R.string.persona_subtitle_researcher),
|
||||
imageUri = getUriFromResource(context, R.drawable.avatar_miguel_garcia)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_carole_poland),
|
||||
getString(R.string.persona_subtitle_researcher)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_mona_kane),
|
||||
getString(R.string.persona_subtitle_designer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_carlos_slattery),
|
||||
getString(R.string.persona_subtitle_engineer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_wanda_howard),
|
||||
getString(R.string.persona_subtitle_engineer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_tim_deboer),
|
||||
getString(R.string.persona_subtitle_researcher)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_robin_counts),
|
||||
getString(R.string.persona_subtitle_designer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_elliot_woordward),
|
||||
getString(R.string.persona_subtitle_designer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_cecil_folk),
|
||||
getString(R.string.persona_subtitle_manager),
|
||||
R.drawable.avatar_colin_ballinger
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_celeste_burton),
|
||||
getString(R.string.persona_subtitle_researcher)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_elvia_atkins),
|
||||
getString(R.string.persona_subtitle_designer),
|
||||
imageDrawable = ContextCompat.getDrawable(context, R.drawable.avatar_elvia_atkins)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_colin_ballinger),
|
||||
getString(R.string.persona_subtitle_manager)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_katri_ahokas),
|
||||
getString(R.string.persona_subtitle_designer),
|
||||
imageBitmap = BitmapFactory.decodeResource(resources, R.drawable.avatar_katri_ahokas)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_henry_brill),
|
||||
getString(R.string.persona_subtitle_engineer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_johnie_mcconnell),
|
||||
getString(R.string.persona_subtitle_researcher),
|
||||
imageUri = getUriFromResource(context, R.drawable.avatar_johnie_mcconnell)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_kevin_sturgis),
|
||||
getString(R.string.persona_subtitle_researcher)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_kristen_patterson),
|
||||
getString(R.string.persona_subtitle_designer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_charlotte_waltson),
|
||||
getString(R.string.persona_subtitle_engineer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_erik_nason),
|
||||
getString(R.string.persona_subtitle_engineer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_isaac_fielder),
|
||||
getString(R.string.persona_subtitle_researcher)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_mauricio_august),
|
||||
getString(R.string.persona_subtitle_designer)
|
||||
),
|
||||
createPersona(
|
||||
getString(R.string.persona_name_amanda_brady),
|
||||
getString(R.string.persona_subtitle_designer)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getUriFromResource(context: Context, avatarDrawable: Int): Uri? {
|
||||
return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE +
|
||||
"://" + context.resources.getResourcePackageName(avatarDrawable) +
|
||||
'/'.toString() + context.resources.getResourceTypeName(avatarDrawable) +
|
||||
'/'.toString() + context.resources.getResourceEntryName(avatarDrawable)
|
||||
)
|
||||
}
|
||||
|
||||
private fun createPersona(name: String, subtitle: String, imageResource: Int? = null, imageDrawable: Drawable? = null,
|
||||
imageBitmap: Bitmap? = null, imageUri: Uri? = null): Persona {
|
||||
val persona = Persona(name)
|
||||
persona.subtitle = subtitle
|
||||
persona.avatarImageResource = imageResource
|
||||
persona.avatarImageDrawable = imageDrawable
|
||||
persona.avatarImageBitmap = imageBitmap
|
||||
persona.avatarImageUri = imageUri
|
||||
return persona
|
||||
}
|
||||
}
|
|
@ -31,8 +31,8 @@ class PersonaFragment: DemoFragment() {
|
|||
val context = context ?: return
|
||||
val personaView = PersonaView(context)
|
||||
personaView.avatarSize = AvatarSize.SMALL
|
||||
personaView.name = resources.getString(R.string.avatar_male_name)
|
||||
personaView.email = resources.getString(R.string.avatar_male_email)
|
||||
personaView.name = resources.getString(R.string.persona_name_mauricio_august)
|
||||
personaView.email = resources.getString(R.string.persona_email_mauricio_august)
|
||||
personaView.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
persona_layout.addView(personaView)
|
||||
}
|
||||
|
|
После Ширина: | Высота: | Размер: 294 KiB |
После Ширина: | Высота: | Размер: 301 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_ashley_mccarthy.png
Executable file
После Ширина: | Высота: | Размер: 271 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_carlos_slattery.png
Executable file
После Ширина: | Высота: | Размер: 298 KiB |
После Ширина: | Высота: | Размер: 299 KiB |
После Ширина: | Высота: | Размер: 292 KiB |
После Ширина: | Высота: | Размер: 346 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_charlotte_waltson.png
Executable file
После Ширина: | Высота: | Размер: 316 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_colin_ballinger.png
Executable file
После Ширина: | Высота: | Размер: 285 KiB |
После Ширина: | Высота: | Размер: 274 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_elliot_woodward.png
Executable file
После Ширина: | Высота: | Размер: 286 KiB |
После Ширина: | Высота: | Размер: 272 KiB |
После Ширина: | Высота: | Размер: 337 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_female.png
До Ширина: | Высота: | Размер: 20 KiB |
После Ширина: | Высота: | Размер: 340 KiB |
После Ширина: | Высота: | Размер: 263 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_johnie_mcconnell.png
Executable file
После Ширина: | Высота: | Размер: 326 KiB |
После Ширина: | Высота: | Размер: 335 KiB |
После Ширина: | Высота: | Размер: 308 KiB |
После Ширина: | Высота: | Размер: 314 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_kristin_patterson.png
Executable file
После Ширина: | Высота: | Размер: 319 KiB |
После Ширина: | Высота: | Размер: 314 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_male.png
До Ширина: | Высота: | Размер: 18 KiB |
Двоичные данные
OfficeUIFabric.Demo/src/main/res/drawable/avatar_mauricio_august.png
Executable file
После Ширина: | Высота: | Размер: 272 KiB |
После Ширина: | Высота: | Размер: 301 KiB |
После Ширина: | Высота: | Размер: 265 KiB |
После Ширина: | Высота: | Размер: 248 KiB |
После Ширина: | Высота: | Размер: 275 KiB |
После Ширина: | Высота: | Размер: 276 KiB |
После Ширина: | Высота: | Размер: 293 KiB |
|
@ -23,9 +23,16 @@
|
|||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.v4.widget.NestedScrollView
|
||||
android:id="@+id/demo_detail_container"
|
||||
android:id="@+id/demo_detail_scrollable_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/demo_detail_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.microsoft.officeuifabric.peoplepicker.PersonaListView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/people_picker_example"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
|
@ -11,22 +11,20 @@
|
|||
android:id="@+id/persona_example_xxlarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/default_layout_margin"
|
||||
app:avatarSize="xxlarge"
|
||||
app:email="@string/avatar_female_email"
|
||||
app:email="@string/persona_email_kat_larsson"
|
||||
app:footer="@string/persona_footer"
|
||||
app:name="@string/avatar_female_name"
|
||||
app:subtitle="@string/avatar_female_email" />
|
||||
app:name="@string/persona_name_kat_larsson"
|
||||
app:subtitle="@string/persona_email_kat_larsson" />
|
||||
|
||||
<com.microsoft.officeuifabric.persona.PersonaView
|
||||
android:id="@+id/persona_example_large"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/default_layout_margin"
|
||||
app:avatarDrawable="@drawable/avatar_male"
|
||||
app:avatarDrawable="@drawable/avatar_tim_deboer"
|
||||
app:avatarSize="large"
|
||||
app:email="@string/avatar_male_email"
|
||||
app:name="@string/avatar_male_name"
|
||||
app:subtitle="@string/avatar_male_email" />
|
||||
app:email="@string/persona_email_mauricio_august"
|
||||
app:name="@string/persona_name_mauricio_august"
|
||||
app:subtitle="@string/persona_email_mauricio_august" />
|
||||
|
||||
</LinearLayout>
|
|
@ -5,11 +5,42 @@
|
|||
<string name="action_settings">Settings</string>
|
||||
<string name="title_demo_detail">Control Demo</string>
|
||||
|
||||
<!--Avatar-->
|
||||
<string name="avatar_female_name">Kat Larson</string>
|
||||
<string name="avatar_female_email">klarson@microsoft.com</string>
|
||||
<string name="avatar_male_name">Maor Sharett</string>
|
||||
<string name="avatar_male_email">maorsharett@microsoft.com</string>
|
||||
<!--Persona-->
|
||||
<string name="persona_email_kat_larsson">klarsson@microsoft.com</string>
|
||||
<string name="persona_email_mauricio_august">maugust@microsoft.com</string>
|
||||
<string name="persona_footer">Available</string>
|
||||
<string name="persona_name_allan_munger">Allan Munger</string>
|
||||
<string name="persona_name_amanda_brady">Amanda Brady</string>
|
||||
<string name="persona_name_ashley_mccarthy">Ashley McCarthy</string>
|
||||
<string name="persona_name_carlos_slattery">Carlos Slattery</string>
|
||||
<string name="persona_name_carole_poland">Carole Poland</string>
|
||||
<string name="persona_name_cecil_folk">Cecil Folk</string>
|
||||
<string name="persona_name_celeste_burton">Celeste Burton</string>
|
||||
<string name="persona_name_charlotte_waltson">Charlotte Waltson</string>
|
||||
<string name="persona_name_colin_ballinger">Colin Ballinger</string>
|
||||
<string name="persona_name_daisy_phillips">Daisy Phillips</string>
|
||||
<string name="persona_name_elliot_woordward">Elliot Woodward</string>
|
||||
<string name="persona_name_elvia_atkins">Elvia Atkins</string>
|
||||
<string name="persona_name_erik_nason">Erik Nason</string>
|
||||
<string name="persona_name_henry_brill">Henry Brill</string>
|
||||
<string name="persona_name_isaac_fielder">Isaac Fielder</string>
|
||||
<string name="persona_name_johnie_mcconnell">Johnie McConnell</string>
|
||||
<string name="persona_name_kat_larsson">Kat Larsson</string>
|
||||
<string name="persona_name_katri_ahokas">Katri Ahokas</string>
|
||||
<string name="persona_name_kevin_sturgis">Kevin Sturgis</string>
|
||||
<string name="persona_name_kristen_patterson">Kristen Patterson</string>
|
||||
<string name="persona_name_lydia_bauer">Lydia Bauer</string>
|
||||
<string name="persona_name_mauricio_august">Mauricio August</string>
|
||||
<string name="persona_name_miguel_garcia">Miguel Garcia</string>
|
||||
<string name="persona_name_mona_kane">Mona Kane</string>
|
||||
<string name="persona_name_robin_counts">Robin Counts</string>
|
||||
<string name="persona_name_tim_deboer">Tim Deboer</string>
|
||||
<string name="persona_name_wanda_howard">Wanda Howard</string>
|
||||
<string name="persona_subtitle_designer">Designer</string>
|
||||
<string name="persona_subtitle_engineer">Engineer</string>
|
||||
<string name="persona_subtitle_manager">Manager</string>
|
||||
<string name="persona_subtitle_researcher">Researcher</string>
|
||||
<string name="persona_truncation">\ (long text example to test truncation)</string>
|
||||
|
||||
<!--TemplateView-->
|
||||
<string name="cell_sample_title">Title</string>
|
||||
|
@ -30,7 +61,4 @@
|
|||
<string name="body_1">Body 1</string>
|
||||
<string name="body_2">Body 2</string>
|
||||
<string name="caption">Caption</string>
|
||||
|
||||
<!--Persona-->
|
||||
<string name="persona_footer">Available</string>
|
||||
</resources>
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* Copyright © 2018 Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
package com.microsoft.officeuifabric.peoplepicker
|
||||
|
||||
import android.content.Context
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import com.microsoft.officeuifabric.persona.*
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* This adapter controls data binding and ViewHolders for [PersonaListView].
|
||||
*/
|
||||
class PersonaListAdapter(private val context: Context) : RecyclerView.Adapter<PersonaListAdapter.ViewHolder>() {
|
||||
/**
|
||||
* [Callback] for when a list item is clicked
|
||||
*/
|
||||
var clickCallback: Callback? = null
|
||||
/**
|
||||
* Collection of [Persona] objects that hold data to create the [PersonaView]s
|
||||
*/
|
||||
var personaList = ArrayList<IPersona>()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = PersonaView(context)
|
||||
view.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
view.avatarSize = AvatarSize.LARGE
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
if (position in 0 until personaList.size)
|
||||
holder.setPersona(personaList[position])
|
||||
else
|
||||
return
|
||||
}
|
||||
|
||||
override fun getItemCount() = personaList.size
|
||||
|
||||
private fun onItemClicked(persona: IPersona) {
|
||||
clickCallback?.onItemClicked(persona)
|
||||
}
|
||||
|
||||
inner class ViewHolder : RecyclerView.ViewHolder, View.OnClickListener {
|
||||
private val personaView: PersonaView
|
||||
private lateinit var persona: IPersona
|
||||
|
||||
constructor(view: PersonaView) : super(view) {
|
||||
personaView = view
|
||||
view.setOnClickListener(this)
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
onItemClicked(persona)
|
||||
}
|
||||
|
||||
fun setPersona(persona: IPersona) {
|
||||
this.persona = persona
|
||||
personaView.setPersona(persona)
|
||||
}
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
fun onItemClicked(persona: IPersona)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Copyright © 2018 Microsoft Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
package com.microsoft.officeuifabric.peoplepicker
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.InsetDrawable
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v7.widget.DividerItemDecoration
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.util.AttributeSet
|
||||
import com.microsoft.officeuifabric.R
|
||||
import com.microsoft.officeuifabric.persona.AvatarSize
|
||||
import com.microsoft.officeuifabric.persona.IPersona
|
||||
import com.microsoft.officeuifabric.persona.PersonaView
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* This is a custom [RecyclerView] with a set adapter and layoutManager. It provides an interface for the list data and clickCallback and
|
||||
* adds a custom [DividerItemDecoration] to each row.
|
||||
*/
|
||||
class PersonaListView : RecyclerView {
|
||||
/**
|
||||
* [personaList] contains the collection of Personas that the adapter binds to the ViewHolder.
|
||||
*/
|
||||
var personaList = ArrayList<IPersona>()
|
||||
set(value) {
|
||||
field = value
|
||||
personaListAdapter.personaList = value
|
||||
}
|
||||
|
||||
/**
|
||||
* This clickCallback is called when a [PersonaView] cell is clicked.
|
||||
*/
|
||||
var onItemClicked: PersonaListAdapter.Callback? = null
|
||||
set(value) {
|
||||
field = value
|
||||
personaListAdapter.clickCallback = value
|
||||
}
|
||||
|
||||
private val personaListAdapter = PersonaListAdapter(context)
|
||||
|
||||
@JvmOverloads
|
||||
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(context, attrs, defStyleAttr) {
|
||||
adapter = personaListAdapter
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
addCustomDivider((layoutManager as LinearLayoutManager).orientation)
|
||||
}
|
||||
|
||||
private fun addCustomDivider(orientation: Int) {
|
||||
val dividerItemDecoration = DividerItemDecoration(context, orientation)
|
||||
val spacing = PersonaView.getSpacing(context, AvatarSize.LARGE)
|
||||
val insetDrawable = InsetDrawable(ContextCompat.getDrawable(context, R.drawable.divider_people_picker), spacing.insetLeft, 0, spacing.cellPadding, 0)
|
||||
dividerItemDecoration.setDrawable(insetDrawable)
|
||||
addItemDecoration(dividerItemDecoration)
|
||||
}
|
||||
}
|
|
@ -63,7 +63,7 @@ open class AvatarView : AppCompatImageView {
|
|||
|
||||
override fun setImageBitmap(bitmap: Bitmap?) {
|
||||
if (bitmap == null) {
|
||||
super.setImageBitmap(bitmap)
|
||||
return
|
||||
} else {
|
||||
val roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(resources, bitmap)
|
||||
roundedBitmapDrawable.isCircular = true
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package com.microsoft.officeuifabric.persona
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
|
||||
interface IPersona {
|
||||
var name: String
|
||||
var email: String
|
||||
var subtitle: String
|
||||
var footer: String
|
||||
var avatarImageBitmap: Bitmap?
|
||||
var avatarImageDrawable: Drawable?
|
||||
var avatarImageResource: Int?
|
||||
var avatarImageUri: Uri?
|
||||
}
|
||||
|
||||
data class Persona(override var name: String = "", override var email: String = "") : IPersona {
|
||||
override var subtitle: String = ""
|
||||
override var footer: String = ""
|
||||
override var avatarImageBitmap: Bitmap? = null
|
||||
override var avatarImageDrawable: Drawable? = null
|
||||
override var avatarImageResource: Int? = null
|
||||
override var avatarImageUri: Uri? = null
|
||||
}
|
|
@ -24,6 +24,16 @@ import kotlinx.android.synthetic.main.view_persona.view.*
|
|||
class PersonaView : LinearLayout {
|
||||
companion object {
|
||||
val personaAvatarSizes = arrayOf(AvatarSize.SMALL, AvatarSize.LARGE, AvatarSize.XXLARGE)
|
||||
|
||||
internal data class Spacing(val cellPadding: Int, val insetLeft: Int)
|
||||
|
||||
internal fun getSpacing(context: Context, avatarSize: AvatarSize): Spacing {
|
||||
val avatarDisplaySize = avatarSize.getDisplayValue(context)
|
||||
val spacingRight = context.resources.getDimension(R.dimen.uifabric_persona_horizontal_spacing)
|
||||
val cellPadding = context.resources.getDimension(R.dimen.uifabric_persona_cell_horizontal_padding).toInt()
|
||||
val insetLeft = (avatarDisplaySize + spacingRight + cellPadding).toInt()
|
||||
return Spacing(cellPadding, insetLeft)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,3 +175,14 @@ class PersonaView : LinearLayout {
|
|||
persona_subtitle.visibility = if (subtitle != "" && avatarSize != AvatarSize.SMALL) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
fun PersonaView.setPersona(persona: IPersona) {
|
||||
name = persona.name
|
||||
email = persona.email
|
||||
subtitle = persona.subtitle
|
||||
footer = persona.footer
|
||||
avatarImageBitmap = persona.avatarImageBitmap
|
||||
avatarImageDrawable = persona.avatarImageDrawable
|
||||
avatarImageResource = persona.avatarImageResource
|
||||
avatarImageUri = persona.avatarImageUri
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--TODO: Merge with DatePicker's divider-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<size android:height="@dimen/uifabric_divider_height" />
|
||||
|
||||
<solid android:color="@color/uifabric_divider" />
|
||||
|
||||
</shape>
|
|
@ -11,6 +11,7 @@
|
|||
android:layout_marginBottom="@dimen/uifabric_persona_cell_vertical_padding"
|
||||
android:layout_marginEnd="@dimen/uifabric_persona_horizontal_spacing"
|
||||
android:layout_marginStart="@dimen/uifabric_persona_cell_horizontal_padding"
|
||||
android:layout_marginTop="@dimen/uifabric_persona_cell_vertical_padding"
|
||||
app:avatarSize="large" />
|
||||
|
||||
<LinearLayout
|
||||
|
@ -18,6 +19,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/uifabric_persona_cell_vertical_padding"
|
||||
android:layout_marginTop="@dimen/uifabric_persona_cell_vertical_padding"
|
||||
android:layout_marginEnd="@dimen/uifabric_persona_horizontal_spacing"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="uifabric_gray">#8E8E93</color>
|
||||
<color name="uifabric_divider">#E1E1E1</color>
|
||||
<color name="uifabric_black">#222222</color>
|
||||
<array name="uifabric_avatar_background_colors">
|
||||
<item>#FF3298DB</item>
|
||||
<item>#FF50BBC4</item>
|
||||
<item>#FF32C270</item>
|
||||
<item>#FFF07E21</item>
|
||||
<item>#FFE6463C</item>
|
||||
<item>#FFF0CE0E</item>
|
||||
<item>#FFF069B1</item>
|
||||
<item>#FF9E75DB</item>
|
||||
<item>#FFAC735F</item>
|
||||
<item>#FFA5A5AB</item>
|
||||
<item>#750B1C</item>
|
||||
<item>#A4262C</item>
|
||||
<item>#D13438</item>
|
||||
<item>#CA5010</item>
|
||||
<item>#986F0B</item>
|
||||
<item>#498205</item>
|
||||
<item>#005E50</item>
|
||||
<item>#038387</item>
|
||||
<item>#0078D4</item>
|
||||
<item>#004E8C</item>
|
||||
<item>#4F6BED</item>
|
||||
<item>#373277</item>
|
||||
<item>#881798</item>
|
||||
<item>#C239B3</item>
|
||||
<item>#E3008C</item>
|
||||
<item>#603D30</item>
|
||||
<item>#69797E</item>
|
||||
<item>#7A7574</item>
|
||||
<item>#393939</item>
|
||||
</array>
|
||||
</resources>
|
|
@ -7,6 +7,8 @@
|
|||
<dimen name="uifabric_avatar_size_xlarge">52dp</dimen>
|
||||
<dimen name="uifabric_avatar_size_xxlarge">64dp</dimen>
|
||||
|
||||
<dimen name="uifabric_divider_height">.5dp</dimen>
|
||||
|
||||
<!--Persona-->
|
||||
<dimen name="uifabric_persona_horizontal_spacing">16dp</dimen>
|
||||
<dimen name="uifabric_persona_cell_horizontal_padding">16dp</dimen>
|
||||
|
|