Ejemplo n.º 1
0
        public override void Initialize(RecyclerView view)
        {
            colView = view as CollectionView;
            if (colView == null)
            {
                throw new ArgumentException("LinearLayouter only can be applied CollectionView.", nameof(view));
            }
            // 1. Clean Up
            foreach (RecyclerViewItem item in VisibleItems)
            {
                colView.UnrealizeItem(item, false);
            }
            VisibleItems.Clear();
            ItemPosition.Clear();
            ItemSize.Clear();
            groups.Clear();

            FirstVisible = 0;
            LastVisible  = 0;

            IsHorizontal = (colView.ScrollingDirection == ScrollableBase.Direction.Horizontal);

            RecyclerViewItem header = colView?.Header;
            RecyclerViewItem footer = colView?.Footer;
            float            width, height;
            int count = colView.InternalItemSource.Count;

            if (header != null)
            {
                MeasureChild(colView, header);

                width = header.Layout != null?header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;

                height = header.Layout != null?header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;

                headerSize = IsHorizontal ? width : height;
                hasHeader  = true;

                colView.UnrealizeItem(header);
            }
            else
            {
                hasHeader = false;
            }

            if (footer != null)
            {
                MeasureChild(colView, footer);

                width = footer.Layout != null?footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;

                height = footer.Layout != null?footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;

                footerSize   = IsHorizontal ? width : height;
                footer.Index = count - 1;
                hasFooter    = true;

                colView.UnrealizeItem(footer);
            }
            else
            {
                hasFooter = false;
            }

            //No Internal Source exist.
            if (count == (hasHeader ? (hasFooter ? 2 : 1) : 0))
            {
                return;
            }

            int firstIndex = hasHeader ? 1 : 0;

            if (colView.IsGrouped)
            {
                isGrouped = true;

                if (colView.GroupHeaderTemplate != null)
                {
                    while (!colView.InternalItemSource.IsGroupHeader(firstIndex))
                    {
                        firstIndex++;
                    }
                    //must be always true
                    if (colView.InternalItemSource.IsGroupHeader(firstIndex))
                    {
                        RecyclerViewItem groupHeader = colView.RealizeItem(firstIndex);
                        firstIndex++;

                        if (groupHeader == null)
                        {
                            throw new Exception("[" + firstIndex + "] Group Header failed to realize!");
                        }

                        // Need to Set proper height or width on scroll direction.
                        if (groupHeader.Layout == null)
                        {
                            width  = groupHeader.WidthSpecification;
                            height = groupHeader.HeightSpecification;
                        }
                        else
                        {
                            MeasureChild(colView, groupHeader);

                            width  = groupHeader.Layout.MeasuredWidth.Size.AsRoundedValue();
                            height = groupHeader.Layout.MeasuredHeight.Size.AsRoundedValue();
                        }
                        //Console.WriteLine("[NUI] GroupHeader Size {0} :{0}", width, height);
                        // pick the StepCandidate.
                        groupHeaderSize = IsHorizontal ? width : height;
                        colView.UnrealizeItem(groupHeader);
                    }
                }
                else
                {
                    groupHeaderSize = 0F;
                }

                if (colView.GroupFooterTemplate != null)
                {
                    int firstFooter = firstIndex;
                    while (!colView.InternalItemSource.IsGroupFooter(firstFooter))
                    {
                        firstFooter++;
                    }
                    //must be always true
                    if (colView.InternalItemSource.IsGroupFooter(firstFooter))
                    {
                        RecyclerViewItem groupFooter = colView.RealizeItem(firstFooter);

                        if (groupFooter == null)
                        {
                            throw new Exception("[" + firstFooter + "] Group Footer failed to realize!");
                        }
                        // Need to Set proper height or width on scroll direction.
                        if (groupFooter.Layout == null)
                        {
                            width  = groupFooter.WidthSpecification;
                            height = groupFooter.HeightSpecification;
                        }
                        else
                        {
                            MeasureChild(colView, groupFooter);

                            width  = groupFooter.Layout.MeasuredWidth.Size.AsRoundedValue();
                            height = groupFooter.Layout.MeasuredHeight.Size.AsRoundedValue();
                        }
                        // pick the StepCandidate.
                        groupFooterSize = IsHorizontal ? width : height;

                        colView.UnrealizeItem(groupFooter);
                    }
                }
                else
                {
                    groupFooterSize = 0F;
                }
            }
            else
            {
                isGrouped = false;
            }

            bool failed = false;

            //Final Check of FirstIndex
            while (colView.InternalItemSource.IsHeader(firstIndex) ||
                   colView.InternalItemSource.IsGroupHeader(firstIndex) ||
                   colView.InternalItemSource.IsGroupFooter(firstIndex))
            {
                if (colView.InternalItemSource.IsFooter(firstIndex))
                {
                    StepCandidate = 0F;
                    failed        = true;
                    break;
                }
                firstIndex++;
            }

            if (!failed)
            {
                RecyclerViewItem sizeDeligate = colView.RealizeItem(firstIndex);
                if (sizeDeligate == null)
                {
                    // error !
                    throw new Exception("Cannot create content from DatTemplate.");
                }

                sizeDeligate.BindingContext = colView.InternalItemSource.GetItem(firstIndex);

                // Need to Set proper height or width on scroll direction.
                if (sizeDeligate.Layout == null)
                {
                    width  = sizeDeligate.WidthSpecification;
                    height = sizeDeligate.HeightSpecification;
                }
                else
                {
                    MeasureChild(colView, sizeDeligate);

                    width  = sizeDeligate.Layout.MeasuredWidth.Size.AsRoundedValue();
                    height = sizeDeligate.Layout.MeasuredHeight.Size.AsRoundedValue();
                }
                //Console.WriteLine("[NUI] Layout Size {0} :{0}", width, height);
                // pick the StepCandidate.
                StepCandidate = IsHorizontal ? width : height;
                if (StepCandidate == 0)
                {
                    StepCandidate = 1;                     //????
                }
                colView.UnrealizeItem(sizeDeligate);
            }

            float Current = 0.0F;
            IGroupableItemSource source       = colView.InternalItemSource;
            GroupInfo            currentGroup = null;

            for (int i = 0; i < count; i++)
            {
                if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
                {
                    if (i == 0 && hasHeader)
                    {
                        ItemSize.Add(headerSize);
                    }
                    else if (i == count - 1 && hasFooter)
                    {
                        ItemSize.Add(footerSize);
                    }
                    else if (source.IsGroupHeader(i))
                    {
                        ItemSize.Add(groupHeaderSize);
                    }
                    else if (source.IsGroupFooter(i))
                    {
                        ItemSize.Add(groupFooterSize);
                    }
                    else
                    {
                        ItemSize.Add(StepCandidate);
                    }
                }
                if (isGrouped)
                {
                    if (i == 0 && hasHeader)
                    {
                        //ItemPosition.Add(Current);
                        Current += headerSize;
                    }
                    else if (i == count - 1 && hasFooter)
                    {
                        //ItemPosition.Add(Current);
                        Current += footerSize;
                    }
                    else
                    {
                        //GroupHeader must always exist in group usage.
                        if (source.IsGroupHeader(i))
                        {
                            currentGroup = new GroupInfo()
                            {
                                GroupParent = source.GetGroupParent(i),
                                //hasHeader = true,
                                //hasFooter = false,
                                StartIndex    = i,
                                Count         = 1,
                                GroupSize     = groupHeaderSize,
                                GroupPosition = Current
                            };
                            currentGroup.ItemPosition.Add(0);
                            groups.Add(currentGroup);
                            Current += groupHeaderSize;
                        }
                        //optional
                        else if (source.IsGroupFooter(i))
                        {
                            //currentGroup.hasFooter = true;
                            currentGroup.Count++;
                            currentGroup.GroupSize += groupFooterSize;
                            currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
                            Current += groupFooterSize;
                        }
                        else
                        {
                            currentGroup.Count++;
                            currentGroup.GroupSize += StepCandidate;
                            currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
                            Current += StepCandidate;
                        }
                    }
                }
                else
                {
                    ItemPosition.Add(Current);

                    if (i == 0 && hasHeader)
                    {
                        Current += headerSize;
                    }
                    else if (i == count - 1 && hasFooter)
                    {
                        Current += footerSize;
                    }
                    else
                    {
                        Current += StepCandidate;
                    }
                }
            }

            ScrollContentSize = Current;
            if (IsHorizontal)
            {
                colView.ContentContainer.SizeWidth = ScrollContentSize;
            }
            else
            {
                colView.ContentContainer.SizeHeight = ScrollContentSize;
            }


            base.Initialize(view);
            //Console.WriteLine("[NUI] Init Done, StepCnadidate{0}, Scroll{1}", StepCandidate, ScrollContentSize);
        }
Ejemplo n.º 2
0
        public override void Initialize(RecyclerView view)
        {
            colView = view as CollectionView;
            if (colView == null)
            {
                throw new ArgumentException("GridLayouter only can be applied CollectionView.", nameof(view));
            }

            // 1. Clean Up
            foreach (RecyclerViewItem item in VisibleItems)
            {
                colView.UnrealizeItem(item, false);
            }
            VisibleItems.Clear();
            groups.Clear();

            FirstVisible = 0;
            LastVisible  = 0;

            IsHorizontal = (colView.ScrollingDirection == ScrollableBase.Direction.Horizontal);

            RecyclerViewItem header = colView?.Header;
            RecyclerViewItem footer = colView?.Footer;
            float            width, height;
            int count = colView.InternalItemSource.Count;
            int pureCount = count - (header ? 1 : 0) - (footer ? 1 : 0);

            // 2. Get the header / footer and size deligated item and measure the size.
            if (header != null)
            {
                MeasureChild(colView, header);

                width = header.Layout != null?header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;

                height = header.Layout != null?header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;

                headerSize = IsHorizontal ? width : height;
                hasHeader  = true;

                colView.UnrealizeItem(header);
            }

            if (footer != null)
            {
                MeasureChild(colView, footer);

                width = footer.Layout != null?footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;

                height = footer.Layout != null?footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;

                footerSize   = IsHorizontal ? width : height;
                footer.Index = count - 1;
                hasFooter    = true;

                colView.UnrealizeItem(footer);
            }

            int firstIndex = header ? 1 : 0;

            if (colView.IsGrouped)
            {
                isGrouped = true;

                if (colView.GroupHeaderTemplate != null)
                {
                    while (!colView.InternalItemSource.IsGroupHeader(firstIndex))
                    {
                        firstIndex++;
                    }
                    //must be always true
                    if (colView.InternalItemSource.IsGroupHeader(firstIndex))
                    {
                        RecyclerViewItem groupHeader = colView.RealizeItem(firstIndex);
                        firstIndex++;

                        if (groupHeader == null)
                        {
                            throw new Exception("[" + firstIndex + "] Group Header failed to realize!");
                        }

                        // Need to Set proper hieght or width on scroll direciton.
                        if (groupHeader.Layout == null)
                        {
                            width  = groupHeader.WidthSpecification;
                            height = groupHeader.HeightSpecification;
                        }
                        else
                        {
                            MeasureChild(colView, groupHeader);

                            width  = groupHeader.Layout.MeasuredWidth.Size.AsRoundedValue();
                            height = groupHeader.Layout.MeasuredHeight.Size.AsRoundedValue();
                        }
                        //Console.WriteLine("[NUI] GroupHeader Size {0} :{0}", width, height);
                        // pick the StepCandidate.
                        groupHeaderSize = IsHorizontal ? width : height;
                        colView.UnrealizeItem(groupHeader);
                    }
                }
                else
                {
                    groupHeaderSize = 0F;
                }

                if (colView.GroupFooterTemplate != null)
                {
                    int firstFooter = firstIndex;
                    while (!colView.InternalItemSource.IsGroupFooter(firstFooter))
                    {
                        firstFooter++;
                    }
                    //must be always true
                    if (colView.InternalItemSource.IsGroupFooter(firstFooter))
                    {
                        RecyclerViewItem groupFooter = colView.RealizeItem(firstFooter);

                        if (groupFooter == null)
                        {
                            throw new Exception("[" + firstFooter + "] Group Footer failed to realize!");
                        }
                        // Need to Set proper hieght or width on scroll direciton.
                        if (groupFooter.Layout == null)
                        {
                            width  = groupFooter.WidthSpecification;
                            height = groupFooter.HeightSpecification;
                        }
                        else
                        {
                            MeasureChild(colView, groupFooter);

                            width  = groupFooter.Layout.MeasuredWidth.Size.AsRoundedValue();
                            height = groupFooter.Layout.MeasuredHeight.Size.AsRoundedValue();
                        }
                        // pick the StepCandidate.
                        groupFooterSize = IsHorizontal ? width : height;

                        colView.UnrealizeItem(groupFooter);
                    }
                }
                else
                {
                    groupFooterSize = 0F;
                }
            }
            else
            {
                isGrouped = false;
            }

            bool failed = false;

            //Final Check of FirstIndex
            while (colView.InternalItemSource.IsHeader(firstIndex) ||
                   colView.InternalItemSource.IsGroupHeader(firstIndex) ||
                   colView.InternalItemSource.IsGroupFooter(firstIndex))
            {
                if (colView.InternalItemSource.IsFooter(firstIndex))
                {
                    StepCandidate = 0F;
                    failed        = true;
                    break;
                }
                firstIndex++;
            }

            sizeCandidate = new Size2D(0, 0);
            if (!failed)
            {
                // Get Size Deligate. FIXME if group exist index must be changed.
                RecyclerViewItem sizeDeligate = colView.RealizeItem(firstIndex);
                if (sizeDeligate == null)
                {
                    throw new Exception("Cannot create content from DatTemplate.");
                }
                sizeDeligate.BindingContext = colView.InternalItemSource.GetItem(firstIndex);

                // Need to Set proper hieght or width on scroll direciton.
                if (sizeDeligate.Layout == null)
                {
                    width  = sizeDeligate.WidthSpecification;
                    height = sizeDeligate.HeightSpecification;
                }
                else
                {
                    MeasureChild(colView, sizeDeligate);

                    width  = sizeDeligate.Layout.MeasuredWidth.Size.AsRoundedValue();
                    height = sizeDeligate.Layout.MeasuredHeight.Size.AsRoundedValue();
                }
                //Console.WriteLine("[NUI] item Size {0} :{1}", width, height);

                // pick the StepCandidate.
                StepCandidate = IsHorizontal ? width : height;
                spanSize      = IsHorizontal ? Convert.ToInt32(Math.Truncate((double)(colView.Size.Height / height))) :
                                Convert.ToInt32(Math.Truncate((double)(colView.Size.Width / width)));

                sizeCandidate = new Size2D(Convert.ToInt32(width), Convert.ToInt32(height));

                colView.UnrealizeItem(sizeDeligate);
            }

            if (StepCandidate < 1)
            {
                StepCandidate = 1;
            }
            if (spanSize < 1)
            {
                spanSize = 1;
            }

            if (isGrouped)
            {
                float Current = 0.0F;
                IGroupableItemSource source       = colView.InternalItemSource;
                GroupInfo            currentGroup = null;

                for (int i = 0; i < count; i++)
                {
                    if (i == 0 && hasHeader)
                    {
                        Current += headerSize;
                    }
                    else if (i == count - 1 && hasFooter)
                    {
                        Current += footerSize;
                    }
                    else
                    {
                        //GroupHeader must always exist in group usage.
                        if (source.IsGroupHeader(i))
                        {
                            currentGroup = new GroupInfo()
                            {
                                GroupParent   = source.GetGroupParent(i),
                                StartIndex    = i,
                                Count         = 1,
                                GroupSize     = groupHeaderSize,
                                GroupPosition = Current
                            };
                            groups.Add(currentGroup);
                            Current += groupHeaderSize;
                        }
                        //optional
                        else if (source.IsGroupFooter(i))
                        {
                            //currentGroup.hasFooter = true;
                            currentGroup.Count++;
                            currentGroup.GroupSize += groupFooterSize;
                            Current += groupFooterSize;
                        }
                        else
                        {
                            currentGroup.Count++;
                            int index = i - currentGroup.StartIndex - 1; // groupHeader must always exist.
                            if ((index % spanSize) == 0)
                            {
                                currentGroup.GroupSize += StepCandidate;
                                Current += StepCandidate;
                            }
                        }
                    }
                }
                ScrollContentSize = Current;
            }
            else
            {
                // 3. Measure the scroller content size.
                ScrollContentSize = StepCandidate * Convert.ToInt32(Math.Ceiling((double)pureCount / (double)spanSize));
                if (hasHeader)
                {
                    ScrollContentSize += headerSize;
                }
                if (hasFooter)
                {
                    ScrollContentSize += footerSize;
                }
            }

            if (IsHorizontal)
            {
                colView.ContentContainer.SizeWidth = ScrollContentSize;
            }
            else
            {
                colView.ContentContainer.SizeHeight = ScrollContentSize;
            }

            base.Initialize(colView);
            //Console.WriteLine("Init Done, StepCnadidate{0}, spanSize{1}, Scroll{2}", StepCandidate, spanSize, ScrollContentSize);
        }