Savandhi Goonasekera
Savandhi Goonasekera

Reputation: 21

flutter text editing controller listview.builder

I want the page to display a list of social media apps where the user can input their usernames/ details. I want to be able to extract this input data along with the app name and logo (preferably as a JSON file) to be able to create them into buttons which lead to the respective app and profile.

For this I've created a list of List Tiles using the listview.builder (from a separate list which has the list of apps and logo that I want to include) and have added a TextField to each List Tile using the subtitle function.

Please would you be able to help me add the TextEditing Controller to each item of the list and extract a file with the text input, appname and logo.

Please note: the applist is a list which contains the appname, hint text of the TextField and image of the logo.

import 'package:flutter/material.dart';
import 'package:applist/apps.dart';

class AppList extends StatefulWidget {
  const AppList({Key? key}) : super(key: key);

  @override
  _AppListState createState() => _AppListState();
}

class _AppListState extends State<AppList> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My list of apps'),
      ),
      body: Padding(
        padding: EdgeInsets.all(20.0),
        child: Column(
          children: [
            Expanded(
                child: ListView.builder(
                    itemCount: apps.length,
                    itemBuilder: (BuildContext context, int index) {
                      return ListTile(
                        title: Text(apps[index].appname),
                        leading: SizedBox(
                          height: 50,
                          width: 50,
                          child: Image.asset(apps[index].image),
                        ),
                        subtitle: TextField(
                          decoration:
                              InputDecoration(hintText: (apps[index].hint)),
                        ),
                      );
                    }))
          ],
        ),
      ),
    );
  }
}

Upvotes: 2

Views: 4491

Answers (3)

Nikolay
Nikolay

Reputation: 773

If you want to use unique controllers for text fields. You should use a model that will have a controller and other data. Example of a model using "freezed"

import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'controller_model.freezed.dart';

@freezed
class ControllerModel with _$ControllerModel {
  const factory ControllerModel({
    required String name,
    required TextEditingController controller,
  }) = _ControllerModel;
}

Upvotes: 0

Ibrahim Ali
Ibrahim Ali

Reputation: 2503

Make each app have a unique id (if only the app name isn't unique).

Create a map of TextEditingController

Map<String, TextEditingController> _textControllers = new Map();

Add a new TextEditingController for each of your apps with its unique name or id as the key

apps.forEach((app) => textControllers[app.id] = new TextEditingController());

Finally you can use it in your ListViewBuilder like so..

ListView.builder(
          itemCount: apps.length,
          itemBuilder: (context, index) => TextFormField(
            controller: _textControllers[apps[index].id],
          ),
        )

Upvotes: 0

Hosam Hasan
Hosam Hasan

Reputation: 692

1- you need to define TextEditingConrtoller field variable:

late  TextEditingController textEditingController ; 

2- initialize the field variable in initState

  @override
  void initState(){
    super.initState();
    textEditingController = TextEditingController();
  }

3- then Initialize your TextField the th e controller

TextField(
   controller:textEditingController ,
)
  • your final code should be like this
import 'package:flutter/material.dart';
import 'package:applist/apps.dart';

class AppList extends StatefulWidget {
  const AppList({Key? key}) : super(key: key);

  @override
  _AppListState createState() => _AppListState();
}

class _AppListState extends State<AppList> {
late  TextEditingController textEditingController ;   // <--
@override
  void initState() {
    super.initState();
    textEditingController = TextEditingController(); // <--
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My list of apps'),
      ),
      body: Padding(
        padding: EdgeInsets.all(20.0),
        child: Column(
          children: [
            Expanded(
                child: ListView.builder(
                    itemCount: apps.length,
                    itemBuilder: (BuildContext context, int index) {
                      return ListTile(
                        title: Text(apps[index].appname),
                        leading: SizedBox(
                          height: 50,
                          width: 50,
                          child: Image.asset(apps[index].image),
                        ),
                        subtitle: TextField(
                          controller:textEditingController , // <--
                          decoration:
                              InputDecoration(hintText: (apps[index].hint)),
                        ),
                      );
                    }))
          ],
        ),
      ),
    );
  }
}

Upvotes: 2

Related Questions