Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building for Wear OS “Workshop” - Introduction ...

Building for Wear OS “Workshop” - Introduction & Part1-

The workshop slide "Building for Wear OS Workshop - Introduction & Part1"
#wearos #android #workshop

Kenichi Kambara

November 17, 2022
Tweet

More Decks by Kenichi Kambara

Other Decks in Technology

Transcript

  1. Building for Wear OS “Workshop” - Introduction & Part1- Kenichi

    Kambara (@korodroid) 17 November, 2022 2022
  2. Agenda •Part1 (Development) by Kenichi Kambara •Short Session: Developing Apps

    for Wear OS •Workshop: Developing Wear OS Apps •Part2 (Test) by Josh Murigi •Short Session: Writing tests for Wear OS Apps •Workshop: Testing Wear OS Compose Codelab App •Q&A
  3. 3 About me Kenichi Kambara (@korodroid) •Mobile App Development •Speeches

    (e.g. 12 International confs.) •Writings (e.g. 7 Dev Books) •[Of fi cial] Evangelist at NTT TechnoCross •[Private] iplatform.org
  4. Wear OS Features  Overlay Noti fi cation Complication Based

    on Android & optimized for the wrist Tile 
  5.  Compose for Wear OS is now 1.0: time to

    build wearable apps with Compose! (27 July, 2022) ref: https://android-developers.googleblog.com/2022/07/compose-for-wear-os-10-stable.html Now Stable!!
  6.  @Composable fun ChipExample(){ Chip( modifier = Modifier .fillMaxWidth(), icon

    = { Image( painter = painterResource(id = R.drawable.flag_jp), contentDescription = "Japan", ) }, label = {Text(text = “Japan")}, secondaryLabel = {Text(text = "Tokyo")}, onClick = { /* do anything */ }, ) } Implementation Example (Chip)
  7. Optimized for the wrist: UI & UX Input components Dialogs

    Page Indicator Progress Indicator  Navigation
  8. Differences on Wear OS & Mobile  Wear OS 


    (androidx.wear.*) Mobile 
 (androidx.*) androidx.wear.compose:compose-material androidx.compose.foundation:foundation androidx.wear.compose:compose-foundation androidx.compose.material:material androidx.navigation:navigation-compose androidx.compose.foundation:foundation ref: https://developer.android.com/training/wearables/compose Material androidx.wear.compose:compose-navigation Navigation Foundation
  9. Contact App (First Version)  @Composable fun ContactListScreenV0() { LazyColumn(

    horizontalAlignment = Alignment.CenterHorizontally ) { item { ListHeader { Text(text = "Contacts") } } items(model.data.size) { Chip( modifier = Modifier .fillMaxSize(), icon = { Icon( Icons.Rounded.Face, contentDescription = "faceIcon", ) }, label = { Text(model.data[it]) }, colors = ChipDefaults.primaryChipColors(), onClick = { }, ) } } }
  10. 5 Steps for improving this App  •Step1. Replacing with

    ScalingLazyColumn •Step2. Using a Scaffold •Step3. Adding a new Screen •Step4. Implementing Navigation •Step5. Replacing with Wear Navigation 

  11.  •Go future with Wear OS & Jetpack Compose🚀 


    •Important to optimize for Wearable Device⌚ •Let’s expand Wear OS World with making apps💪
  12. Please let me know if you have any requests 


    such as technical speeches, technical writings and so on. http://www.linkedin.com/in/korodroid Thank you so much http://fb.com/kanbara.kenichi @korodroid
  13. Step1. Replacing with ScalingLazyColumn  @Composable fun ContactListScreenV1() { ScalingLazyColumn(

    horizontalAlignment = Alignment.CenterHorizontally ) { item { ListHeader { Text(text = "Contacts") } } items(model.data.size) { Chip( modifier = Modifier .fillMaxSize(), icon = { Icon( Icons.Rounded.Face, contentDescription = "faceIcon", ) }, label = { Text(model.data[it]) }, colors = ChipDefaults.primaryChipColors(), onClick = { }, ) } } }
  14. Step2. Using a Scaffold  @Composable fun ContactListScreenV2() { val

    listState = rememberScalingLazyListState() Scaffold( timeText = { if (!listState.isScrollInProgress) { TimeText() } }, vignette = { Vignette( vignettePosition = VignettePosition.TopAndBottom ) }, positionIndicator = { PositionIndicator( scalingLazyListState = listState, ) } ) { ScalingLazyColumn(state = listState) { // … }
  15. Step2-1. TimeText  @Composable fun ContactListScreenV2() { val listState =

    rememberScalingLazyListState() Scaffold( timeText = { if (!listState.isScrollInProgress) { TimeText() } }, vignette = { Vignette( vignettePosition = VignettePosition.TopAndBottom ) }, positionIndicator = { PositionIndicator( scalingLazyListState = listState, ) } ) { ScalingLazyColumn(state = listState) { // … }
  16. Step2-2. Vignette  @Composable fun ContactListScreenV2() { val listState =

    rememberScalingLazyListState() Scaffold( timeText = { if (!listState.isScrollInProgress) { TimeText() } }, vignette = { Vignette( vignettePosition = VignettePosition.TopAndBottom ) }, positionIndicator = { PositionIndicator( scalingLazyListState = listState, ) } ) { ScalingLazyColumn(state = listState) { // … }
  17. Step2-3. PositionIndicator  @Composable fun ContactListScreenV2() { val listState =

    rememberScalingLazyListState() Scaffold( timeText = { if (!listState.isScrollInProgress) { TimeText() } }, vignette = { Vignette( vignettePosition = VignettePosition.TopAndBottom ) }, positionIndicator = { PositionIndicator( scalingLazyListState = listState, ) } ) { ScalingLazyColumn(state = listState) { // … }
  18. Step3. Adding a new Screen  @Composable fun ContactDetailScreen(id: Int)

    { Chip( modifier = Modifier .fillMaxSize(), icon = { Icon( Icons.Rounded.Face, contentDescription = "faceIcon", ) }, label = { Column( ) { Text(text = model.data[id].name,
 fontWeight = FontWeight.Bold) Text(text = model.data[id].phone) Text(text = model.data[id].nation) } }, colors = ChipDefaults.primaryChipColors(), onClick = { /* do anything */ }, ) }
  19. Step4. Implementing Navigation  @Composable fun ScreenNavigation_BadImpl( navController: NavHostController =

    rememberNavController() ) { NavHost( navController = navController, startDestination = "contact_list" ) { composable("contact_list") { ContactListScreenV3(navController = navController) } composable("contact_detail/{id}") { val id = it.arguments?.getString("id")!! ContactDetailScreen(id = id.toInt()) } } }
  20. Step4. Implementing Navigation  @Composable fun ContactListScreenV3(navController: NavHostController) { Scaffold(

    // just same ) { ScalingLazyColumn(state = listState) { item { // just same } items(model.data.size) { Chip( modifier = Modifier.fillMaxSize(), icon = { // just same }, label = { Text(model.data[it].name) }, colors = ChipDefaults.primaryChipColors(), onClick = { navController.navigate("contact_detail/$it") }, ) } } } }
  21. Implementing with Wear Navigation  Wear OS 
 (androidx.wear.*) Mobile

    
 (androidx.*) androidx.navigation:navigation-compose ref: https://developer.android.com/training/wearables/compose/navigation androidx.wear.compose:compose-navigation Navigation <wear>/build.gradle dependencies { def wear_compose_version = "1.0.2" implementation "androidx.wear.compose:compose-navigation:$wear_compose_version" }
  22. Step5. Replacing with Wear Navigation  @Composable fun ScreenNavigation_GoodImpl( navController:

    NavHostController = rememberSwipeDismissableNavController() ) { SwipeDismissableNavHost( navController = navController, startDestination = "contact_list" ) { composable("contact_list") { ContactListScreenV3(navController = navController) } composable("contact_detail/{id}") { val id = it.arguments?.getString("id")!! ContactDetailScreen(id = id.toInt()) } } }