简体   繁体   English

如何将从相机拍摄的图像添加到列表视图? Xamarin 表单

[英]How to add images taken from camera to a Listview? Xamarin Forms

I would like to add images to a Listview in Xamarin Forms?(or other layout) after each image is taken by the camera, something similar to the image above.在相机拍摄每张图像后,我想将图像添加到 Xamarin Forms 中的 Listview?(或其他布局),类似于上图。 How would I approach this?我将如何处理这个问题? 有点像这张照片

I used https://github.com/jamesmontemagno/MediaPlugin example for taking/picking photos, but unsure on how to add them to the Listview or other layout in Xamarin Forms我使用https://github.com/jamesmontemagno/MediaPlugin示例拍摄/挑选照片,但不确定如何将它们添加到 Xamarin Forms 中的 Listview 或其他布局

You'll need to hack the crap out of this to make it work and look exactly how you want, but this does work.您需要解决这个问题以使其正常工作并看起来完全符合您的要求,但这确实有效。 Refactor to MVVM, add bindings where required and be sure to change any and all aspects that don't work for you.重构为 MVVM,在需要时添加绑定,并确保更改对您不起作用的任何和所有方面。

I've tested on iOS but not Android.我在 iOS 上测试过,但没有在 Android 上测试过。 Given it's Forms, the only thing you should need to do is what you've already done and that's initialise the Media plugin.鉴于它是 Forms,你唯一需要做的就是你已经完成的事情,那就是初始化 Media 插件。

Given it's quite dynamic, all of the visual work has been done in the view (code behind).鉴于它非常动态,所有的视觉工作都在视图中完成(代码隐藏)。

XAML XAML

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="PlaypenApp.ImageGridPage">

    <ScrollView VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
        <Grid x:Name="ImageGridContainer" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Padding="5">
            <Grid.RowDefinitions>
                <RowDefinition Height="1" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>            
        </Grid>        
    </ScrollView>    
</ContentPage>

C# (Code Behind) C#(代码隐藏)

using System;
using System.Threading.Tasks;

using Xamarin.Forms;

using Plugin.Media;
using Plugin.Media.Abstractions;
using Plugin.Permissions;
using Plugin.Permissions.Abstractions;

namespace PlaypenApp
{
    public partial class ImageGridPage : ContentPage
    {
        private const int MaxColumns = 3;

        private double _rowHeight = 0;
        private int _currentRow = 0;
        private int _currentColumn = 0;

        public ImageGridPage()
        {
            InitializeComponent();

            Device.BeginInvokeOnMainThread(async () => await InitialiseMediaPermissions());

            var addPhotoButton = new Button()
            {
                Text = "Add Photo",
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                BorderColor = Color.FromHex("#F0F0F0"),
                BorderWidth = 1,
                BackgroundColor = Color.FromHex("#F9F9F9"),
                TextColor = Color.Black,
                FontAttributes = FontAttributes.Bold
            };

            addPhotoButton.Clicked += async (object sender, EventArgs e) => await AddPhoto();

            ImageGridContainer.Children.Add(addPhotoButton, 0, 0);

            Device.BeginInvokeOnMainThread(async () =>
            {
                // Wait for a small amount of time so the UI has a chance to update the relevant values
                // we need to complete the operation.
                await Task.Delay(10);

                // Set the row height to be the same as the column width so that the image 
                // is presented in a square grid.
                _rowHeight = addPhotoButton.Width;
                ImageGridContainer.RowDefinitions[0].Height = _rowHeight;

                await ImageGridContainer.FadeTo(1);
            });
        }

        async Task AddPhoto()
        {
            MediaFile file = null;

            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
            {
                await DisplayAlert("No Camera", "You need to fix the problem of camera availability", "OK");
                return;
            }

            var imageSource = await DisplayActionSheet("Image Source", "Cancel", null, new string[] { "Camera", "Photo Gallery" });
            var photoName = Guid.NewGuid().ToString() + ".jpg";

            switch (imageSource)
            {
                case "Camera":
                    file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
                    {
                        Directory = "Sample",
                        Name = photoName
                    });

                    break;

                case "Photo Gallery":
                    file = await CrossMedia.Current.PickPhotoAsync();

                    break;

                default:
                    break;
            }

            if (file == null)
                return;

            // We have the photo, now add it to the grid.
            _currentColumn++;

            if (_currentColumn > MaxColumns - 1)
            {
                _currentColumn = 0;
                _currentRow++;

                // Add a new row definition by copying the first row.
                ImageGridContainer.RowDefinitions.Add(ImageGridContainer.RowDefinitions[0]);
            }

            var newImage = new Image()
            {
                Source = ImageSource.FromFile(file.Path),
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                Aspect = Aspect.AspectFill,
                Scale = 0
            };

            ImageGridContainer.Children.Add(newImage, _currentColumn, _currentRow);

            await Task.Delay(250);

            await newImage.ScaleTo(1, 250, Easing.SpringOut);
        }

        async Task InitialiseMediaPermissions()
        {
            var cameraStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Camera);
            var storageStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);

            if (cameraStatus != PermissionStatus.Granted || storageStatus != PermissionStatus.Granted)
            {
                var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Camera, Permission.Storage });
                cameraStatus = results[Permission.Camera];
                storageStatus = results[Permission.Storage];
            }
        }
    }
}

... I'm essentially just adding rows dynamically to the grid as I need to. ...我基本上只是根据需要将行动态添加到网格中。

I hope that helps you anyway.无论如何,我希望这对你有帮助。

Let me know how you go.让我知道你怎么去。

从 Xamarin Forms 3.0 开始,这可以使用 Flexlayout 实现

在此处输入图片说明

Just a quick snapshot of what Brad code look like.只是 Brad 代码外观的快速快照。

//if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
//{
//    await DisplayAlert("No Camera", "You need to fix the problem of camera availability", "OK");
//    return;
//}

if (!CrossMedia.Current.IsPickPhotoSupported)
{
    DisplayAlert("Photos Not Supported", ":( Permission not granted to photos.", "OK");
    return;
}

Change the validation check to IsPickPhotoSupported if anyone is running it on the Emulator as Camera control does not work on Emulator ( or is it just me?).如果有人在模拟器上运行它,则将验证检查更改为 IsPickPhotoSupported,因为 Camera 控件在模拟器上不起作用(或者只是我?)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM