Lidar com a conectividade da Internet no Flutter com Riverpod

Tempo de leitura: 4 minutes

Obter dados da API Rest, fazer uma solicitação HTTP e exibir os dados na tela é a tarefa mais básica e crucial em um aplicativo. Esse processo acontece conforme o usuário interage com a aplicação e é necessária uma conexão constante com a internet para recuperar os dados da API.

Se não houver conexão com a Internet, é provável que o aplicativo continue mostrando o símbolo de carregamento e o usuário pense que o aplicativo está quebrado ou que há algum bug no aplicativo.

Os desenvolvedores de aplicativos devem informar o usuário sobre a conectividade com a Internet para ajudá-lo.

Aqui discutiremos como verificar a conectividade com a Internet de um aplicativo integrado ao Flutter.

 

O que vamos construir?

Para isso, construiremos um aplicativo básico que mostra na tela o status da conexão com a internet e uma lanchonete sobre o mesmo. Isso ouvirá o status da conexão com a Internet para obtermos atualizações de rede em tempo real.

Vamos começar

Vamos começar criando um aplicativo Flutter que possui um Texto no Centro que diz Status de Conectividade e está Conectado ao Texto da Internet. Usei um fundo escuro, mas você pode usar a cor de fundo que desejar.

Adicionando pacotes de pub

Para esta aplicação, usaremos dois pacotes.

  • conectividade_plus: um plug-in que permite ao aplicativo Flutter descobrir a conectividade de rede e configurar o aplicativo de acordo.
  • flutter_riverpod: Uma biblioteca de gerenciamento de estado que ajuda a gerenciar o estado do aplicativo e fornecer as dependências.

vamos começar adicionando esses dois pacotes à nossa aplicação. Para fazer isso, adicione os pacotes ao arquivo pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  connectivity_plus: ^5.0.0
  flutter_riverpod: ^2.4.3

Nota: Não se esqueça de executar flutter pub get após adicionar dependências

 

Notificador de status de conectividade

vamos criar um arquivo Connectivity status Notifier que terá todo o código para notificar o aplicativo sobre a conexão de rede. Criaremos uma classe com o mesmo nome que se estende até StateNotifier.

Um StateNotifier é uma solução simples para controlar o estado de maneira imutável e é uma solução recomendada para gerenciar o estado ao usar Provider e Riverpod.

Ao estender para StateNotifier, precisamos fornecer um Type para StateNotifier. Vamos criar um enum que terá o status de conectividade do qual rastrearemos.

enum ConnectivityStatus { NotDetermined, isConnected, isDisonnected }

class ConnectivityStatusNotifier extends StateNotifier<ConnectivityStatus> {}

Ouça as alterações do ConnectivityResult

Adicione o seguinte código ao ConnectivityStatusNotifier

ConnectivityStatus? lastResult;
  ConnectivityStatus? newState;

  ConnectivityStatusNotifier() : super(ConnectivityStatus.isConnected) {
    if (state == ConnectivityStatus.isConnected) {
      lastResult = ConnectivityStatus.isConnected;
    } else {
      lastResult = ConnectivityStatus.isDisonnected;
    }
    lastResult = ConnectivityStatus.NotDetermined;
    Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
      switch (result) {
        case ConnectivityResult.mobile:
        case ConnectivityResult.wifi:
          newState = ConnectivityStatus.isConnected;
          break;
        case ConnectivityResult.none:
          newState = ConnectivityStatus.isDisonnected;
          break;
      }
      if (newState != lastResult) {
        state = newState!;
        lastResult = newState;
      }
    });
  }

Primeiro, criamos duas variáveis anuláveis do tipo ConnectivityStatus denominadas lastState e newState. Quando o status de conectividade mudar, atualizaremos essas variáveis.

Usando o super construtor para ouvir as mudanças que ocorrem no connectivity status do dispositivo. O Switch nos permite verificar o status da conectividade e então atualizar o valor para a variável newState que criamos no topo.

State Notifier Provider

// Variável global final que irá expor o estado.
// Deve estar fora da classe.

final connectivityStatusProviders = StateNotifierProvider((ref) {
  return ConnectivityStatusNotifier();
});

StateNotifierProvider é um provedor usado para ouvir e expor um StateNotifier e é uma solução recomendada pela Riverpods para gerenciar o estado que pode mudar em reação à interação dos usuários.

Este conectividadeStatusProvider nos ajudará a ouvir o estado exposto por ConnectivityStateNotifier.

 

UI

Agora vamos criar uma UI onde possamos atualizar o usuário sobre as mudanças de conectividade que ocorrem. Aqui usei ConsumerWidget para obter o provedor notificador no widget.

class HomeScreen extends ConsumerWidget {
  const HomeScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    var connectivityStatusProvider = ref.watch(connectivityStatusProviders);
   
    return Scaffold(
        backgroundColor: Colors.black54,
        appBar: AppBar(
          title: const Text(
            'Network Connectivity',
            style: TextStyle(
              color: Colors.white,
              fontSize: 20.0,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text(
                'Connectivity Status',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 20.0,
                  fontWeight: FontWeight.bold,
                ),
              ),
              Text(
                connectivityStatusProvider == ConnectivityStatus.isConnected
                    ? 'Is Connected to Internet'
                    : 'Is Disconnected from Internet',
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 20.0,
                ),
              )
            ],
          ),
        ));
  }
}

 

Mostrar snackbar

Agora que obtivemos o status da conexão vamos mostrar uma snackbar que irá atualizar o usuário.

WidgetsBinding.instance.addPostFrameCallback((_) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text(
            connectivityStatusProvider == ConnectivityStatus.isConnected
                ? 'Is Connected to Internet'
                : 'Is Disconnected from Internet',
            style: const TextStyle(
              color: Colors.white,
              fontSize: 20.0,
            ),
          ),
          backgroundColor: connectivityStatusProvider ==
                  ConnectivityStatus.isConnected
              ? Colors.green
              : Colors.red,
        ),
      );
    });

 

 

Atualizando o main.dart.

Sempre que usamos RiverPod, envolvemos nosso aplicativo com ProviderScope para que os widgets sejam capazes de ler o Provedor que criamos.

// main.dart

void main() {
  runApp(ProviderScope(child: NetworkConnectivity()));
}

class NetworkConnectivity extends StatelessWidget {
  const NetworkConnectivity({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

É isso. Criamos com sucesso um aplicativo que atualiza os usuários quando há uma alteração no status de conectividade do dispositivo. Execute o aplicativo no Android, iOS e tente desconectar e reconectar o dispositivo à internet.

Aqui está o código completo do projeto no Github