xamarin/Xamarin.Forms

[Android] StackLayout Height not updated with IsVisible Binding

Open

#4,424 opened on Nov 15, 2018

 (2 comments) (0 reactions) (0 assignees)C# (1,926 forks)batch import
e/5 :clock5:help wantedinactivep/Androidt/bug :bug:up-for-grabs

Repository metrics

Stars
 (5,644 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Description

The height of a StackLayout is not properly updated on android when using the IsVisible Property. This sounds similar to this issue, but it claims to be ios specific: https://github.com/xamarin/Xamarin.Forms/issues/4184

Steps to Reproduce

  1. Download my sample and run it on android
  2. Open the About Page
  3. Disable Option 5, 4, 3, 2, 1
  4. Go to the Browse Page
  5. Go back to the About Page
  6. Enable 1
  7. Number 2 does not show up. Only until you trigger 1 twice again.

Note: I broke down the issue into this small reproducible example. Sometimes the height changes not only when you trigger the button twice, but also when you scrol down and up again (So the control is outside the view). This does not work for the first item, but once you enable all 4 elements, the 5th will show up if you do that scoll trick. Its a rendering issue.

Expected Behavior

The Stacklayout should get updated

Actual Behavior

It does not change the height on the first trigger, only after the second. Sometimes the bug gets triggered, sometimes not.

Basic Information

  • Version with issue: 3.3.0.912540
  • Last known good version: Dont know
  • IDE: Visual Studi 2017
  • Platform Target Frameworks:
    • Android: 8.1
    • UWP: Nuget 6.1.5, 16299
  • Android Support Library Version: 27
  • Nuget Packages: None
  • Affected Devices: None

Screenshots

grafik

Reproduction Link

StackLayoutVisibleBug.zip

You can try my zipped Solution. I only modified the About View and Viewmodel. Its the Master-Detail example. For those who want to see the code here in the issue, here is a copy:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StackLayoutVisibleBug.Views.AboutPage"
             xmlns:vm="clr-namespace:StackLayoutVisibleBug.ViewModels"
             Title="{Binding Title}">

    <ContentPage.BindingContext>
        <vm:AboutViewModel />
    </ContentPage.BindingContext>

    <ListView ItemsSource="{Binding TestData}" 
              HasUnevenRows="true"
              CachingStrategy="RecycleElement">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout>
                        <StackLayout IsVisible="{Binding Visible}">
                            <Label Text="{Binding Title}"></Label>
                            <Switch IsToggled="{Binding Modified}"></Switch>
                        </StackLayout>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace StackLayoutVisibleBug.ViewModels
{
    public class AboutViewModel : BaseViewModel
    {

        private TestEntry _1 = new TestEntry("1");
        private TestEntry _2 = new TestEntry("2");
        private TestEntry _3 = new TestEntry("3");
        private TestEntry _4 = new TestEntry("4");
        private TestEntry _5 = new TestEntry("5");

        public ObservableCollection<TestEntry> _testData = new ObservableCollection<TestEntry>();

        public ObservableCollection<TestEntry> TestData => _testData;

        public AboutViewModel()
        {
            _testData.Add(_1);
            _testData.Add(_2);
            _testData.Add(_3);
            _testData.Add(_4);
            _testData.Add(_5);
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));
            _testData.Add(new TestEntry("filler"));

            _1.PropertyChanged += OnPropertyChanged;
            _2.PropertyChanged += OnPropertyChanged;
            _3.PropertyChanged += OnPropertyChanged;
            _4.PropertyChanged += OnPropertyChanged;
            _5.PropertyChanged += OnPropertyChanged;
        }

        private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            _2.Visible = _1.Modified;
            _3.Visible = _2.Modified;
            _4.Visible = _3.Modified;
            _5.Visible = _4.Modified;
        }
    }

    public class TestEntry : BaseViewModel
    {
        public TestEntry(string title)
        {
            Title = title;
        }

        public bool Modified
        {
            get => _modified;
            set => SetProperty(ref _modified, value);
        }
        private bool _modified = true;

        public bool Visible
        {
            get => _visible;
            set => SetProperty(ref _visible, value);
        }
        private bool _visible = true;
    }
}

Contributor guide