ListView中的实际MeasuredHeight值是否带有自定义渲染器?

时间:2018-04-04 16:12:17

标签: xamarin.forms xamarin.android

这个问题已在here和其他地方得到解决,但没有一个建议的解决方案对我有用。大多数答案是为布局事件附加侦听器和执行测量的变体,直到返回的值有意义,然后删除附加的侦听器。问题是如果没有滚动状态变化,孩子在测量时总是返回零维度。

这是我最接近解决方案的方法:

public class CustomListViewRenderer : ListViewRenderer, IOnScrollListener, IOnLayoutChangeListener
{
    public CustomListViewRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
    {
        base.OnElementChanged(e);

        Control.SetOnScrollListener(this);
        Control.AddOnLayoutChangeListener(this);

        Task.Run(() =>
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                // Scrolls the ListView to an arbitrary position different than the top.  
                // Otherwise MeasuredHeight returns zero.
                Control.SetSelectionFromTop(1, 0);
            });
        });
    }

    public void OnScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
    {
    }

    public void OnScrollStateChanged(AbsListView view, ScrollState scrollState)
    {
        Debug.WriteLine("OnScrollStateChanged");
        Debug.WriteLine(Control.GetChildAt(0)?.MeasuredHeight);
    }

    public void OnLayoutChange(global::Android.Views.View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
    {
        Debug.WriteLine("OnLayoutChange");
        Debug.WriteLine(Control.GetChildAt(0)?.MeasuredHeight);
    }
}    

我的猜测是,有一些内部优化会导致MeasuredHeight返回零,即使子视图已经布局,除非滚动状态发生变化。这就是为什么OnElementChanged安排Control.SetSelectionFromTop(1, 0);在绘制ListView之后更改滚动位置的原因(大概)。

修改

当ListView处于其初始滚动位置时,或者之后滚动到该位置时,打印出子视图的类显示它们属于类ListViewRenderer_Container。其余的子视图属于类ConditionalFocusLayout

0 个答案:

没有答案