Xamarin - привязать видимость ActivityIndicator к asyn c Задача выполнена - PullRequest
0 голосов
/ 23 марта 2020

Я загружаю изображения asyn c в свой Listview в соответствии с этим ответом: Xamarin - Асинхронное связывание данных

Я хочу отображать ActivityIndicator во время загрузки страницы данные из Интернета, но не могу понять, как связать их видимость с задачей, чтобы они исчезли, когда задача будет завершена, загрузка ..

Я создал переменную isLoading bool в моей ViewModel.

Я пытался сделать это таким же образом в моей ViewModel, но это не работает:

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

        isLoading = false;

Я также пытался установить его в Задаче, но isLoading всегда ложно ..

 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;
    }

my 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>

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;
    }

}
}

galleryservice:

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
    }
}

1 Ответ

1 голос
/ 23 марта 2020

Вы можете использовать ActivityIndicator вот так

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

Использовать свойство IsRunning со свойством IsBusy

    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;
        }
    }
...