微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Xamarin.iOS CollectionView - 添加新元素会导致刷新整个列表

如何解决Xamarin.iOS CollectionView - 添加新元素会导致刷新整个列表

我正在构建一个 xamarin.forms 聊天应用程序,只需要添加交付的新元素,在 Android 上我有预期的行为,但 iOS 刷新了所有 CollectionView,这会导致糟糕的用户体验。请查看我的代码(仅相关部分),让我知道我做错了什么,或者我错过了什么在 iOS 上也有这种行为。

我的 .xaml:

<CollectionView x:Name="ChatCollectionView" 
    SelectionMode="None" HorizontalScrollBarVisibility="Never" 
    VerticalScrollBarVisibility="Always" ItemsUpdatingScrollMode="KeepLastItemInView"
    ItemTemplate="{StaticResource MsgTemplateSelector}" Margin="5,5,10">
</CollectionView>

.cs 文件


public static readerwriterlockslim valuesLock = new readerwriterlockslim();
void ObservableCollectionCallback(IEnumerable collection,object context,Action accessMethod,bool writeAccess)
{
    var collectionLock = (readerwriterlockslim)context;
    Action enterLock = writeAccess ? new Action(collectionLock.EnterWriteLock) : new Action(collectionLock.EnterReadLock);
    Action exitLock = writeAccess ? new Action(collectionLock.ExitWriteLock) : new Action(collectionLock.ExitReadLock);

    enterLock();
    try { accessMethod(); } finally { exitLock(); }
}

ObservableCollection<Msg> ListMsg;

public Page(string userid,string chatkey,string titulo,string foto)
{
    // some code ...
    this.BindingContext = this;
    BindingBase.EnableCollectionSynchronization(ListMsg as IEnumerable,valuesLock,ObservableCollectionCallback);

    List<Msg> recipient = await Task.Run(()=> client.PostData<List<Msg>>("url/msg.PHP")); 
    //prevIoUs line returns a json and deserialize it to a list of "Msg"

    if (recipient != null)
    {
        ListMsg = new ObservableCollection<Msg>(recipient);
        
        ChatCollectionView.ItemsSource = ListMsg;
            
        if (ListMsg.Count > 0)
        {
            if(Device.RuntimePlatform==Device.iOS)
                await Task.Delay(2000);

            ChatCollectionView.ScrollTo(ListMsg.Count - 1,position: ScrollToPosition.End,animate: false);
        }
    }
    else
        ChatCollectionView.ItemsSource = new ObservableCollection<Msg>(); 

    MessagingCenter.Subscribe<MainPage,Msg>("Page","scroll",async (sender,arg) =>
    {
        Task.WaitAll(tasks.ToArray());

        tasks.Add(Task.Run(async () =>
        {
            arg = await MsgPrepare(arg); //this only changes the element arg not the list
            _ = Device.InvokeOnMainThreadAsync(() =>
            {
                valuesLock.EnterWriteLock();
                try { ListMsg.Add(arg); }
                finally { valuesLock.ExitWriteLock(); }
            });
        }));
    }

}





解决方法

通过“错误”修复它。我添加了整个页面来解决 iOS 软键盘(覆盖焦点 Entry 元素)和宾果游戏的问题,它已经解决了这两个问题。如果我取下 ScrollView,问题又回来了。我还注意到,如果 ScrollView 只包含 CollectionView,它就可以工作,它不需要像我一样包含整个页面。另一点是如果您不想要 ScrollView 的滚动功能,您可以设置 Orientation=Neither 来避免它。希望这对你们有帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。