【问题标题】:Xamarin.forms: How to add image list inside ListviewXamarin.forms:如何在 Listview 中添加图像列表
【发布时间】:2017-11-29 05:56:17
【问题描述】:

我正在使用 Xamarin.Forms 有两个项目:AndroidIOS

我有一个Listview,我想在其中添加一个ImagesList Listview

我想按照下图设计用户界面

请帮忙。

【问题讨论】:

  • 列表视图中的图像列表是否可滚动?
  • 是的,它是可滚动的
  • @KirtiZare 您可以使用 FlowListView 来归档该设计。

标签: listview xamarin xamarin.forms xamarin.android


【解决方案1】:

如果你可以使用 customlistView 渲染器,你可以根据给定的图像设计 UI

Xamarin.core NativeListView 渲染器

namespace My.Renderer
{
 public class NativeListView : ListView
    {
        public static readonly BindableProperty ItemsProperty =
            BindableProperty.Create("Items", typeof(IEnumerable<DataSource>), typeof(NativeListView), new List<DataSource>());

        public IEnumerable<DataSource> Items
        {
            get { return (IEnumerable<DataSource>)GetValue(ItemsProperty); }
            set { SetValue(ItemsProperty, value); }
        }

        public event EventHandler<SelectedItemChangedEventArgs> ItemSelected;

        public void NotifyItemSelected(object item)
        {
            if (ItemSelected != null)
            {
                ItemSelected(this, new SelectedItemChangedEventArgs(item));
            }
        }
    }

安卓渲染器

[assembly: ExportRenderer(typeof(NativeListView), typeof(NativeAndroidListViewRenderer))] namespace My.Droid.CustomRenderer { public class NativeAndroidListViewRenderer : ListViewRenderer { protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // unsubscribe
            Control.ItemClick -= OnItemClick;
        }

        if (e.NewElement != null)
        {
            // subscribe
            Control.Adapter = new NativeAndroidListViewAdapter(Forms.Context as Android.App.Activity, e.NewElement as NativeListView);
            Control.ItemClick += OnItemClick;
        }
    }

    protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName == NativeListView.ItemsProperty.PropertyName)
        {
            Control.Adapter = new NativeAndroidListViewAdapter(Forms.Context as Android.App.Activity, Element as NativeListView);
        }
    }

    void OnItemClick(object sender, Android.Widget.AdapterView.ItemClickEventArgs e)
    {
        ((NativeListView)Element).NotifyItemSelected(((NativeListView)Element).Items.ToList()[e.Position - 1]);
    }
} 
 adapter Class for android
    namespace My.Droid.CustomRenderer
{
    public class NativeAndroidListViewAdapter : BaseAdapter<DataSource>
    {
        readonly Activity context;
        IList<DataSource> tableItems = new List<DataSource>();

        public IEnumerable<DataSource> Items
        {
            set
            {
                tableItems = value.ToList();
            }
        }

        public NativeAndroidListViewAdapter(Activity context, NativeListView view)
        {
            this.context = context;
            tableItems = view.Items.ToList();
        }

        public override DataSource this[int position]
        {
            get
            {
                return tableItems[position];
            }
        }

        public override long GetItemId(int position)
        {
            return position;
        }

        public override int Count
        {
            get { return tableItems.Count; }
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            var item = tableItems[position];

            var view = convertView;
            if (view == null)
            {
                // no view to re-use, create new
                view = context.LayoutInflater.Inflate(Resource.Layout.NativeAndroidListViewCell, null);
            }
            view.FindViewById<TextView>(Resource.Id.textView1).Text = item._subject;
            view.FindViewById<TextView>(Resource.Id.textView2).Text = item._date;
            view.FindViewById<TextView>(Resource.Id.textView3).Text = item._priority;
            view.FindViewById<TextView>(Resource.Id.textView4).Text = Html.FromHtml(item._description).ToString();
            view.FindViewById<TextView>(Resource.Id.textView5).Text = item._category;

            return view;
        }
    }
} 

ios 渲染器

      [assembly: ExportRenderer(typeof(NativeListView), typeof(NativeiOSListViewRenderer))]
