1
votes

I have a scrollabillity issue in a Form, layered out by BoxLayout.y().

The form contains many Tabs (with fixed size), each tab of the Tabs can contain an image or a video (the video is inside a BorderLayout to scale it at the tab size).

If an image is shown, the scrolling up and down works correctly.

If a video is shown, the y scrolling is not possibile, I can only swipe to change the tab.

I suppose that the cause of this issue is that videos are native component (I used the Codename One API to show the videos).

How can I solve or workaround this issue? This is crucial for the app design. Thanks for the tips.

1
This happens on Android and iOS. I cannot test on the Simulator because when a Form contains a video the Simulator crashes because of the bug github.com/codenameone/CodenameOne/issues/3360 - Francesco Galgani
As a workaround try using video.setEnabled(false) so it won't grab pointer events. I provided a potential workaround for the simulator issue in the issue comments - Shai Almog
video.setEnabled(false) doesn't solve. Please see my answer. - Francesco Galgani
That's a very good solution you came up with. Notice that in my suggestion I referred to the actual video peer and not the surrounding container so it might work if you find that peer and disable that. But your solution is elegant and good - Shai Almog

1 Answers

1
votes

The video.setEnabled(false) workaround (Make videos scrollable) doesn't work.

I workaround in a different way, inserting the MediaPlayer container in a LayeredLayout container, and then placing a Button over the MediaPlayer. A generic empty Label doesn't work, but an empty Button works. Of course I have to override calcPreferredSize to make the MediaPlayer and the Button of the same size (or use a different approach to make them of the same size).

This allows scrolling, but prevents the tapping of the play and pause Buttons (that are over the video). I solved also this issue.

In short, this is my solution, tested on Simulator, Android and iOS (in the following code, note that videoBtnsCnt is a Container over the video, in which I inserted play and pause Buttons):

        MediaPlayer mediaPlayer = new MediaPlayer(video) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(size, size);
            }
        };

        Container mediaPlayerCnt = new Container(new LayeredLayout(), "NoMarginNoPadding") {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(size, size);
            }
        };
        mediaPlayerCnt.add(mediaPlayer);

        Button allowScrollingLabel = new Button() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(size, size);
            }
        };
        allowScrollingLabel.setUIID("NoMarginNoPadding");
        allowScrollingLabel.addActionListener(l -> {
            Component responder = videoBtnsCnt.getResponderAt(l.getX(), l.getY());
            if (responder instanceof Button) {
                // it can be a play button or a pause button
                ((Button) responder).pressed();
                ((Button) responder).released();
            }
        });
        mediaPlayerCnt.add(allowScrollingLabel);