Flutter - How to set initial selected value and update it (also the layout) on tap of user?

0

I am trying to change the selected category after the user taps. Appreciate any solution the would help and/or improve my code. If you have any questions or clarification please let me know.

Category Provider:

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

class Category with ChangeNotifier {
  final String id;
  final String title;
  final bool isActive;

  Category({
    @required this.id,
    @required this.title,
    @required this.isActive,
  });
}
class Categories with ChangeNotifier {
  List<Category> _items = [
    Category(
      id: 'c1',
      title: 'Standard',
      isActive: true,
    ),
    Category(
      id: 'c2',
      title: 'French Lesson',
      isActive: false,
    ),
    Category(
      id: 'c3',
      title: 'Spanish Lesson',
      isActive: false,
    ),
  ];
  List<Category> get items {
    return [..._items];
  }
}

Note Screen: As of now the default is the first category. But how should I change the default if the user selected different category in category screen?

...
class NoteWriteScreen extends StatefulWidget {
  static
  const routeName = '/note-write';
  @override
  _NoteWriteScreenState createState() => _NoteWriteScreenState();
}
class _NoteWriteScreenState extends State <NoteWriteScreen> {
  Category selectedCategory;
  final _answerFocusNode = FocusNode();
  final _form = GlobalKey < FormState > ();
  var _editedNote = NoteItem(
    id: null,
    category: null,
    question: '',
    answer: '',
  );
  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final categoriesData = Provider.of<Categories>(context, listen: false);
      final categoriesDataItems = categoriesData.items;
      setState(() {
        selectedCategory = categoriesDataItems.first;
      });
    });
    super.initState();
  }
  void selectCat(BuildContext context) {
    Navigator.of(context).pushNamed(
      CategoriesScreen.routeName,
      arguments: selectedCategory
    );
  }
  @override
  Widget build(BuildContext context) {
    final categoriesData = Provider.of<Categories>(context);
    final categories = categoriesData.items.first;
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Text("New Note"),
          actions: < Widget > [
            IconButton(
              icon: const Icon(
                Icons.check), onPressed: () {
                // _saveNote();
                // ...
              },
            ),
          ],
      ),
...

Category Screen:

  • On this page, all categories will be displayed, but only the selected (in Note Screen) will have border layout.
  • And when the user taps on other category, the default category will change as well as the selected category when the user presses the back button.
  • The border layouts will also be updated. If the user selects the same category, then no change on default category, selected category and on border layout.

code

...
class CategoriesScreen extends StatefulWidget {
    static
    const routeName = '/categories';
    @override
    _CategoriesScreenState createState() => _CategoriesScreenState();
}
class _CategoriesScreenState extends State < CategoriesScreen > {
    toggleCategory(String catId) {
        print(catId);
        // print(catId);
    }
    @override
    Widget build(BuildContext context) {
        final categoriesData = Provider.of < Categories > (context);
        final categories = categoriesData.items.toList();
        final routeArgs = ModalRoute.of(context).settings.arguments as Category;
        // String categoryID = routeArgs.id;
        return Scaffold(appBar: AppBar(title: Text('Category'), ), body: ListView.builder(itemCount: categories.length, itemBuilder: (ctx, i) => CategoryItem(categories[i].id, categories[i].title, routeArgs.id == categories[i].id ? true : false, toggleCategory), ), );
    }
}

Category Item Screen: This is where on tap of user happens as will as the layout of a category.

...
class CategoryItem extends StatelessWidget {
  final String id;
  final String title;
  final bool isSelected;
  final Function toggleCategory;


  CategoryItem(this.id, this.title, this.isSelected, this.toggleCategory);
  @override
  Widget build(BuildContext context) {
    return InkWell(
      // onTap: toggleCategory(id),
      onTap: () => (id),
      child: Card(
        margin: EdgeInsets.all(10),
        child: Container(
          decoration: isSelected ? BoxDecoration(
            color: Color(0xffffffff),
            border: Border.all(
              color: Color(0xff201b3b),
              width: 2,
            ),
          ) : null ,
          
          child: Column(
            children: <Widget>[
              ListTile(
                title: Text(title),
              )
            ],
          ),
        ),
      ),
    );
  }
}

For now I'm still trying to learn on local data but in the future I might integrate this in firebase... Appreciate any help on this. Thank you!

android
android-studio
flutter
android-layout
dart
asked on Stack Overflow Jan 7, 2021 by Bry • edited Jan 7, 2021 by Bry

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0