skip to Main Content

I have a widget UnkownWidget() (let’s say the sample counter from Flutter) :

enter image description here

What I would like to create is a widget that displays its child next to a duplication of its view:

WithPreviewOnTheRight(
  child: UnknownWidget(),
),

What I would like WithPreviewOnTheRight to do is to display its child on the left, and a preview/screening/duplication on the right:

I want the 2 instances to be "the same" (aka sharing the same state). When I interact with the widget on the left, the changes are also visible on the widget on the right.

enter image description here

The widget on the right doesn’t have to be interactive, I am planning to wrap it with an IgnorePointer. I just want it to be a "rediffusion" / "screening" of the main one on the left.

Using a Row as in

Row(
  children: [
    Expanded(
      child: child,
    ),
    Expanded(
      child: child,
    ),
  ],
),

wouldn’t work as the 2 "views" wouldn’t share the same state.


How can I duplicate the "view" of a widget?

2

Answers


  1. Ok, let’s see if I understood what you want to achieve.

    The Widget approach:
    Create a widget class for your component, which you can call multiple instances which might not be entirely disconnected between them, if you have a common controller that is used to set their state, making them clones of each other.

    class EmptyScreen extends StatelessWidget {
      const EmptyScreen({super.key});
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text("title"),
          ),
          body: const Center(
            child: Flexible(flex: 1, child: Text('Content')),
          ),
        );
      }
    }
    

    The Method approach:
    Just like before, but instead of creating a class, you create a function that returns the Widget.
    These methods might create an exact clone of the element that you want, without the Widget state management part in it.

     Widget EmptyScreen() {
        return Scaffold(
          appBar: AppBar(
            title: const Text("title"),
          ),
          body: const Center(
            child: Flexible(flex: 1, child: Text('Content')),
          ),
        );
      }
    

    in both approaches, you can call the element by writing EmptyScreen() on your widget tree.

    Just be aware that any constraints like height, and width are not set by default, and might depend on the parent of the element where you place your self-made widgets.

    To make sure both have the same aspect, you might need to track the size of one of them, and manually set the values of the clone.

    I hope this helped. 👍

    Login or Signup to reply.
  2. I think what you want is to paint the child another time, next to the old one. And you won’t be able to interact with the second one.

    import 'package:flutter/material.dart';
    import 'package:flutter/rendering.dart';
    
    class DoubleWidget extends SingleChildRenderObjectWidget {
      const DoubleWidget({super.key, required super.child});
    
      @override
      RenderObject createRenderObject(BuildContext context) {
        return DoubleRenderObject();
      }
    }
    
    class DoubleRenderObject extends RenderShiftedBox {
      DoubleRenderObject({RenderBox? child}) : super(child);
    
      @override
      void performLayout() {
        final child = this.child!;
        final childConstraints = BoxConstraints(
          maxWidth: constraints.maxWidth / 2,
          minWidth: constraints.minWidth / 2,
          minHeight: constraints.minHeight,
          maxHeight: constraints.maxHeight,
        );
        child.layout(childConstraints, parentUsesSize: true);
        size = Size(child.size.width * 2, child.size.height);
      }
    
      @override
      void paint(PaintingContext context, Offset offset) {
        super.paint(context, offset);
        super.paint(context, offset + Offset(child!.size.width, 0));
      }
    
      @override
      double computeMinIntrinsicWidth(double height) {
        return (child?.getMinIntrinsicWidth(height) ?? 0.0) * 2;
      }
    
      @override
      double computeMaxIntrinsicWidth(double height) {
        return (child?.getMaxIntrinsicWidth(height) ?? 0.0) * 2;
      }
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search