RelativeLayout孩子没有出现

时间:2016-03-16 15:51:04

标签: android android-layout xamarin

我正在为Android运行ActivityOverlay渲染器。不幸的是,“进度条”视图没有正确显示。

到目前为止,这是我的代码:

internal class ViewImplementation : FormsViewGroup
    {
        private Framework.Controls.ActivityIndicatorOverlay _element;
        private FormsElementWrapper _displayView;
        private RelativeLayout _overlay;
        private ProgressBar _indicator;

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            if (!disposing)
                return;

            this._displayView = null;
            this._element = null;
            this._overlay = null;
            this._indicator = null;

            RemoveAllViews();
        }

        public ViewImplementation(Framework.Controls.ActivityIndicatorOverlay element, Context context) : base(context)
        {
            _element = element;
            EnsureChildLayers();
        }

        public void OnElementPropertyChanged(object sender, PropertyChangedEventArgs args)
        {
            if (_displayView == null || _overlay == null)
                return;

            switch (args.PropertyName)
            {
                case nameof(Framework.Controls.ActivityIndicatorOverlay.IsBusy):
                    UpdateIsBusy();
                    break;
                case nameof(Framework.Controls.ActivityIndicatorOverlay.Width):
                case nameof(Framework.Controls.ActivityIndicatorOverlay.Height):
                case nameof(Framework.Controls.ActivityIndicatorOverlay.OverlayBackgroundColor):
                    UpdateBackgroundColor();
                    break;
                case nameof(Framework.Controls.ActivityIndicatorOverlay.ActivityColor):
                    UpdateIndicatorColor();
                    break;
            }
        }

        protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
        {
            base.OnLayout(changed, left, top, right, bottom);

            _overlay.Layout(left, top, right, bottom);
            //          _indicator.Layout(left-200, top - 200, right - 200, bottom - 200);
//          _indicator.Layout(left, top, right, bottom);
            _displayView.Layout(left, top, right, bottom);
        }

        private void UpdateBackgroundColor()
        {
            _overlay.SetBackgroundColor(_element.OverlayBackgroundColor.ToAndroid());
        }

        private void UpdateIsBusy()
        {
            if (_element.IsBusy)
            {
                _overlay.Visibility = ViewStates.Visible;
            }
            else
            {
                _overlay.Visibility = ViewStates.Invisible;
            }
        }

        private void UpdateIndicatorColor()
        {
            if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop)
                return;

            this._indicator.IndeterminateDrawable.SetColorFilter(this._element.ActivityColor.ToAndroid(), PorterDuff.Mode.SrcIn);
        }

        private void EnsureChildLayers()
        {
            if (_displayView != null)
                return;

            _displayView = new FormsElementWrapper(_element.Content);
            this.AddView(_displayView);
            _indicator = new ProgressBar(this.Context);
            _indicator.Indeterminate = true;
            _indicator.ForceLayout();
            _overlay = new RelativeLayout(this.Context);
            _overlay.SetHorizontalGravity(GravityFlags.Center);
            _overlay.SetVerticalGravity(GravityFlags.Center);
            _overlay.AddView(_indicator, new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent));
            this.AddView(_overlay);

            UpdateBackgroundColor();
            UpdateIndicatorColor();
            UpdateIsBusy();
        }
    }

我希望视图以_overlay.AddView(_indicator, new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent));

判断,以最小尺寸显示

然而,除非我做_indicator.Layout(left, top, right, bottom);(我自己计算的值),否则我无法获得进度视图。然而,在我看来,如果我在这里进行计算,我会做错事,因为根据RelativeLayout规范判断,这应该是可行的,无需任何计算。

有人能够在这里发现错误吗?

1 个答案:

答案 0 :(得分:0)

此版本有效。至于为什么我不能让其他版本以我想要的方式工作 - 我仍然无能为力。至少它现在可以工作了。仍然对这个原因感到好奇。

internal class ViewImplementation : RelativeLayout
{
    private Framework.Controls.ActivityIndicatorOverlay _element;
    private FormsElementWrapper _displayView;
    private RelativeLayout _overlay;
    private ProgressBar _indicator;

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        if (!disposing)
            return;

        this._displayView = null;
        this._element = null;
        this._overlay = null;
        this._indicator = null;

        RemoveAllViews();
    }

    public ViewImplementation(Framework.Controls.ActivityIndicatorOverlay element, Context context) : base(context)
    {
        _element = element;
        EnsureChildLayers();
    }

    public void OnElementPropertyChanged(object sender, PropertyChangedEventArgs args)
    {
        if (_displayView == null || _overlay == null)
            return;

        switch (args.PropertyName)
        {
            case nameof(Framework.Controls.ActivityIndicatorOverlay.IsBusy):
                UpdateIsBusy();
                break;
            case nameof(Framework.Controls.ActivityIndicatorOverlay.Width):
            case nameof(Framework.Controls.ActivityIndicatorOverlay.Height):
            case nameof(Framework.Controls.ActivityIndicatorOverlay.OverlayBackgroundColor):
                UpdateBackgroundColor();
                break;
            case nameof(Framework.Controls.ActivityIndicatorOverlay.ActivityColor):
                UpdateIndicatorColor();
                break;
        }
    }

    private void UpdateBackgroundColor()
    {
        _overlay.SetBackgroundColor(_element.OverlayBackgroundColor.ToAndroid());
    }

    private void UpdateIsBusy()
    {
        if (_element.IsBusy)
        {
            _overlay.Visibility = ViewStates.Visible;
        }
        else
        {
            _overlay.Visibility = ViewStates.Invisible;
        }
    }

    private void UpdateIndicatorColor()
    {
        if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop)
            return;

        this._indicator.IndeterminateDrawable.SetColorFilter(this._element.ActivityColor.ToAndroid(), PorterDuff.Mode.SrcIn);
    }

    private void EnsureChildLayers()
    {
        if (_displayView != null)
            return;

        _displayView = new FormsElementWrapper(_element.Content);
        _displayView.LayoutParameters = new RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent);
        this.AddView(_displayView);
        _indicator = new ProgressBar(this.Context);
        var layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent);
        layoutParams.AddRule(LayoutRules.CenterInParent);
        _indicator.LayoutParameters = layoutParams;
        _indicator.Indeterminate = true;
        _overlay = new RelativeLayout(this.Context);
        _overlay.LayoutParameters = new RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent);
        _overlay.AddView(_indicator);

        this.AddView(_overlay);

        UpdateBackgroundColor();
        UpdateIndicatorColor();
        UpdateIsBusy();
    }
}

的变化:

  • 现在我派生自RelativeLayout
  • 每个孩子都设置了LayoutParameters
  • OnLayout不再定制