Search code examples
fluttertouchchildrenmulti-touch

Flutter: how to stop the finger in the side borders of the screen count as a touch?


I have a children's app that show pictures that they need to touch to play a sound. The images are centered occupying about 85% of the width. Testing with my son of 3 years old shows that the way he holds the phone ends up creating a touch on the borders of the screen, which then make the real touch on the image to not work. I'm using the inkwell component to get the touch event. I think one way to solve this l would be when getting a multi touch to only count the last touch made. By I actually not sure. If there is a way to solve this still using the inkwell would be great.

To generate the different images I use a ListView/Padding ( which I managed to get some area not toucheable)/Container/Column with an ClipRRect/Image and also a Padding/Text (with the name of the image) The app has the following interface: enter image description here


Solution

  • The idea with the last touch during multitouch can work, but it also requires some corner-cases to be handled.

    Instead, an Image widget can occupy 85% of the width, and inside of this Image widget you can place a transparent InkWell widget, that will response to the touch. See a picture below for better understanding:

    enter image description here

    Here is a simple example that you can modify to adjust the gap between active and inactive areas:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final screenWidth = MediaQuery.of(context).size.width;
        final screenHeight = MediaQuery.of(context).size.height;
        final imageWidth = screenWidth * 0.85;
        final imageHeight = screenHeight * 0.85;
    
        return Scaffold(
          appBar: AppBar(
            title: Text('Image InkWell Demo'),
          ),
          body: Center(
            child: Container(
              width: imageWidth,
              height: imageHeight,
              decoration: const BoxDecoration(
                image: DecorationImage(
                  fit: BoxFit.cover,
                  image: NetworkImage(
                      'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'), // Replace with your image asset
                ),
              ),
              child: Center(
                child: Container(
                  width: imageWidth * 0.60,
                  height: imageHeight * 0.60,
                  decoration: const BoxDecoration(
                    color: Colors.transparent,
                  ),
                  child: InkWell(
                    onTap: () {
                      print('InkWell tapped!');
                    },
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }