Pular para o conteúdo
charmotion

Rive e Lottie no FlutterFlow: widgets e limites

Por equipe Charmotion · Atualizado em

Ilustração de capa do guia de frameworks e no-code: Rive e Lottie no FlutterFlow: widgets e limites, com personagens de demonstração do Charmotion

O FlutterFlow tem um widget RiveAnimation nativo que reproduz um .riv a partir de um asset ou URL, com seletores de artboard e de animação e uma ação Rive Animation para iniciar a reprodução. A documentação não aborda inputs de state machine nem data binding, então trocar o humor de um personagem ou disparar reações exige um widget personalizado criado com o pacote Flutter rive.

Principais pontos

  • O widget RiveAnimation nativo reproduz timelines; o controle da state machine não é documentado.
  • Um widget personalizado com o pacote rive expõe um parâmetro mood e triggers.
  • O widget LottieAnimation do FlutterFlow atende clipes lineares, com ações de iniciar e pausar.
  • Inicialize o runtime do Rive uma vez na inicialização do app, antes de carregar qualquer arquivo.
  • Teste widgets personalizados em um build real; as prévias podem não renderizar código personalizado da mesma forma.

O FlutterFlow tem suporte nativo ao Rive?

Sim, para reprodução. O widget RiveAnimation do FlutterFlow fica em Base Elements, no painel de widgets. Você escolhe uma origem (um asset enviado ou uma URL de rede), seleciona um artboard em uma lista suspensa, escolhe as animações a reproduzir e deixa o Auto Animate ativado para iniciar a reprodução automaticamente. Uma ação Rive Animation separada pode iniciar a reprodução a partir de um botão ou de um evento da página.

NecessidadeRiveAnimation nativoWidget personalizado
Reproduzir uma timeline ou colocá-la em loopYesYes
Definir um número da state machine, disparar um triggerNão documentadoYes
View model de Data BindingNão documentadoYes
Sem códigoYesNo

Por isso, o widget nativo é uma boa escolha para uma ilustração em loop ou uma intro única. Um mascote que deve parecer pensativo enquanto uma consulta roda e comemorar quando ela dá certo precisa que a state machine seja controlada pelo estado do app, e é aí que entra o widget personalizado.

Como adiciono um .riv como asset ou origem de rede?

No widget nativo:

  1. Arraste o RiveAnimation de Base Elements para a página.
  2. No painel de propriedades, defina a origem como Asset e envie o .riv, ou como Network e cole uma URL HTTPS.
  3. Escolha o artboard e as animações a reproduzir.
  4. Deixe o Auto Animate ativado para loops, ou desative e inicie a reprodução com a ação Rive Animation.
  5. Defina largura e altura fixas para o widget, para o layout não pular enquanto o arquivo carrega.

Assets vão dentro do app e funcionam offline. Arquivos de rede deixam o binário menor e podem ser atualizados sem republicar, mas precisam de conexão no primeiro carregamento. Para um personagem que aparece na abertura ou no onboarding, prefira um asset.

A mesma escolha vale para um widget personalizado: os assets enviados vão para o pacote de assets do app e podem ser carregados pelo caminho, e os arquivos de rede podem ser carregados pela URL.

O widget nativo consegue controlar inputs da state machine?

Não, segundo a documentação do FlutterFlow. A página do RiveAnimation descreve a origem, o artboard, a seleção de animações e o Auto Animate, além da ação que inicia a reprodução. Ela não menciona state machines, inputs nem view models. Discussões da comunidade sobre como controlar uma state machine chegam à mesma conclusão e usam um widget personalizado.

Na prática: um arquivo construído em torno de uma state machine reproduz só o estado padrão no widget nativo, ou nada de útil, se depender de inputs para escolher um loop. Escolher timelines pelo nome pode funcionar em arquivos simples, mas você perde as transições criadas pelo designer e precisa sequenciar a reprodução por conta própria.

Diagrama de uma state machine do Rive: um estado de entrada, dez estados de loop escolhidos por um número mood e estados de reação única por trigger que voltam ao loop atual
Como um .riv do Charmotion é conectado: o número mood escolhe um loop, e os triggers tocam reações únicas a partir de qualquer estado.

Os arquivos do Charmotion mostram bem a diferença. Cada conjunto é um único .riv com 17 animações geradas a partir do seu personagem ou logo em poucos minutos, ligadas a uma state machine: CharacterStateMachine com um input numérico mood (0 idle, 1 happy, 2 wave, 3 thinking, 4 sad, 5 loading, 6 listening, 7 talking, 8 sleeping, 9 attention) e os triggers success, error, yes, no, enter e exit, além de um view model Character para Data Binding. Para usar esses humores no FlutterFlow, crie o widget personalizado abaixo.

Como controlo o número do mood com um widget personalizado?

Em Custom Code, adicione o pacote rive como dependência (confira no pub.dev a versão atual do pacote rive) e crie um widget personalizado com um parâmetro inteiro mood. O widget carrega o arquivo uma vez, localiza os inputs e os atualiza sempre que o FlutterFlow passa um novo valor:

class RiveMascot extends StatefulWidget {
  const RiveMascot({super.key, this.width, this.height, required this.mood});
  final double? width;
  final double? height;
  final int mood;
  @override
  State<RiveMascot> createState() => _RiveMascotState();
}

class _RiveMascotState extends State<RiveMascot> {
  File? file;
  RiveWidgetController? controller;
  NumberInput? mood;

