Xamarin-将ActivityIndi​​cator可见性绑定到异步任务已完成 [英] Xamarin - Bind ActivityIndicator visibility to async Task finished

查看:90
本文介绍了Xamarin-将ActivityIndi​​cator可见性绑定到异步任务已完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在根据以下答案将图像异步加载到我的Listview中: Xamarin-异步数据绑定

I'm loading images async into my Listview according to this answer: Xamarin - Asynchronous data binding

我想在页面从网络加载数据时显示一个ActivityIndi​​cator,但无法弄清楚如何绑定它的可视性

I'd like to display a ActivityIndicator while the page is loading the data from the web, but cannot figure out how to bind the visibility it to the task, so that it disappears when the task is done loading..

我已经在ViewModel中创建了isLoading bool变量。

I've created a isLoading bool variable in my ViewModel.

我在ViewModel中以这种方式尝试过,但是它不起作用:

I tried it this way in my ViewModel, but It's not working:

        isLoading = true;
        GetImagesCommand = new Command(async () => await DoGetImagesCommand(pCode, gCode, gUrl));

        isLoading = false;

我也尝试在Task中进行设置,但是isLoading始终为false。.

I also tried setting it in the Task, but isLoading is always false..

 private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl)
    {
        isLoading = true;
        var images = await _galleryService.GetImageList(pCode, gCode, gUrl);
        foreach (var image in images)
            Galleries.Add(image);
        isLoading = false;
    }

我的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"
         xmlns:vm="clr-namespace:GalShare.ViewModel"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" xmlns:forms="clr-namespace:RedCorners.Forms;assembly=RedCorners.Forms"
         mc:Ignorable="d"
         x:Class="GalShare.Views.Gallery">

<ContentPage.Content>
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <StackLayout
             AbsoluteLayout.LayoutFlags="All"
             AbsoluteLayout.LayoutBounds="0,0,1,1">
            <CollectionView ItemsSource="{Binding Galleries}" x:Name="MyCollection" SelectionMode="Single" SelectionChanged="CollectionView_SelectionChanged">
                <CollectionView.ItemsLayout>
                    <GridItemsLayout Orientation="Vertical"                                 
                            Span="2" />

                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <ContentView Padding="1">
                            <forms:Frame2 CornerRadius="15"  
                                   HasShadow="True"
                                   ShadowRadius="8"                               
                                   Padding="0">
                                <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="LightGray" Padding="2">
                                    <ffimageloading:CachedImage x:Name="myImage" Source="{Binding ThumbUrl}" Aspect="AspectFit" CacheDuration="0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" DownsampleToViewSize="False"></ffimageloading:CachedImage>
                                    <Label x:Name="Picname" Text="{Binding ImageName}" IsVisible="{Binding showName}" VerticalOptions="StartAndExpand" VerticalTextAlignment="Center" HorizontalTextAlignment="Center" ></Label>
                                </StackLayout>
                            </forms:Frame2>
                        </ContentView>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </StackLayout>
        <StackLayout IsVisible="{Binding isLoading}" x:Name="LoadingLayout" Padding="12"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">
            <ActivityIndicator  />
            <Label Text="Loading gallery..." HorizontalOptions="Center" TextColor="Black"/>
        </StackLayout>
    </AbsoluteLayout>

</ContentPage.Content>

我的ViewModel:

my ViewModel:

namespace GalShare.ViewModel
{
class GalleryViewModel
{
    public string pCode { get; set; }
    public string gCode { get; set; }
    public string gUrl { get; set; }
    public bool isLoading { get; set; }
    public bool showname { get; set; }
    public ObservableCollection<picdata> Galleries { get; } = new ObservableCollection<picdata>();

    public ICommand GetImagesCommand { get; }
    private GalleryService _galleryService;

    public GalleryViewModel(string pCode, string gCode, string gUrl, string showName)
    {
        this.pCode = pCode;
        this.gCode = gCode;
        this.gUrl = gUrl;


        _galleryService = new GalleryService();



        GetImagesCommand = new Command(async () => DoGetImagesCommand(pCode, gCode, gUrl, showName));


    }

    private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl, string showName)
    {
        isLoading = true;
        var images = await _galleryService.GetImageList(pCode, gCode, gUrl, showName);
        foreach (var image in images)
            Galleries.Add(image);
        isLoading = false;
    }

}
}

图库服务:

class GalleryService
 {

    private HttpClient _httpClient;

    public GalleryService()
    {
        _httpClient = new HttpClient();
    }

    public async Task<IEnumerable<picdata>> GetImageList(string pCode, string gCode, string gUrl, string showName)
    {
        var response = await _httpClient.GetAsync(gUrl).ConfigureAwait(false);

        if (response.IsSuccessStatusCode)
        {
            var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

            //  var json = response.Content.GetStringAsync().ConfigureAwait(false);
            var deserialized = JsonConvert.DeserializeObject<JsonTxt>(json);

            bool shownametemp;
            if (showName == "1")
            {
                shownametemp = true;
            }
            else
            {
                shownametemp = false;
            }

            var images = new List<picdata>();
            foreach (var img in deserialized.Files)
            {
                images.Add(new picdata()
                {
                    ImageName = img.file,
                    BaseUrl = deserialized.Settings.Path.ToString(),
                    ThumbUrl = deserialized.Settings.Path.ToString() + "thumbs/" + img.file,
                    showname = shownametemp

                }) ;
            }

            return images;
        }

        return new picdata[0]; // return empty set
    }
}


推荐答案

您应该这样使用 ActivityIndi​​cator

<ActivityIndicator AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
                               AbsoluteLayout.LayoutFlags="All"
                               IsVisible="{Binding IsBusy}" 
                               IsRunning="{Binding IsBusy}" 
                               Color="{StaticResource PrimaryColor}"
                               VerticalOptions="Center"
                               HorizontalOptions="Center" />

对<$ c $使用 IsRunning 属性c> IsBusy 属性

Use IsRunning property with IsBusy property

    private bool _isBusy;

    public bool IsBusy
    {
        get
        {
            return _isBusy;
        }

        set
        {
            _isBusy = value;
            RaisePropertyChanged(() => IsBusy);
        }
    }

在视图模型中

  class GalleryViewModel : ExtendedBindableObject 
{
...
     private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl)
    {
        IsBusy = true;
        var images = await _galleryService.GetImageList(pCode, gCode, gUrl);
        foreach (var image in images)
            Galleries.Add(image);
        IsBusy = false;
    }
}

在另一个班级

public abstract class ExtendedBindableObject : BindableObject
    {
        public void RaisePropertyChanged<T>(Expression<Func<T>> property)
        {
            var name = GetMemberInfo(property).Name;
            OnPropertyChanged(name);
        }

        private MemberInfo GetMemberInfo(Expression expression)
        {
            MemberExpression operand;
            LambdaExpression lambdaExpression = (LambdaExpression)expression;
            if (lambdaExpression.Body is UnaryExpression)
            {
                UnaryExpression body = (UnaryExpression)lambdaExpression.Body;
                operand = (MemberExpression)body.Operand;
            }
            else
            {
                operand = (MemberExpression)lambdaExpression.Body;
            }
            return operand.Member;
        }
    }

这篇关于Xamarin-将ActivityIndi​​cator可见性绑定到异步任务已完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