xamarin/Xamarin.Forms

[Android] StackLayout Height not updated with IsVisible Binding

开放

#4,424 创建于 2018年11月15日

 (2 条评论) (0 个反应) (0 位负责人)C# (1,926 个派生)batch import
e/5 :clock5:help wantedinactivep/Androidt/bug :bug:up-for-grabs

仓库指标

星标
 (5,644 个星标)
PR 合并指标
 (30 天内没有已合并 PR)

描述

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;
    }
}

贡献者指南