EN VI

Flutter/Dart: A simple data stream required?

2024-03-12 19:00:06
How to Flutter/Dart: A simple data stream required

I have spent over an hour on this but I can't find a single example of what I need anywhere. Any good examples of streams I can find use timers.

So I have a basic class that creates objects:

class CharacterModel {
  final CharacterModelType type;
  late final String imagePath;
  final bool isModel;
  int currentHealth;
  int startingHealth;

  CharacterModel({
    required this.type,
    required this.imagePath,
    required this.isModel,
    required this.startingHealth,
    required this.currentHealth,
  });
}

This is used to create tiles on a game board, the tiles are made from a class called Square, which builds like this:

Widget build(BuildContext context) {
String selectedImage;
selectedImage = tile!.imagePath;

if (isSelected) {
  const selectedImage = './lib/images/dungeon_tile_1.png';
}

return GestureDetector(
  onDoubleTap: onDoubleTap,
  onTap: onTap,
  child: Stack(
    children: [
      Container(
        child: tile != null ? Image.asset(selectedImage) : null,
      ),
      Align(
        alignment: Alignment.bottomRight,
        child: tile!.currentHealth > 0 ? Padding(
          padding: EdgeInsets.all(10),
          child: Text(
            tile!.currentHealth.toString(),
            style: TextStyle(
              color: Colors.red,
              fontWeight: FontWeight.bold,
              fontSize: 20,
            ),
          ),
        ) : null,
      ),
    ],
  ),
);

And the result is that you get a grid populated by these images of characters with their current health overlayed on top of the images.

This is all fine so far, but now I want to add functionality where double-tapping on one of these images causes the current health to change, and for the text on the image to update instantly.

For this, from what I am reading, I believe I need to use a stream?

Other examples I can see on these forums seem to indicate that if I want something visual to update based on the streamed data, then I need to use a bloc as well, but none of them have included how to initiate a bloc either.

I guess I am at the starting point here where I don't even know what the best approach is. Is the stream/bloc model actually what I need?

This has been my attempt so far:

Stream<int> _health();

damageModel() {
  print("no idea what to even do here");
}

Widget build(BuildContext context) {
return Scaffold(
  body: StreamBuilder(
    stream: _health(),
    builder: (context, snapshot) {
      return GridView.builder(
        itemCount: 8 * 8,
        physics: const NeverScrollableScrollPhysics(),
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 8),
        itemBuilder: (context, index) {
          int row = index ~/ 8;
          int col = index % 8;
          bool isSelected = selectedRow == row && selectedColumn == col;
          if (!snapshot.hasData) {
            return CircularProgressIndicator();
          } else {
            return Square(
              tile: board[row][col],
              isSelected: isSelected,
              currentHealth: snapshot.data!,
              onTap: () => modelSelected(row, col),
              onDoubleTap: () => damageModel(),
            );
          }
        },
      );
    }
  ),
);
}

Solution:

I don't see why you would need a stream at all. a simple

onDoubleTap: () => setState(() => board[row][col].currentHealth -= 1),

might be all you need

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login