
O Material Design 2.0 introduziu vários novos conceitos. Uma delas é a atenção especial às formas geométricas dos elementos da interface. E existe uma maneira fácil de criar belas formas personalizadas. É chamado de MaterialShapeDrawable. Vamos ver como é útil e fácil de usar.
Existem várias maneiras de adicionar elementos gráficos à tela de um aplicativo Android. O mais simples é importar bitmaps no formato webp ou png. Outra opção é usar o VectorDrawable, que permite esticar a imagem para o tamanho necessário. Outra maneira de adicionar gráficos à tela é usar o ShapeDrawable. Esta última é a maneira mais fácil de adicionar um plano de fundo simples ou até criar um ícone. As imagens criadas com o ShapeDrawable são independentes da densidade de pixels na tela. Eles podem ser descritos em um arquivo xml, fazer parte de outro recurso gráfico (por exemplo, StateListDrawable) e estão presentes no Android SDK, iniciando na API v.1.
Para alterar a aparência de uma figura, podemos alterar várias propriedades ShapeDrawable: o nome da figura, a cor de preenchimento (ou gradiente) e a cor da borda da figura. Para retângulos, você também pode definir o raio dos cantos. Usando essas propriedades, você pode criar gráficos que serão usados como imagens individuais na tela, divisores, planos de fundo de botões ou para qualquer outra finalidade. Se o aplicativo usar a API v.21 + e ShapeDrawable como plano de fundo para elementos com elevação, a sombra abaixo desses elementos também terá a forma correta:

O ShapeDrawable é uma ferramenta útil que quase sempre faz seu trabalho bem, mas com o advento do Material Design 2.0, os desenvolvedores precisam de algo mais flexível. O novo sistema de design incentiva o uso de diferentes formas para enfatizar seu significado, condição e estilo de aplicação individual. Eu escrevi acima que existem várias maneiras de fazer o desejado, mas a mais simples delas não é mais relevante. Isso significa que precisamos começar a usar gráficos vetoriais e, assim, perder a capacidade de "libertar" criar sombras para elementos de interface com elevação? Ou vale a pena voltar a usar imagens raster e criar recursos gráficos para seis possíveis densidades de pixels na tela? Felizmente, com o advento do Material Design 2.0, uma biblioteca de componentes completamente nova apareceu.
Essa biblioteca foi criada para unificar a aparência e o comportamento dos componentes da interface do usuário do Material Design em todas as versões do Android e outras plataformas (existem versões dessa biblioteca para iOS, Web e Flutter). A biblioteca de componentes implementa muitos recursos para o novo Design de materiais. Por exemplo, inclui o componente BottomAppBar com o comportamento esperado. Entre outros componentes e utilitários, há a classe MaterialShapeDrawable. Na minha opinião, essa é uma ferramenta necessária para resolver as tarefas que o novo sistema de design apresenta para os desenvolvedores.
Embora o MaterialShapeDrawable ainda seja considerado experimental na versão 1.0.0 da biblioteca, ele pode ser usado para criar efeitos interessantes no aplicativo. Na classe MaterialShapeDrawable, você pode descrever uma forma especificando a aparência de seus lados e cada um de seus ângulos. Essas propriedades especificadas podem ser controladas por um interpolador, o que lhes permite animar.
Para criar seu próprio MaterialShapeDrawable, você pode usar o construtor para o qual precisa passar um objeto do tipo ShapePathModel nos parâmetros. Ele armazena informações sobre cada lado e cada canto da figura nas classes EdgeTreatment e CornerTreatment, respectivamente (sempre existem exatamente quatro lados e ângulos, mas isso não interfere na descrição de quase qualquer figura com a ajuda deles). Você pode especificar as descrições pessoalmente para cada lado e canto, ou defini-las imediatamente para a figura inteira, chamando um método.
Já existem várias descrições prontas para uso (tratamento) dos lados e ângulos da biblioteca, que incluem a maioria das inovações relacionadas ao formato dos componentes introduzidos no Material Design 2.0. Já está presente: RoundedCornerTreatment - para cantos arredondados, CutCornerTreatment - para cantos cortados, TriangleEdgeTreatment - para cortar ou adicionar um triângulo ao lado. Para demonstrar seu trabalho, há um exemplo simples:
val shapePathModel = ShapePathModel().apply { setAllCorners(CutCornerTreatment(dip(5).toFloat())) setAllEdges(TriangleEdgeTreatment(dip(5).toFloat(), true)) } val backgroundDrawable = MaterialShapeDrawable(shapePathModel).apply { setTint(ContextCompat.getColor(this@MainActivity, R.color.colorPrimary)) paintStyle = Paint.Style.FILL } textView.background = backgroundDrawable
Ficará assim:

