2

I'm trying to develop some notebook like this :

Picture of NoteBook

my issue is when user add some description of note .. if it long text , I got overflow error when I tying to show that note in HomeScreen . check this pictures:

picture of add some note in AddScreen

picture of overflow error note

I use GridView.builder to show Notes in Home page but I can not Develop Some code that Check if description of note is Long text , Change height of Card to same height that description does ! Here is my code :

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:samsung_note/CustomWidget/base_container.dart';
import 'package:samsung_note/Database/database.dart';
import 'package:samsung_note/Screens/add_screen.dart';
import 'package:samsung_note/Screens/details_screen.dart';
import 'package:samsung_note/app_style.dart';

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late Database _database;

  @override
  void initState() {
    _database = Database();
    super.initState();
  }
  @override
  void dispose() {
    _database.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final double itemHeight = (size.height - kToolbarHeight - 24) / 2;
    final double itemWidth = size.width / 2;
    return Scaffold(
      backgroundColor: Colors.grey.shade200,
      drawer: const Drawer(),
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Colors.grey.shade200,
        title: Text(
          "All notes",
          style: AppStyle.normalTextStyle.copyWith(fontWeight: FontWeight.w600),
        ),
        actions: [
          IconButton(onPressed: () {}, icon: const Icon(Icons.search)),
          IconButton(
              onPressed: () {}, icon: const Icon(Icons.more_vert_outlined))
        ],
      ),
      body: FutureBuilder<List<NoteEntityData>>(
        future: _database.getAllNotes(),
        builder: (context, snapshot) {
          final List<NoteEntityData>? notes = snapshot.data;
          if (snapshot.connectionState != ConnectionState.done) {
            return Center(
              child: LoadingAnimationWidget.inkDrop(
                  color: Colors.deepOrange, size: 200),
            );
          } else if (snapshot.hasError) {
            return Center(
              child: Text(snapshot.error.toString()),
            );
          } else if (notes!.isNotEmpty) {
            return Padding(
                padding: const EdgeInsets.symmetric(vertical: 16),
                child: GridView.builder(
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                      mainAxisExtent: 160,
                      crossAxisCount: 2),
                  itemCount: notes.length,
                  itemBuilder: (context, index) {
                    final note = notes[index];
                    return GestureDetector(
                        onTap: () => Get.to(() => DetailsScreen(id: note.id)),
                        child: BaseContainer(note: note));
                  },
                ));
          } else if (notes.isEmpty) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(
                    "No notes",
                    style: AppStyle.normalTextStyle.copyWith(
                        color: Colors.grey.shade700,
                        fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 20),
                  Text("Tap the Add button to create a note",
                      style: AppStyle.normalTextStyle
                          .copyWith(color: Colors.grey.shade500, fontSize: 17)),
                ],
              ),
            );
          }
          return const Text('No Data Found');
        },
      ),
      floatingActionButton: SizedBox(
        height: 65,
        width: 65,
        child: FloatingActionButton(
          tooltip: 'Add note',
          child: const Icon(
            Icons.add,
            size: 30,
          ),
          onPressed: () => Get.to(() => const AddScreen()),
        ),
      ),
    );
  }
}

Here is my card widget (baseContainer) code :

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:samsung_note/Database/database.dart';
import 'package:samsung_note/app_style.dart';
class BaseContainer extends StatelessWidget {
  final NoteEntityData note ;
  const BaseContainer({Key? key,required this.note}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    //final time = DateFormat.Hm().format(note.createdTime);
    final dateTime = DateFormat.yMMMd().format(note.createdTime);
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8.0,vertical: 8),
      child: Container(
        width: MediaQuery.of(context).size.width*0.45,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(30)
        ),
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children:  [
              const CircleAvatar(
                backgroundColor: Colors.grey,
                radius: 4,
              ),
              const SizedBox(height: 6),
              Text(note.title,style: AppStyle.normalTextStyle,),
              const SizedBox(height: 5),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(dateTime,style: AppStyle.smallTextStyle.copyWith(color: Colors.grey),),
                  note.isImportant ? const Icon(Icons.star,color: Colors.orange,size: 20,): Container(),
                ],
              ),
              const SizedBox(height: 15),
              Text(note.description,style: AppStyle.smallTextStyle,),
            ],
          ),
        ),
      ),
    );
  }
}

