Xamarin.Forms 仿照京东搜索记录控件

Xamarin.Forms 仿照京东搜索记录控件

在项目中遇到这样一个需求,仿照京东搜索记录。在Xamarin.Forms中有什么控件可以实现呢?

首先,来分析这个控件的特点:

  1. 数据量不大
  2. 每条记录字数长度不一,使得每条记录呈现的样式长度不一

经过如上分析,由于数据量不大,且界面样式并不是整齐划一,所以用不着使用ListView,查看官方文档后,发现FlexLayout即可满足我们的需求。

FlexLayout这个控件的详细说明可以看微软的官方文档。

这里主要利用了FlexLayout的一些相关特性:

  1. AlignContent
  2. AlignItems
  3. JustifyContent
  4. Wrap

demo如下代码所示:


    public class FlowLayout: StackLayout
    {
        private FlexLayout _flexLayout;
        public Action<int, object> ItemTapped;


        public FlowLayout()
        {
            _flexLayout = new FlexLayout
            {
                AlignContent = FlexAlignContent.Start,
                AlignItems = FlexAlignItems.Start,
                JustifyContent = FlexJustify.Start,
                Wrap = FlexWrap.Wrap,
            };
            this.Children.Add(_flexLayout);
        }

        #region BindableProperty

        public static readonly BindableProperty ItemsSourceProperty =
        BindableProperty.Create(nameof(ItemsSource), typeof(IList), typeof(FlowLayout), default(IList),propertyChanged: ItemsSourcePropertyChanged);

        private static void ItemsSourcePropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            if (bindable is FlowLayout view)
            {
                view.UpdateViews();
            }
        }

        public IList ItemsSource
        {
            get { return (IList)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }
        #endregion

        public void UpdateViews()
        {
            _flexLayout.Children.Clear();
            foreach(var item in ItemsSource)
            {
                _flexLayout.Children.Add(CreateItem(item.ToString()));
            }
        }

        private StackLayout CreateItem(string content)
        {
            var label = new Label
            {
                Text = content,
                TextColor = Color.Black,
                Margin = new Thickness(10,6,10,6), FontSize = 12,
                MaxLines = 1,
                VerticalOptions = LayoutOptions.Center,
                HorizontalOptions = LayoutOptions.Center,
            };
            var stack = new StackLayout()
            {
                BackgroundColor = Color.LightGray,
                Margin = new Thickness(0,6,12,6),
            };
            stack.Children.Add(label);
            var tapGestureRecognizer = new TapGestureRecognizer();
            tapGestureRecognizer.Tapped += TapGestureRecognizer_Tapped;
            stack.GestureRecognizers.Add(tapGestureRecognizer);
            return stack;
        }

        private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
        {
            try
            {
                var index = _flexLayout.Children.IndexOf(sender as StackLayout);
                var o = ItemsSource[index];
                ItemTapped?.Invoke(index, o);
            }
            catch { }
        }
    }

效果图:

这样就基本实现了搜索记录。

posted @ 2019-03-17 18:51  Devin.Zhou  阅读(582)  评论(0编辑  收藏  举报