caduandrade / multi_split_view

Provides horizontal or vertical multiple split view for Flutter.
MIT License
152 stars 29 forks source link

dividerPainter doesn't grow when touched when Axis.horizontal #38

Closed 4bSolutionsLLP closed 4 months ago

4bSolutionsLLP commented 1 year ago

When using a dividerPainter with Axis.vertical, touching the divider causes the divider to 'grow' to the highlightedSize - this is correct behaviour.

When doing the same with Axis.horizontal, the divider doesn't grow until it is dragged.

caduandrade commented 1 year ago

Hi @4bSolutionsLLP!

Sorry for the delay. :disappointed:

I was unable to reproduce the issue using DividerPainters.grooved1 or DividerPainters.grooved2

Could you add some sample code?

summitcomputing commented 1 year ago

Hi Carlos - this is the code @4bSolutionsLLP is referring to...

We have a page with 2 MultiSplitViewThemes - 1 for portrait, 1 for landscape as follows:

  Widget _portraitSplitLayout(BuildContext context) {
    // set up multi split view
    MultiSplitViewController _multiSplitViewControllerPortrait =
        MultiSplitViewController(
      areas: [
        Area(
            weight: global
                .mvMultiSplitSavedWeightPortrait, // default size for top area
            minimalWeight: 0.25 // minimum 25% size for top area
            ),
        Area(
          minimalWeight: 0.25, // minimum 25% size for bottom area
        ),
      ],
    );

    MultiSplitView _multiSplitViewPortrait = MultiSplitView(
      axis: Axis.vertical,
      children: [
        _scrollingCardView(),
        _map(),
      ],
      controller: _multiSplitViewControllerPortrait,
      onWeightChange: () {
        global.mvMultiSplitSavedWeightPortrait =
            _multiSplitViewControllerPortrait.areas[0].weight;
      },
    );

    MultiSplitViewTheme _multiSplitViewThemePortrait = MultiSplitViewTheme(
      child: _multiSplitViewPortrait,
      data: MultiSplitViewThemeData(
        dividerThickness: 25,
        dividerPainter: DividerPainters.grooved1(
          color: Colors.grey[500],
          highlightedColor: Colors.grey[500],
          size: 30,
          highlightedSize: 90,
          thickness: 5,
        ),
      ),
    );

    return Expanded(
      // portrait layout
      child: Column(
        children: [
          Expanded(
            child: _multiSplitViewThemePortrait,
          ),
        ],
      ),
    );
  }

...and...

  Widget _landscapeSplitLayout(BuildContext context) {
    // set up multi split view
    MultiSplitViewController _multiSplitViewControllerLandscape =
        MultiSplitViewController(
      areas: [
        Area(
          weight: global
              .mvMultiSplitSavedWeightLandscape, // default size for top area
          minimalWeight: 0.25, // minimum 25% size for left area
        ),
        Area(
          minimalWeight: 0.25, // minimum 25% size for right area
        ),
      ],
    );

    MultiSplitView _multiSplitViewLandscape = MultiSplitView(
      axis: Axis.horizontal,
      children: [
        _scrollingCardView(),
        _map(),
      ],
      controller: _multiSplitViewControllerLandscape,
      onWeightChange: () {
        global.mvMultiSplitSavedWeightLandscape =
            _multiSplitViewControllerLandscape.areas[0].weight;
      },
    );

    MultiSplitViewTheme _multiSplitViewThemeLandscape = MultiSplitViewTheme(
      child: _multiSplitViewLandscape,
      data: MultiSplitViewThemeData(
        dividerThickness: 25,
        dividerPainter: DividerPainters.grooved1(
          color: Colors.grey[500],
          highlightedColor: Colors.grey[500],
          size: 30,
          highlightedSize: 90,
          thickness: 5,
        ),
      ),
    );

    return Expanded(
      // portrait layout
      child: Column(
        children: [
          Expanded(
            child: _multiSplitViewThemeLandscape,
          ),
        ],
      ),
    );
  }

Then the page build() method has an element:

MediaQuery.of(context).orientation == Orientation.portrait
                    ? _portraitSplitLayout(context)
                    : _landscapeSplitLayout(context),

So when the device is portrait, _multiSplitViewPortrait is used (Axis.vertical), and in landscape, _multiSplitViewLandscape is used (Axis.horizontal). If you then long press the splitController without dragging, the controller grows in portait (Axis.vertical) from 30 to 90, but doesn't grow in landscape (Axis.horizontal) until you start to drag.

caduandrade commented 1 year ago

Hi @summitcomputing !

I removed non-existing methods to have this example testable and compilable, ok?

I keep my packages focused on Desktops and I hadn't noticed this behavior. I tested it on my cell phone and as expected, it was even worse. The animation did not start on either one. :smile:

It was expected because I used only the onEnter and onExit events internally. I'll think about how it will be for mobile. I don't know if longPress will work because it can take a long time.

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

void main() => runApp(const MultiSplitViewExampleApp());

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Example(),
    );
  }
}

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

  @override
  ExampleState createState() => ExampleState();
}