I want to solve this issue that if Height of Description text is more than that 160 pixel , Extented to whatever height description have .

  • Welcome to SO! What do you mean about calculating the widget height? Looks like you want to make the card twice as tall, is that it? Or you'd like to trim the text to the first line only? – lepsch Jun 23 '22 at 17:46
  • Hi there ! I locking for the way that if description of note that i want to show in card and in screen is more than 160 pixel , scale card height to whatever description height does . I dont wanna set a static height for each note card .. I want to flexible it – arash shakibaee Jun 24 '22 at 10:49

2 Answers2

1

To fix the problem with the card not resizing with the text you'd need to change from the GridView to 2 Columns side by side because GridViews have fixed width and height.

Take a look at the screenshot and the live demo on DartPad:

Screenshot

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

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        appBarTheme: const AppBarTheme(
          foregroundColor: Color.fromARGB(255, 95, 95, 95),
          backgroundColor: Colors.transparent,
        ),
      ),
      home: const HomeScreen(),
    );
  }
}

class NoteEntityData {
  final DateTime createdTime;
  final String title;
  final bool isImportant;
  final String description;

  const NoteEntityData({
    required this.createdTime,
    required this.title,
    this.isImportant = false,
    required this.description,
  });
}

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

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  // late Database _database;

  @override
  void initState() {
    // _database = Database();
    super.initState();
  }

  @override
  void dispose() {
    // _database.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final double itemHeight = (size.height - kToolbarHeight - 24) / 2;
    final double itemWidth = size.width / 2;
    return Scaffold(
      backgroundColor: Colors.grey.shade200,
      drawer: const Drawer(),
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Colors.grey.shade200,
        title: const Text(
          "All notes",
          style: TextStyle(
              fontWeight: FontWeight.w600,
              color: Color.fromARGB(255, 95, 95, 95)),
        ),
        actions: [
          IconButton(onPressed: () {}, icon: const Icon(Icons.search)),
          IconButton(
              onPressed: () {}, icon: const Icon(Icons.more_vert_outlined))
        ],
      ),
      body: FutureBuilder<List<NoteEntityData>>(
        future: Future.value([
          NoteEntityData(
            createdTime: DateTime.now(),
            title: 'Some title',
            isImportant: true,
            description: 'Hello guys ',
          ),
          NoteEntityData(
            createdTime: DateTime.now(),
            title: 'Work stuff',
            isImportant: true,
            description:
                '1 : go to office\n2 : secret\n3 : get back to home\n4 : bela bela bela\n5 : ...\n6 : ...\n.\n.\n.\n.',
          ),
          NoteEntityData(
            createdTime: DateTime.now(),
            title: 'alireza',
            description: 'Arash shakibaee',
          ),
        ]),
        builder: (context, snapshot) {
          final List<NoteEntityData>? notes = snapshot.data;
          if (notes == null) {
            return const Center(
              child: SizedBox(
                height: 200,
                child: CircularProgressIndicator(color: Colors.deepOrange),
              ),
            );
          } else if (snapshot.hasError) {
            return Center(
              child: Text(snapshot.error.toString()),
            );
          } else if (notes.isNotEmpty) {
            return Padding(
              padding: const EdgeInsets.symmetric(vertical: 16),
              child: SingleChildScrollView(
                child: Center(
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: [
                      Expanded(
                        child: Column(
                          children: [
                            for (int i = 0; i < notes.length; i += 2)
                              GestureDetector(
                                  onTap:
                                      () {}, // => Get.to(() => DetailsScreen(id: note.id)),
                                  child: BaseContainer(note: notes[i])),
                          ],
                        ),
                      ),
                      Expanded(
                        child: Column(
                          children: [
                            for (int i = 1; i < notes.length; i += 2)
                              GestureDetector(
                                  onTap:
                                      () {}, // => Get.to(() => DetailsScreen(id: note.id)),
                                  child: BaseContainer(note: notes[i])),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            );
          } else if (notes.isEmpty) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(
                    "No notes",
                    style: TextStyle(
                        color: Colors.grey.shade700,
                        fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 20),
                  Text("Tap the Add button to create a note",
                      style:
                          TextStyle(color: Colors.grey.shade500, fontSize: 17)),
                ],
              ),
            );
          }
          return const Text('No Data Found');
        },
      ),
      floatingActionButton: SizedBox(
        height: 65,
        width: 65,
        child: FloatingActionButton(
            tooltip: 'Add note',
            child: const Icon(
              Icons.add,
              size: 30,
            ),
            onPressed: () {} // => Get.to(() => const AddScreen()),
            ),
      ),
    );
  }
}

class BaseContainer extends StatelessWidget {
  final NoteEntityData note;
  const BaseContainer({Key? key, required this.note}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    //final time = DateFormat.Hm().format(note.createdTime);
    final dateTime = DateFormat.yMMMd().format(note.createdTime);
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8),
      child: Container(
        width: MediaQuery.of(context).size.width * 0.45,
        decoration: BoxDecoration(
            color: Colors.white, borderRadius: BorderRadius.circular(30)),
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const CircleAvatar(
                backgroundColor: Colors.grey,
                radius: 4,
              ),
              const SizedBox(height: 6),
              Text(
                note.title,
                style: TextStyle(fontSize: 22),
              ),
              const SizedBox(height: 5),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    dateTime,
                    style: TextStyle(color: Colors.grey, fontSize: 16),
                  ),
                  if (note.isImportant)
                      const Icon(
                          Icons.star,
                          color: Colors.orange,
                          size: 20,
                        ),
                ],
              ),
              const SizedBox(height: 15),
              Text(
                note.description,
                style: TextStyle(fontSize: 16)
                .copyWith(overflow: TextOverflow.fade),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
lepsch
  • 8,927
  • 5
  • 24
  • 44
  • Thanks a lot man your solution is very useful but my problem is I want build some structure that if my description height is more than 160 pixel , I want to set all the description in card widget .. I don't wanna fade it or something like that .. I want to height of my card scale – arash shakibaee Jun 24 '22 at 12:46
  • Oh, I see. You'd need to use a component other than GridView. GridViews have fixed height for every item. Let me update my answer. – lepsch Jun 24 '22 at 12:47
  • Also, can you provide a screenshot of what you want exactly? – lepsch Jun 24 '22 at 12:58
  • I can provide you a video man .. do you have any social media ? like WhatsApp or telegram or Instagram ? also I can connect you with AnyDesk if you have it – arash shakibaee Jun 24 '22 at 13:38
  • I've updated my answer. Please take a look – lepsch Jun 24 '22 at 13:39
  • It's working but how can I go to the DetailScreen with specific id of each note ? – arash shakibaee Jun 24 '22 at 14:59
  • I've commented out the code that goes to the `DetailScreen` as I don't have the definition of it. Just uncomment them and you're good to go. Besides that I've commented other lines out, like the database init, just to make it work on my side. – lepsch Jun 24 '22 at 15:26
  • I know man . the issue is when you want to go to the DetailScreen , I have to pass note.id . I can't specify id of each notes with out making a builder . when I trying to make cards . I said : final note = notes[index] .. in builder I pass index and its working just fine but in your solution i don't know how can I pass id of each note in DetailScreen . – arash shakibaee Jun 24 '22 at 22:35
  • I see. Please, open another question with this info as this is completely different from the original question and just let me know. Also, if this answer did solve your original question remember to approve it ✅ (upvote it ▲ if you like) so other users know which answer to look for. – lepsch Jun 24 '22 at 22:54
0

Try childAspectRatio inside grid delegate and value (Child width / child height)

GridView.count(
childAspectRatio = value

Mahi
  • 1,297
  • 1
  • 14
  • 28
  • this is working for GridView.count() NOT FOR GridView,builder() .. is there any solution for building like this code with GridView.count() ? – arash shakibaee Jun 23 '22 at 19:42
  • Which one you want gridview.count or gridview.builder? – Mahi Jun 23 '22 at 20:08
  • The one who can solve my problem ... I tried to use gridView.count() for that specific childAspectRatio but I could not find away to show notes card in screen .. if you locking at my code , I use itemCount and itemBuilder properties in GridView.builder() But there no such as thing as this properties in GridView.count() – arash shakibaee Jun 24 '22 at 10:37