Obviamente, você pode simplesmente criar suas próprias descrições de rostos e ângulos. A forma é sempre definida para o elemento superior esquerdo, e o Drawable realiza as operações de rotação / reflexão para obter a forma final. Há um pequeno exemplo para demonstrar isso:
class CutoutCornersTreatment(val size: Float) : CornerTreatment() { override fun getCornerPath(angle: Float, interpolation: Float, shapePath: ShapePath) { shapePath.reset(0.0f, size * interpolation) shapePath.lineTo(size * interpolation, size * interpolation) shapePath.lineTo(size * interpolation, 0f) } } class CurvedEdgeTreatment(val size: Float) : EdgeTreatment() { override fun getEdgePath(length: Float, interpolation: Float, shapePath: ShapePath) { shapePath.quadToPoint(length / 2f, size * interpolation, length, 0f) } }
Se este MaterialShapeDrawable for usado como plano de fundo, o resultado será o seguinte:

O pacote bottomappbar da nova Biblioteca de componentes de material possui um BottomAppBarTopEdgeTreatment. Ele descreve o recorte no BottomAppBar para o botão FloatingActionButton. Seu lado superior pode ser animado, dependendo da posição e tamanho do botão. Aconselho que você leia o código dessas classes para ver com seus próprios olhos que o MaterialShapeDrawable é muito flexível de usar e quase tudo pode ser feito com ele.
Se falamos sobre o ShapeDrawable usual, há outro detalhe que vale a pena mencionar - a capacidade de projetar uma sombra da forma correspondente ao contorno. Como agora você pode criar contornos de formas muito incomuns usando MaterialShapeDrawable, seria uma decepção não trazer a forma da sombra para a forma da imagem, especialmente quando essas sombras podem ser vistas em todos os lugares no Matarial Design 2.0. MaterialShapeDrawable também calcula a aparência da sombra. Usando a propriedade shadowEnabled, você pode ativar a sombra, que seguirá exatamente o contorno da figura, também é possível determinar o raio, a elevação e a cor da sombra. Parece bom demais para ser verdade? Infelizmente sim. Se você usar a sombra de MaterialShapeDrawable, obtém uma sombra normal (desenhada pelo método setShadowLayer () da classe Paint, criada para desenhar sombras no texto), mas cortada nas bordas do componente de interface do usuário no qual o resultado é exibido:

Lembre-se de que o MaterialShapeDrawable ainda é considerado experimental, como sua API, e pode mudar no futuro. Também é importante notar que o código para a nova biblioteca de Componentes de materiais está aberto; portanto, é muito bem-vindo a criação de tickets em um rastreador de bugs ou até mesmo solicitações pull com a correção de problemas conhecidos. De fato, quando você lê essas linhas, a API já é um pouco diferente na ramificação principal da biblioteca (por exemplo, ShapeAppearanceModel será usado em vez de ShapePathModel), o que indica trabalho ativo. Um dos recursos promissores no próximo release pode ser a capacidade de determinar os lados / ângulos padrão para todo o tema do aplicativo. Você pode aprender mais sobre isso na documentação oficial ou nas fontes da biblioteca.
Do tradutor:
É legal que existem ferramentas que adicionam novos recursos ao ShapeDrawable usual e ajudam a criar gráficos não mais simples. Isso permite que o desenvolvedor não convide o designer para todas as pequenas coisas, mas resolva o problema ele mesmo, e requer significativamente menos tempo. Estamos aguardando as próximas versões da biblioteca Componentes de materiais para tentar, na prática, novas maneiras de resolver problemas existentes.