namespace My.iOS.CustomRenderer
{
    public class NativeiOSListViewRenderer : ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                // Unsubscribe
            }

            if (e.NewElement != null)
            {
                Control.Source = new NativeiOSListViewSource(e.NewElement as NativeListView);
            }
        }

        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == NativeListView.ItemsProperty.PropertyName)
            {
                Control.Source = new NativeiOSListViewSource(Element as NativeListView);
            }
        }
    }
}
ViewSource for ios
    namespace My.iOS.CustomRenderer
{
    public class NativeiOSListViewSource : UITableViewSource
    {
        // declare vars
        IList<DataSource> tableItems;
        NativeListView listView;
        readonly NSString cellIdentifier = new NSString("TableCell");

        public IEnumerable<DataSource> Items
        {
            //get{ }
            set
            {
                tableItems = value.ToList();
            }
        }

        public NativeiOSListViewSource(NativeListView view)
        {
            tableItems = view.Items.ToList();
            listView = view;
        }

        /// <summary>
        /// Called by the TableView to determine how many cells to create for that particular section.
        /// </summary>
        public override nint RowsInSection(UITableView tableview, nint section)
        {
            return tableItems.Count;
        }

        #region user interaction methods

        public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
        {
            listView.NotifyItemSelected(tableItems[indexPath.Row]);
            Console.WriteLine("Row " + indexPath.Row.ToString() + " selected");
            tableView.DeselectRow(indexPath, true);
        }

        public override void RowDeselected(UITableView tableView, NSIndexPath indexPath)
        {
            Console.WriteLine("Row " + indexPath.Row.ToString() + " deselected");
        }

        #endregion

        /// <summary>
        /// Called by the TableView to get the actual UITableViewCell to render for the particular section and row
        /// </summary>
        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {
            // request a recycled cell to save memory
            NativeiOSListViewCell cell = tableView.DequeueReusableCell(cellIdentifier) as NativeiOSListViewCell;

            // if there are no cells to reuse, create a new one
            if (cell == null)
            {
                cell = new NativeiOSListViewCell(cellIdentifier);
            }

            cell.UpdateCell(tableItems[indexPath.Row]._sender, tableItems[indexPath.Row]._date);

            return cell;
        }
    }
}
  ViewCell for ios
     namespace My.iOS.CustomRenderer
{
    public class NativeiOSListViewCell : UITableViewCell
    {

        UILabel headingLabel, subheadingLabel;

        public NativeiOSListViewCell(NSString cellId) : base(UITableViewCellStyle.Default, cellId)
        {
            SelectionStyle = UITableViewCellSelectionStyle.Gray;

            this.ContentView.BackgroundColor = UIColor.FromRGB(255, 255, 255);
            this.ContentView.Layer.BorderWidth = 0.0f;
            this.ContentView.Layer.CornerRadius = 7.0f;
            this.ContentView.Layer.BorderColor = UIColor.White.CGColor;

            headingLabel = new UILabel()
            {
                Font = UIFont.FromName("Cochin-BoldItalic", 22f),
                TextColor = UIColor.FromRGB(53, 53, 53),
                BackgroundColor = UIColor.Clear
            };

            subheadingLabel = new UILabel()
            {
                Font = UIFont.FromName("AmericanTypewriter", 12f),
                TextColor = UIColor.FromRGB(53, 53, 53),
                TextAlignment = UITextAlignment.Center,
                BackgroundColor = UIColor.Clear
            };

            ContentView.Add(headingLabel);
            ContentView.Add(subheadingLabel);
        }

        public void UpdateCell(string caption, string subtitle)
        {
            headingLabel.Text = caption;
            subheadingLabel.Text = subtitle;
        }

        public override void LayoutSubviews()
        {
            base.LayoutSubviews();

            headingLabel.Frame = new CoreGraphics.CGRect(5, 4, ContentView.Bounds.Width - 63, 25);
            subheadingLabel.Frame = new CoreGraphics.CGRect(100, 18, 100, 20);
        }
    }
}

【讨论】:

  • 这个过程太长了。我们可以在 contentview 中动态地进行图像控制吗?例如。我在 contentview 中设计 listview.datatemplate 那么是否可以在 contentview 中动态添加图像控件?
  • stack layout 和 imageurl 数组的自定义属性创建自定义 View,并根据 customView 中的数组计数添加 circularImageView。
  • 你是如何在 xamarin 表单中的标签栏上制作中心按钮的?
猜你喜欢
  • 2014-09-09
  • 1970-01-01
  • 2018-12-23
  • 2011-01-13
  • 2019-07-13
  • 2011-04-07
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
相关资源
最近更新 更多