c# - Xamarin Forms ListView 程序刷新在页面加载时不会在 Android 上停止

标签 c# android visual-studio-2015 xamarin.forms pull-to-refresh

我在 Visual Studio 2015 中有一个带有 ListView 的 Portable 项目,它通过以下函数 refreshData 通过 API 调用填充了一些数据:

async Task refreshData()
{
    myListView.BeginRefresh();
    var apiCallResult = await App.Api.myApiGetCall();            
    myListView.ItemsSource = apiCallResult;
    myListView.EndRefresh();    
}

refreshData() 被调用

protected override void OnAppearing()
{
    base.OnAppearing();
    refreshData();
}

一切正常,除了在 Android 上,刷新指示器在初始加载页面时不会在 EndRefresh() 上停止或消失。该页面位于 TabbedPage 中,因此我可以转到不同的选项卡,然后返回到该页面,并且刷新指示器会在我的 API 调用完成时正常启动和停止。

为什么在 Android 上最初加载页面时刷新没有停止?任何帮助将不胜感激。

注意:当我在 iOS 上运行时,这工作得很好。

到目前为止我已经尝试过:

  1. myListView.BeginRefresh() 替换为 myListView.IsRefreshing = true 并将 myListView.EndRefresh() 替换为 myListView .IsRefreshing = false

  2. 使用 Device.BeginInvokeOnMainThread(() => {//更新列表和 endRefresh})

  3. 使用 async void refreshData() 而不是 async Task refreshData()

最佳答案

就个人而言,当我在 Page Contructor 中启动 ListView 刷新并在加载数据后停止它时,我会遇到这个问题。有时(经常)Xamarin.Forms ListView 不会取消刷新动画。

我相信您在使用 Android SwipeRefreshLayout 时遇到了一个相当普遍的问题:它可能不会在 setRefreshing(false) 调用后停止刷新动画。 native Android 开发人员使用以下方法:

swipeRefreshLayout.post(new Runnable() {
    @Override
        public void run() {
            mSwipeRefreshLayout.setRefreshing(refreshing);
    }
});

有趣的是,Xamarin.Forms 在设置初始刷新状态 (code) 时使用了这种方法;然而,这还不够。您需要一个自定义渲染器:

public class ExtendedListViewRenderer : ListViewRenderer
{
    /// <summary>
    /// The refresh layout that wraps the native ListView.
    /// </summary>
    private SwipeRefreshLayout _refreshLayout;

    public ExtendedListViewRenderer(Android.Content.Context context) : base(context)
    {
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _refreshLayout = null;
        }
        base.Dispose(disposing);
    }

    protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
    {
        base.OnElementChanged(e);
        _refreshLayout = (SwipeRefreshLayout)Control.Parent;
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == ListView.IsRefreshingProperty.PropertyName)
        {
            // Do not call base method: we are handling it manually
            UpdateIsRefreshing();
            return;
        }
        base.OnElementPropertyChanged(sender, e);
    }

    /// <summary>
    /// Updates SwipeRefreshLayout animation status depending on the IsRefreshing Element 
    /// property.
    /// </summary>
    protected void UpdateIsRefreshing()
    {
        // I'm afraid this method can be called after the ListViewRenderer is disposed
        // So let's create a new reference to the SwipeRefreshLayout instance
        SwipeRefreshLayout refreshLayoutInstance = _refreshLayout;

        if (refreshLayoutInstance == null)
        {
            return;
        }

        bool isRefreshing = Element.IsRefreshing;
        refreshLayoutInstance.Post(() =>
        {
            refreshLayoutInstance.Refreshing = isRefreshing;
        });
    }
}

关于c# - Xamarin Forms ListView 程序刷新在页面加载时不会在 Android 上停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42165245/

相关文章:

c# - 为什么 httpRuntime targetFramework ="4.5"禁用抓取 .ASPXAUTH cookie?

java - 在相对布局中将宽度和高度设置为百分比

javascript - Task Runner 中的意外 token 错误

visual-studio - Visual C++ Update 2 运行时在哪里

c# - 返回否定 bool 时的 "Cast is redundant"警告

c# - 如何使用 Action 过滤器在 asp.net mvc 中集中模型状态验证?

c# - roslyn 编译器未使用 msbuild 复制到 AspnetCompileMerge 文件夹

c# - 依赖注入(inject)AddSingleton实例化多次

android - Android应用程序和网络服务之间的身份验证+ facebook登录

android - 单击 EditText 打开 DatePickerDialog 需要两次单击