Search code examples
flutterlistlistview

Return value from all list elements


Because i have no mock-data currently available, i created my own one and im currently struggling to get specific values out it.

The idea is to have a list of devices, which i already instantiated, from where i get the data to display it in a ListView. That works already but i didnt find a solution how to iterate through this list to get name of device 1, name of device 2 and so on.

Currently i get a ListView returned with 2 Elements, but it returns only the value "one" - so the program doesnt iterate through the list. Because the other Element has the name "two".

Here's a screenshot of the current status: enter image description here

Has anyone an idea how to fix it?

My Code:

Device-Class to create a specific device:

import 'package:flutter/material.dart';

class Device {
  Device({this.name,});

  String? name;
}

Mock-API to create a list of devices and return it's name:

import 'package:myProject/stack/device.dart';
import 'package:flutter/material.dart';

class ApiDummyData {
  static List<Device> devicesList = [Device(name: "one"), Device(name: "two")];

  int counter = -1;

  dynamic getDeviceName() {
    counter++;
    return devicesList.elementAt(counter).name;
  }
}

My own created ListViewElement:

import 'package:myProject/api/api_dummy_data.dart';
import 'package:myProject/stack/device.dart';
import 'package:flutter/material.dart';

class MyListViewElement extends StatelessWidget {
  MyListViewElement({
    super.key,
  });

  final getDeviceNameInstance = ApiDummyData();

  @override
  Widget build(BuildContext context) {
    return Container(
        decoration: **...**,
        child: Padding(
          **...**,
          child: Row(
            children: [
              Icon(
                **...**
              ),
              **Text(getDeviceNameInstance.getDeviceName(),**
                  style: TextStyle(color: Colors.white, fontSize: 25))
            ],
          ),
        ));
  }
}

Using the data in the specific view:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
body: ListView(
          children: [
            for (int i = 0; i < ApiDummyData.devicesList.length; i++)
              buildChild(i)
          ],
        ),
      );
    }

buildChild(int i) {
    return InkWell(
      onTap: () {
        print("success");
      },
      child: MyListViewElement()),
    );
  }

I already tried to implement a counter or a for-loop but didnt fix the problem. :( I also tried to use the i counter from the view-file to put it in the child: MyListViewElement(i)), but there occured so many errors..


Solution

  • That's because every time you create a MyListViewElement it creates its own ApiDummyData() object, So every time you create an object counter will be 0, hence you only see the name of the first device.

    So, for solving this problem you have 2 options.

    Make that counter static

    which make all instantiated objects share the same value, and the object No N will have counter equal to N-1.

    But this is a fast solution but still unprofessional.

    Pass that counter to ApiDummyData

    And make sure to return the name of the device corresponding to that counter! got it.

    class ApiDummyData {
      static List<Device> devicesList = [Device(name: "one"), Device(name: "two")];
    
      int counter;
      ApiDummyData({required this.counter})
    
      get deviceName=>devicesList.elementAt(counter).name;
      
    }
    

    BTW, since you have provided a code mock (not the real one), we can't help more because the data layer eg: ApiDummyData should send that list to some other layer to manage its presentation (i mean, you shouldn't call data layer many times to get device name, just catch that list and manage it your own).