Home > Mobile >  How to Pass 3 values (subtitle& IconButton, link) to each 'Topics' listed in Listview Buil
How to Pass 3 values (subtitle& IconButton, link) to each 'Topics' listed in Listview Buil

Time:03-25

[Target UI item is as marked in circle circle in the picture My 3 doubts are: ->How to PASS in line 16 and line 23, "subtitle" to all 6 Topics in Listview, as "title" is already getting passed.I tried but i was getting error.. ->had no clue how to present icon buttons under each of 6 Topics that was in Listview
->how to PASS a separate 6 'external website links' that should open when the respective icon button is pressed enter image description here

code to be modified is in this below location

https://github.com/sandeepnarula999/FlutterProjects/blob/main/ListViewUnderExpansionTile

CodePudding user response:

Your class Entry doesn't have any subtitle property, what I suggest is add that property being optional string as final String? subtitle, then change constructor to only call what you need as in root you don't need subtitle you don't call it, then change your call for subtitle according to your subtitle property.

I've used your code and it's working with what you want, check this:

import 'package:flutter/material.dart';

bool swapFailureTrigger = false;
// If TRUE, scrolling works well when grabbing an open expansion tile list
// If FALSE, scrolling only works if we grab a parent list OUTSIDE the items of the open expansion tile

class EntryItem extends StatelessWidget {
  const EntryItem(this.entry);

  final Entry entry;

  Widget _buildTiles(Entry root) {
    if (root.children.isEmpty) {
      return ListTile(
        title: Text(root.title),
        subtitle: root.subtitle == null ? null : Text(root.subtitle!),
      );
    }

    var kids = root.children.map((child) => _buildTiles(child)).toList();

    return ExpansionTile(
      key: PageStorageKey<Entry>(root),
      title: Text(root.title),
      subtitle: root.subtitle == null ? null : Text(root.subtitle!),

      // <<---------- PROBLEM IS HERE if you test with the ListView.builder() version ---------->>
      children: swapFailureTrigger
          ? root.children.map(_buildTiles).toList()
          : <Widget>[
              ListView.builder(
                shrinkWrap: true,
                physics: ClampingScrollPhysics(),
                // helps scroll all 6 items in list *not working*
                key: PageStorageKey<Entry>(root),
                itemCount: kids.length,
                itemBuilder: (context, index) {
                  return kids[index];
                },
                //shrinkWrap: true,
                //physics: ClampingScrollPhysics(), // for List View to scroll
              )
            ],
      //  <<--------------------------------------------------------------------------------->>
    );
  }

  @override
  Widget build(BuildContext context) {
    return _buildTiles(entry);
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of our application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: ''), //Flutter Expansion Issue'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ExpansionTileExample(),
    );
  }
}

class ExpansionTileExample extends StatelessWidget {
  const ExpansionTileExample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (BuildContext context, int index) => EntryItem(data[index]),
      itemCount: data.length,
    );
  }
}

// One entry in the multilevel list displayed by this app.
class Entry {
  //Change the constructor to set each parameter and skip subtitle on root
  const Entry(
      {required this.title, this.children = const <Entry>[], this.subtitle});
  final String title;
  final List<Entry> children;
  final String? subtitle; // Can be null so root won`t have it
}

// Data to display.
const List<Entry> data = <Entry>[
  Entry(
    title: 'Day1',
    children: <Entry>[
      Entry(title: 'Topic T1.1', subtitle: 'Subtitle 1.1'),
      Entry(title: 'Topic T1.2', subtitle: 'Subtitle 1.2'),
      Entry(title: 'Toipc T1.3', subtitle: 'Subtitle 1.3'),
      Entry(title: 'Topic T1.4', subtitle: 'Subtitle 1.4'),
      Entry(title: 'Topic T1.5', subtitle: 'Subtitle 1.5'),
      Entry(title: 'Topic T1.6', subtitle: 'Subtitle 1.6'),
    ],
  ),
];

CodePudding user response:

To make the code more clean and solve your problems, I would recommend you to use the below data structure:

class Day{
  const Day(this.title, [this.children = const <Entry>[]]);
  final String title;
  final List<Entry> children;
}

class Entry {
  const Entry(this.title, this.subtitle, this.link);
  final String title;
  final String subtitle;
  final String link;
}

const List<Day> data = <Day>[
  Day(
    'Day1',
    <Entry>[
    ...
    ],
  ),
];

With the above data structure you could integrate it with your UI. If you have any doubt in how to integrate then do comment, I will expand my answer.

  • Related