class ExampleState extends State<Example> {
  double mvMultiSplitSavedWeightPortrait = .3;
  double mvMultiSplitSavedWeightLandscape = .3;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: MediaQuery.of(context).orientation == Orientation.portrait
            ? _portraitSplitLayout(context)
            : _landscapeSplitLayout(context));
  }

  Widget _portraitSplitLayout(BuildContext context) {
    // set up multi split view
    MultiSplitViewController multiSplitViewControllerPortrait =
        MultiSplitViewController(
      areas: [
        Area(
            weight: mvMultiSplitSavedWeightPortrait,
            // default size for top area
            minimalWeight: 0.25 // minimum 25% size for top area
            ),
        Area(
          minimalWeight: 0.25, // minimum 25% size for bottom area
        ),
      ],
    );

    MultiSplitView multiSplitViewPortrait = MultiSplitView(
      axis: Axis.vertical,
      controller: multiSplitViewControllerPortrait,
      onWeightChange: () {
        mvMultiSplitSavedWeightPortrait =
            multiSplitViewControllerPortrait.areas[0].weight!;
      },
      children: [
        _scrollingCardView(),
        _map(),
      ],
    );

    MultiSplitViewTheme multiSplitViewThemePortrait = MultiSplitViewTheme(
      data: MultiSplitViewThemeData(
        dividerThickness: 25,
        dividerPainter: DividerPainters.grooved1(
          color: Colors.grey[500]!,
          highlightedColor: Colors.grey[500],
          size: 30,
          highlightedSize: 90,
          thickness: 5,
        ),
      ),
      child: multiSplitViewPortrait,
    );

    return multiSplitViewThemePortrait;
  }

  Widget _landscapeSplitLayout(BuildContext context) {
    // set up multi split view
    MultiSplitViewController multiSplitViewControllerLandscape =
        MultiSplitViewController(
      areas: [
        Area(
          weight: mvMultiSplitSavedWeightLandscape, // default size for top area
          minimalWeight: 0.25, // minimum 25% size for left area
        ),
        Area(
          minimalWeight: 0.25, // minimum 25% size for right area
        ),
      ],
    );

    MultiSplitView multiSplitViewLandscape = MultiSplitView(
      axis: Axis.horizontal,
      controller: multiSplitViewControllerLandscape,
      onWeightChange: () {
        mvMultiSplitSavedWeightLandscape =
            multiSplitViewControllerLandscape.areas[0].weight!;
      },
      children: [
        _scrollingCardView(),
        _map(),
      ],
    );

    MultiSplitViewTheme multiSplitViewThemeLandscape = MultiSplitViewTheme(
      data: MultiSplitViewThemeData(
        dividerThickness: 25,
        dividerPainter: DividerPainters.grooved1(
          color: Colors.grey[500]!,
          highlightedColor: Colors.grey[500],
          size: 30,
          highlightedSize: 90,
          thickness: 5,
        ),
      ),
      child: multiSplitViewLandscape,
    );

    return multiSplitViewThemeLandscape;
  }

  Widget _scrollingCardView() {
    return Container(
        color: Colors.blue,
        child: const Center(child: Text('scrollingCardView')));
  }

  Widget _map() {
    return Container(
        color: Colors.yellow, child: const Center(child: Text('map')));
  }
}
summitcomputing commented 1 year ago

Thanks for testing, and glad you could reproduce the behaviour. It definitely only seems to affect the landscape (Axis.horizontal) behaviour here, but if you can fix it for your scenario, it should work here too.

caduandrade commented 1 year ago

I believe that version 2.3.0 will solve your problem. If you need anything, let me know.

4bSolutionsLLP commented 1 year ago

Hi, We have updated to v2.3.0 and whilst it now understands a long-press in portrait and landscape, it actually breaks things. The issue is that when you long-press, the line indicator correctly increases in size to show that we are in "drag mode", however, after about a second of pressing, the indicator returns to normal size and ceases to be draggable,

Thanks Ian 

On 09/02/2023 23:06:28, Carlos Eduardo Leite de Andrade @.> wrote: I believe that version 2.3.0 will solve your problem. If you need anything, let me know. — Reply to this email directly, view it on GitHub [https://github.com/caduandrade/multi_split_view/issues/38#issuecomment-1424956683], or unsubscribe [https://github.com/notifications/unsubscribe-auth/AQDXTEV3HVEN7QBKAK457KDWWVZ7HANCNFSM6AAAAAATQURYWQ]. You are receiving this because you were mentioned.Message ID: @.>

caduandrade commented 1 year ago

Hi @4bSolutionsLLP!

It shouldn't be happening. In the end, I didn't use longPress. I used the following events that theoretically would be the most correct to not have this problem reported by you:

dragDown is the equivalent of "press" but without the timeout. Interrupting the press without moving will trigger dragCancel.

I tested it on 2 different Androids. Unfortunately, I only have these two phones. I used Flutter 3.7.1 and 3.7.3.

Could you test using the code I posted above? It's complete. Just copy, paste, and run.

Are you using iOS or Android?