SachinGanesh / screenshot

Flutter Screenshot Library
https://pub.dev/packages/screenshot
MIT License
349 stars 142 forks source link

how to capture a scrollview #10

Closed ZMNOTZ closed 3 years ago

gvNN7 commented 5 years ago

If you are trying take a full screenshot of a listview or whatever widget that scrolls.. you might see this post

stefanpfahler commented 4 years ago

If you are trying take a full screenshot of a listview or whatever widget that scrolls.. you might see this post

Can you add the example from your source code where you managed to get the scrollshot ? .. It would help a lot.

stefanpfahler commented 4 years ago

@SachinGanesh can you look into this issue pls .. I saw that you already closed an issue that covered the same problem. It would be really helpful if you could provide a little snippet of source code on how you managed to solve the problem because I can't get it to work.

gvNN7 commented 4 years ago

If you are trying take a full screenshot of a listview or whatever widget that scrolls.. you might see this post

Can you add the example from your source code where you managed to get the scrollshot ? .. It would help a lot.

Sure! Let me remember where i use this package and i`ll post here. Stay tuned.

gvNN7 commented 4 years ago

If you are trying take a full screenshot of a listview or whatever widget that scrolls.. you might see this post

Can you add the example from your source code where you managed to get the scrollshot ? .. It would help a lot.

@stefanpfahler you can do something like this..

Wrap your list with Screenshot widget, but at this point the screenshot can't reach all items on the list.. (my list is being build on the StreamBuilder widget).

image

So, just wrap your Scrollable widget (or his father) with SingleChildScrollView, like this:

image

stefanpfahler commented 4 years ago

Great! Thank you very much! I think you can close this issue now

jagan999 commented 4 years ago

Hi I have the exact same situation mentioned in the post above where I have the following hierarchy being rendered: Card->Column->Container->ListView and using this package only rendered the visible part of the ListView. I tried wrapping the Container inside a SingleChildScrollView but it still only exports the visible part of the ListView.

gvNN7 commented 4 years ago

@jagan999 hmm, are you trying to take a screenshot of entire hierarchy or just the ListView ? Can you post some example of your code here ?

Hi I have the exact same situation mentioned in the post above where I have the following hierarchy being rendered: Card->Column->Container->ListView and using this package only rendered the visible part of the ListView. I tried wrapping the Container inside a SingleChildScrollView but it still only exports the visible part of the ListView.

jagan999 commented 4 years ago

I'm trying to get the screenshot only of the ListView...Like you mentioned previously, I tried wrapping Screenshot widget inside SingleChildScrollView and it still only takes the screenshot of the visible portion of the ListView.

Here's the snippet of my code `` @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppTheme().scaffoldBackgroundColor, body: ListView(controller: _controller, children: [ Container( child: FutureBuilder( future: buildData(), builder: (context, snapshot) { switch (snapshot.connectionState) { default: if (snapshot.hasError) return Text(snapshot.error.toString()); else { if (snapshot.data != null) return Column( children: [ CustomIconButton( icon: Icon(MdiIcons.filePdfBox), onPressed: () async { // await saveInsight(); screenshotController .capture( path: '${Globals().storagePath.path}/details.png') .then((File image) { //Capture Done showMessage(context, 'Saved insight'); }).catchError((onError) { print(onError); }); }), SingleChildScrollView(child: Screenshot( controller: screenshotController, child: buildDetailsCard( context, snapshot.data))) ], ); else return CustomProgressIndicator(); } } })), ])); }

Card buildDetailsCard( BuildContext context, List<Map<String, dynamic>> data) { ScrollController controller = ScrollController();

List<Map<String, dynamic>> dataTable =
    []; 

for (Map<String, dynamic> data in allData) {
  List<Map<String, dynamic>> details = data ['Data']['Details'];
  for (Map<String, dynamic> detail in details) {
    if (detail['Value'] > 0.0)
      dataTable.add(detail); //Only add non zero assets/liabilities
  }
}

return Card(
    child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
          Text(
            'Details',
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          Divider(height: 8.0, color: Colors.black),
          Container(
              height: 300.0,
              width: 1500.0,
              child: ListView.builder(
                controller: controller,
                itemCount: dataTable.length,
                itemBuilder: (BuildContext context, int index) {
                  return Column(
                    children: <Widget>[
                      Container(
                        color: dataTable[index]['IsSummary']
                            ? AppTheme().cardColor
                            : Colors.white,
                        child: ListTile(
                            title: Text(
                                !dataTable[index]['IsSummary']
                                    ? dataTable[index]
                                            ['Class'] +
                                        ' - ' +
                                        dataTable[index]['Name']
                                    : dataTable[index]['Name'],
                                style: TextStyle(
                                    fontSize: 14.0,
                                    fontWeight: FontWeight.bold)),
                            subtitle: Text(
                                '# Active: ${dataTable[index]['NumActive'].toString()}',
                                style: TextStyle(fontSize: 12.0)),
                            trailing:
                                Text(Globals().defaultCurrency + ' ' + intl.NumberFormat("#,###").format(dataTable[index]['Value']),
                                    style: TextStyle(
                                        fontSize: 14.0,
                                        fontWeight: FontWeight.bold,
                                        color: dataTable[index]
                                                ['IsAsset']
                                            ? AppTheme().incomeColor
                                            : AppTheme().expenseColor)),
                            onTap: () {
                              if (!dataTable[index]['IsSummary'])
                                Navigator.of(context).pushNamed(
                                    dataTable[index]['Route']);
                            }),
                      ),
                      Divider(height: 4.0, color: AppTheme().primaryColor),
                    ],
                  );
                },
              ))
        ])));

} ``

gvNN7 commented 4 years ago

@jagan999 Sorry for the delay.. i just forget one point.

In your ListView that you wanna take a full screenshot, put a NeverScrollableScrollPhysics on it, then what is going to take control of the scrolling is the SingleChildScrollView.

So your code will be like this:

image

Full code: http://dontpad.com/jagan999

And the screenshot:

image

Hope this helps you!

jagan999 commented 4 years ago

Thank you. This fix worked wonderfully.

VocsyDikshit commented 3 years ago

I've Been Using SceenShot Package But have Founded Same Problem. I have Used Stack() in Which First Container is Static background Image and Second is 10 static Containers with SingleChildViewScrollView How can I get long ScreenShot with using the same package

mohitarora7272 commented 3 years ago

How can I achieve this using CustomScrollView With SliverList as a child? Screenshot from 2021-06-29 19-52-24

NikhilMJain commented 3 years ago

@mohitarora7272 did you find a solution to your specific use case with slivers?

flutzer commented 3 years ago

With version 1.2.3 and flutter 2.2.3, using captureFromWidget to take a screenshot of an off-tree list widget results in a clipped image. It's only as visible as the screen instead of the entire list. Any tips on solving that?

gtuceturan commented 3 years ago

@jagan999 hmm, are you trying to take a screenshot of entire hierarchy or just the ListView ? Can you post some example of your code here ?

Hi I have the exact same situation mentioned in the post above where I have the following hierarchy being rendered: Card->Column->Container->ListView and using this package only rendered the visible part of the ListView. I tried wrapping the Container inside a SingleChildScrollView but it still only exports the visible part of the ListView.

Hello how can print all widgets in pageview ? Do you have any idea?

mohitarora7272 commented 3 years ago

`body: SafeArea( child: ListView( controller: ScrollController(), children: [ Container( child: SingleChildScrollView( child: Screenshot( controller: screenshotController, child: Column( children: [ _dateTimeWidget(), _listHeadingWidget(), _listWidget(), _totalQtyWidget(), _subTotalWidget(), ], ),

),

          ),
        ),
      ],
    ),
  ),`

@mohitarora7272 did you find a solution to your specific use case with slivers?

Yes, I used the above code to achieve this at my end after lots of research on google. I have used SingleChildScrollView instead of CustomScrollView in my case and its works. Hope this will also help you. Thanks

ghost commented 2 years ago

Anyway to do this without a scrollview before screenshot widget ? Cannot use because of that expanded / flexible in child...

pawanDreemz commented 1 year ago

I am able to get full ScreenShot from screenshotController.capture(); But with this screenshotController.captureFromWidget it doesn't works. It only capture visible area.

RoxDevvv commented 1 year ago

how to achieve same results but using screenshotController.captureFromWidget

LeiYao123 commented 1 year ago

I am able to get full ScreenShot from screenshotController.capture();我可以从 screenshotController.capture(); 获取完整的屏幕截图 But with this screenshotController.captureFromWidget it doesn't works. It only capture visible area.但是这个 screenshotController.captureFromWidget 不起作用。它只捕获可见区域。 @pawanDreemz @RoxDevvv try it

screenshotController.captureFromWidget(
InheritedTheme.captureAll(context, container),
delay: const Duration(milliseconds: 100),
targetSize: const Size(800, 10000), // height A value as large as possible
)
XeroDays commented 1 year ago

@LeiYao123 Thank you, this worked fine AF.

nikhil-viewzen commented 9 months ago

I am able to get full ScreenShot from screenshotController.capture();我可以从 screenshotController.capture(); 获取完整的屏幕截图 But with this screenshotController.captureFromWidget it doesn't works. It only capture visible area.但是这个 screenshotController.captureFromWidget 不起作用。它只捕获可见区域。 @pawanDreemz @RoxDevvv try it

screenshotController.captureFromWidget(
    InheritedTheme.captureAll(context, container),
    delay: const Duration(milliseconds: 100),
    targetSize: const Size(800, 10000), // height A value as large as possible
  )

what if the hieght is not set how would i achieve that then?

marcellocamara commented 9 months ago

@LeiYao123

screenshotController.captureFromWidget(
    InheritedTheme.captureAll(context, container),
    delay: const Duration(milliseconds: 100),
    targetSize: const Size(800, 10000), // height A value as large as possible
  )

This works! I've discovered that the quality is a bit lower. But ok. Thanks