Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android: no text selection possible with useHybridComposition and long webview #722

Closed
5 tasks done
robert-virkus opened this issue Mar 14, 2021 · 9 comments
Closed
5 tasks done
Labels
bug Something isn't working

Comments

@robert-virkus
Copy link

Environment

Technology Version
Flutter version 2.0.2
Plugin version 5.1.0+4
Android version • android-arm64 • Android 9 (API 28) / • Android 11 (API 30) (emulator)
iOS version n/a
Xcode version n/a

Device information:
• BlackView/A80Pro (mobile) A80DK017EEA0070119
• Pixel 2 (emulator) sdk gphone x86 (mobile)

Description

When I enable the hybrid mode with AndroidInAppWebViewOptions( useHybridComposition: true ), then I cannot select text when setting the webview's height at the same time.

In a simple reproduction project I can reduce the height to a seemingly device specific value and then I can select text again. In a more complex setup I was not able to get selection to work by reducing the height, so the height might not be the deciding factor.

Expected behavior:
Text selection via the long press gesture should still be possible.

Current behavior:
Text selection does not work in InAppWebView from a certain height onward.

Steps to reproduce

  1. Put the InAppWebView in a SizedBox and let it load a long webpage.
  2. After loading measure the height (I'm using document.body.scrollHeight as this seems to work better than getContentHeight()) and apply the measured height in the SizedBox
  3. Try to select some text

Sample code (without null-safety):

double webviewHeight;
  @override
  Widget build(BuildContext context) {
     return Scaffold(
      appBar: AppBar(
        title: Text('Select Text'),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Text('header'),
            SizedBox(
              height: webviewHeight ?? MediaQuery.of(context).size.height,
              child: InAppWebView(
                initialUrlRequest: URLRequest(url: Uri.parse(url)),
                initialOptions: InAppWebViewGroupOptions(
                  crossPlatform: InAppWebViewOptions(
                    useShouldOverrideUrlLoading: true,
                    verticalScrollBarEnabled: false,
                  ),
                  android: AndroidInAppWebViewOptions(
                    useWideViewPort: false,
                    loadWithOverviewMode: true,
                    useHybridComposition: true,
                  ),
                ),
                
                onLoadStop: (controller, url) async {
                  int scrollHeight = await controller.evaluateJavascript(
                      source: 'document.body.scrollHeight');
                  if (scrollHeight != null) {
                    setState(() {
                      webviewHeight = scrollHeight + 30.0;
                    });
                  }
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

Possibly related to #704

@robert-virkus robert-virkus added the bug Something isn't working label Mar 14, 2021
@pichillilorenzo
Copy link
Owner

pichillilorenzo commented Mar 19, 2021

The problem is related to the SingleChildScrollView widget that consumes/captures the long-press touch events. If you remove the SingleChildScrollView widget, you can select the text.
I don't know if there is something else you can use instead of the SingleChildScrollView widget or if you can let delegate the long-press event to the InAppWebView widget only instead of the SingleChildScrollView parent widget.

@robert-virkus
Copy link
Author

robert-virkus commented Mar 19, 2021

Thank you very much for your feedback, but the text selection works when I either do not use the hybrid mode or when I have a webpage that is not too long. As I wrote above, I am unsure if the length of the webview is really the only criteria.

Since the text selection works in some case, I doubt that the SingleChildScrollView widget is the culprit here.

@pichillilorenzo
Copy link
Owner

Unfortunately, I'm not able to reproduce your problem.
Using your code and testing it with https://github.com/pichillilorenzo/flutter_inappwebview/pulls as URL (so the page is not too long), I can't select text with or without hybrid composition.
If I just remove the SingleChildScrollView, the long-press touch events work as expected inside the webview

@robert-virkus
Copy link
Author

Thanks again, I will try to come up with a better reproduction case and will file a new bug when I have it. Thanks and keep up the good work!

@pichillilorenzo
Copy link
Owner

pichillilorenzo commented Mar 19, 2021

Here is an example with your code and without SingleChildScrollView:

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();

  if (Platform.isAndroid) {
    await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
  }

  runApp(MaterialApp(
      home: MyApp()
  ));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  double? webviewHeight;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Select Text'),
      ),
      body: Column(
          children: [
            SizedBox(
              height: webviewHeight ?? MediaQuery.of(context).size.height,
              child: InAppWebView(
                initialUrlRequest: URLRequest(url: Uri.parse("https://github.com/pichillilorenzo/flutter_inappwebview/pulls")),
                initialOptions: InAppWebViewGroupOptions(
                  crossPlatform: InAppWebViewOptions(
                    useShouldOverrideUrlLoading: true,
                    verticalScrollBarEnabled: false,
                  ),
                  android: AndroidInAppWebViewOptions(
                    useWideViewPort: false,
                    loadWithOverviewMode: true,
                    useHybridComposition: true,
                  ),
                ),

                onLoadStop: (controller, url) async {
                  int? scrollHeight = await controller.evaluateJavascript(
                      source: 'document.body.scrollHeight');
                  if (scrollHeight != null) {
                    setState(() {
                      webviewHeight = scrollHeight + 30.0;
                    });
                  }
                },
              ),
            ),
          ],
        ),
    );
  }
}

Here is the screen recording:

device-2021-03-19-123045.mp4

Setting useHybridComposition: true or useHybridComposition: false doesn't change the fact I can select or not the text inside the webview.
So, I think the problem, probably, is related to the SingleChildScrollView widget and the fact that the InAppWebView widget is a PlatformView.
If possible, you should avoid using the WebView this way, also because using useHybridComposition: false with a very long page, it will crash your application for sure (you can test it using https://flutter.dev as URL) with this warning:

W/PlatformViewsController(28240): Creating a virtual display of size: [1440, 22593] may result in problems(https://github.com/flutter/flutter/issues/2897).It is larger than the device screen size: [1440, 2392].

@tneotia
Copy link
Contributor

tneotia commented Apr 24, 2021

Little bit of an old thread but this is easily fixable with gestureRecognizers. I had a similar issue where the user would have to double tap the webview to get the text to select. However

gestureRecognizers: {
   Factory<VerticalDragGestureRecognizer>(() => VerticalDragGestureRecognizer()),
   Factory<LongPressGestureRecognizer>(() => LongPressGestureRecognizer()),
},

does the trick. VerticalDrag for scrolling support and LongPress for text selection support.

@robert-virkus
Copy link
Author

Very cool, I can confirm this works fine! In my case I do not use the VerticalDragGestureRecognizer as I have the InAppWebView within a scrollview already. Next to the LongPressGestureRecognizer for selecting text I also use the ScaleGestureRecognizer for pinch to zoom. This is tricky to achieve as a user but better than no zoom at all.

gestureRecognizers: {
    Factory<LongPressGestureRecognizer>(() => LongPressGestureRecognizer()),
    Factory<ScaleGestureRecognizer>(() => ScaleGestureRecognizer()),
},

So many thanks @tneotia - you made someone very happy :-)

robert-virkus added a commit to Enough-Software/enough_mail_flutter that referenced this issue Apr 26, 2021
To use MimeMessageViewer in a ScrollView,
the adjustHeight option needs to be set to true.
However, in that case the text selection
using the long press gesture is not working anymore.

This is now fixed by specifying  gestureRecognizers.

Compare
pichillilorenzo/flutter_inappwebview#722
for details.
@kid-with-a-gun
Copy link

Little bit of an old thread but this is easily fixable with gestureRecognizers. I had a similar issue where the user would have to double tap the webview to get the text to select. However

gestureRecognizers: {
   Factory<VerticalDragGestureRecognizer>(() => VerticalDragGestureRecognizer()),
   Factory<LongPressGestureRecognizer>(() => LongPressGestureRecognizer()),
},

does the trick. VerticalDrag for scrolling support and LongPress for text selection support.

add gestureRecognizers helps,thank you

Copy link

github-actions bot commented Oct 4, 2024

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants