Novas APIs para layouts adaptáveis no Jetpack Compose

Tempo de leitura: 4 minutes

A criação de aplicativos para telefones, dispositivos dobráveis e tablets ficou mais fácil com os novos layouts adaptativos do Material, agora em alfa!

A variedade de tamanhos de dispositivos Android disponíveis no mercado desafia as suposições usuais sobre o tamanho da tela ao criar aplicativos. Os desenvolvedores não devem presumir que a tela é plana ou que a tela em que o aplicativo foi iniciado é a mesma em que ele está sendo exibido no momento. Em vez disso, os desenvolvedores devem adaptar os aplicativos ao dispositivo em que estão sendo executados no momento para que sejam mais úteis para os usuários.

 

O Jetpack Compose simplifica o design dinâmico da interface do usuário e a reutilização de componentes, fornecendo uma alternativa moderna de desenvolvimento de interface do usuário para exibições e arquivos de layout XML. Além disso, as classes de tamanho de janela definem tamanhos de exibição específicos nos quais você pode basear decisões, como mostrar um ou dois painéis na tela. Em nosso repositório CanonicalLayouts no GitHub, você pode ver exemplos de como fazer isso hoje.

 

Layouts adaptáveis de materiais

Para um grande número de aplicativos, as regras para lidar com diferentes tamanhos de janela podem ser as mesmas. Por exemplo, em um determinado tamanho de janela, faz sentido mostrar dois painéis lado a lado ou alternar para um trilho de navegação. Mas a maioria dos aplicativos não deveria ter que definir esse comportamento individualmente. Queremos simplificar essas decisões de layout para você e, ao mesmo tempo, oferecer flexibilidade para designs e comportamentos personalizados.

Para isso, lançamos a primeira versão alfa de nossos novos layouts adaptativos do Material. Os componentes em que nos concentramos primeiro são o ListDetailPaneScaffold e o NavigationSuiteScaffold.

Layout de lista e detalhes

O ListDetailPaneScaffold é um composable que usa um composable para uma lista e um composable para detalhes e lida com toda a lógica para exibir um de cada vez ou ambos lado a lado.

Para usar o ListDetailPaneScaffold, inclua a nova dependência a seguir no arquivo build.gradle do módulo do seu aplicativo:

androidx.compose.material3:material3-adaptive

Armazene o state do scaffold com rememberListDetailPaneScaffoldState, armazene o item selecionado no momento (se houver) e chame ListDetailPaneScaffold com seus composables:

// Copyright 2023 Google LLC. SPDX-License-Identifier: Apache-2.0
val state = rememberListDetailPaneScaffoldState()
var selectedItem: MyItem? by rememberSaveable { mutableStateOf(null) }

ListDetailPaneScaffold(
  scaffoldState = state,
  listPane = {
    MyList(
      onItemClick = { id -> 
        // Set current item
        selectedItem = id 
        // Display the details pane
        state.navigateTo(ListDetailPaneScaffoldRole.Detail)
      }
    )
  },
  detailPane = {
    // Show the details pane content if selected item is available
    selectedItem?.let { item ->
      MyDetails(item)
    }
  },
)

O código controla automaticamente a exibição de um painel ou de ambos os painéis quando o aplicativo é iniciado ou quando ocorre uma alteração na configuração, como girar o dispositivo ou alternar para o modo de tela dividida.

O uso do ListDetailPaneScaffold significa que o número correto de painéis, o tamanho dos painéis e o espaçamento uniforme serão tratados automaticamente.
O uso do ListDetailPaneScaffold significa que o número correto de painéis, o tamanho dos painéis e o espaçamento uniforme serão tratados automaticamente.

Para obter mais detalhes sobre o uso do ListDetailPaneScaffold, consulte Criar um layout de detalhes de lista.

Observação: ainda não integramos o suporte à biblioteca navigation-compose, mas ele está em nosso roadmap.

 

Navigation bar ou navigation rail

O NavigationSuiteScaffold usa automaticamente a interface de usuário de navegação de nível superior mais apropriada para o seu aplicativo a fim de maximizar a acessibilidade. Com base no tamanho atual da janela do aplicativo, a UI alterna entre uma navigation bar inferior e uma navigation rail lateral.

Para usar o NavigationSuiteScaffold, inclua a seguinte nova dependência no arquivo build.gradle do seu aplicativo:

androidx.compose.material3:material3-adaptive-navigation-suite

Em seguida, crie sua interface de navegação:

// Copyright 2023 Google LLC. SPDX-License-Identifier: Apache-2.0
var selectedItem by rememberSaveable { mutableIntStateOf(0) }
val navItems = listOf("Songs", "Artists", "Playlists")
val navSuiteType = 
  NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(currentWindowAdaptiveInfo())

NavigationSuiteScaffold(
  navigationSuiteItems = {
    navItems.forEachIndexed { index, navItem ->
      item(
        icon = { Icon(Icons.Filled.Favorite, contentDescription = navItem) },
        label = { Text(navItem) },
        selected = selectedItem == index,
        onClick = { selectedItem = index }
      )
    }
  }
) {
  // Screen content.
  Text(
    modifier = Modifier.padding(16.dp),
    text = "Current NavigationSuiteType: $navSuiteType"
  )
}

Se estiver usando um Scaffold padrão para exibir apenas uma barra de navegação inferior e conteúdo, poderá substituir completamente o scaffold pelo NavigationSuiteScaffold. Se estiver usando um scaffold para exibir outros elementos, como uma barra de aplicativos superior, um botão de ação flutuante ou uma planilha inferior, poderá mover o scaffold para o lambda de conteúdo do NavigationSuiteScaffold.

 

O que vem a seguir?

Esta versão dos layouts adaptativos de material é uma versão alfa, portanto, há muito mais a ser feito. Estamos aprimorando ativamente os componentes e adicionando novos. Também estamos trabalhando para separar os componentes adaptativos mais gerais que não são específicos do Material da biblioteca material3-adaptive.

Enquanto isso, gostaríamos de receber sua opinião. Adicione layouts adaptáveis aos seus aplicativos com o ListDetailPaneScaffold e o NavigationSuiteScaffold e diga-nos o que achou, registrando um bug ou uma solicitação de recurso.