  @override
  void initState() {
    super.initState();
    _load();
  }

  Future<void> _load() async {
    final f = await File.asset('assets/rive_animations/character.riv',
        riveFactory: Factory.rive);
    if (f == null || !mounted) return;
    final c = RiveWidgetController(f,
        stateMachineSelector: StateMachineSelector.byName('CharacterStateMachine'));
    setState(() {
      file = f;
      controller = c;
      mood = c.stateMachine.number('mood')?..value = widget.mood.toDouble();
    });
  }

  @override
  void didUpdateWidget(RiveMascot old) {
    super.didUpdateWidget(old);
    if (old.mood != widget.mood) mood?.value = widget.mood.toDouble();
  }

  @override
  void dispose() {
    mood?.dispose();
    controller?.dispose();
    file?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final c = controller;
    return SizedBox(width: widget.width, height: widget.height,
        child: c == null ? null : RiveWidget(controller: c, fit: Fit.contain));
  }
}

Confira o caminho que o FlutterFlow atribui aos arquivos enviados no seu projeto e execute await RiveNative.init(); uma vez antes de carregar qualquer arquivo, por exemplo em uma ação personalizada adicionada ao main.dart. Vincule mood a uma variável de estado da página ou do app: ao mudar essa variável, o loop muda.

Como disparo as reações de sucesso e erro?

Triggers são eventos, então não se encaixam bem em um parâmetro de widget. Um padrão simples e confiável é usar um parâmetro contador por trigger: quando o inteiro aumenta, o widget dispara o trigger.

// extra parameter: final int successCount;
TriggerInput? success;   // in _load(): success = c.stateMachine.trigger('success');

@override
void didUpdateWidget(RiveMascot old) {
  super.didUpdateWidget(old);
  if (old.mood != widget.mood) mood?.value = widget.mood.toDouble();
  if (widget.successCount > old.successCount) success?.fire();
}

No action flow, depois que a chamada ao backend der certo, incremente em um a variável de estado successCount. Adicione um errorCount da mesma forma. Descarte cada input em dispose().

Essas chamadas usam a API legada de inputs do Rive, que o Rive descontinuou em favor do Data Binding, mas que o runtime Flutter ainda suporta para arquivos existentes. Um arquivo com view models também pode ser controlado pela API de Data Binding do Flutter com CharacterViewModelMachine; a estrutura do widget continua a mesma. A seção de Flutter do guia de runtimes do Rive mostra a configuração completa do runtime.

Quando devo usar o widget LottieAnimation?

Use-o quando a animação tocar sempre do mesmo jeito. O widget LottieAnimation do FlutterFlow exibe arquivos Lottie a partir de assets enviados ou de uma URL, e uma ação Lottie Animation pode iniciá-lo e pausá-lo. Nenhum código personalizado é necessário.

  • Bons usos: um spinner de carregamento, um check de sucesso depois do checkout, uma ilustração de onboarding, um loop de estado vazio.
  • Usos ruins: um personagem que muda de humor conforme o estado do app ou reage a vários eventos diferentes. Com Lottie, você teria que trocar arquivos ou segmentos e sincronizar as transições por conta própria.
success: um trigger que toca uma vez e depois volta ao humor atual.

Muitos apps usam os dois: Lottie para pequenos momentos decorativos e um personagem Rive, controlado por um widget personalizado, para os momentos que pedem personalidade. Se você só precisa de um clipe fixo, um vídeo mudo em loop também funciona e não exige nenhum runtime de animação.

Como controlar uma state machine do Rive no FlutterFlow

  1. Adicione o pacote. Em Custom Code, adicione o pacote rive como dependência.
  2. Envie o arquivo. Envie o .riv como asset e anote o caminho dele.
  3. Crie o widget. Crie um widget personalizado com um parâmetro inteiro mood que carregue o arquivo com CharacterStateMachine.
  4. Inicialize o runtime. Chame RiveNative.init() uma vez na inicialização, antes de carregar qualquer arquivo.
  5. Vincule o estado. Vincule mood a uma variável de estado e atualize-a nos action flows.
  6. Adicione triggers. Adicione parâmetros contadores que disparem success e error ao serem incrementados.

Perguntas frequentes

Dá para usar uma state machine do Rive no FlutterFlow sem código?

Não, segundo a documentação do FlutterFlow. O widget nativo RiveAnimation documenta a seleção de artboard e de animação, além de uma ação de reprodução, mas nenhum input de state machine nem view models. Para mudar um humor ou disparar triggers a partir da lógica do seu app, envolva o pacote Flutter rive em um widget personalizado.

Por que meu arquivo Rive só mostra o primeiro estado no FlutterFlow?

O widget nativo reproduz animações selecionadas, não uma state machine controlada por inputs. Um arquivo cujos loops são escolhidos por um input numérico fica parado no estado padrão, porque nada define esse número. Um widget personalizado que define o input mood ou a propriedade do view model resolve isso.

Widgets Rive personalizados funcionam nos builds web do FlutterFlow?

O pacote rive é compatível com Flutter web, além de iOS e Android, então o mesmo widget personalizado pode rodar em um build web. Teste em um build publicado de verdade, já que código personalizado pode não ser renderizado em todos os modos de prévia do FlutterFlow, e verifique o tempo de carregamento do runtime na web.

Respostas rápidas deste guia

Fontes

Guias relacionados