问题描述
当滚动视图到达末尾或顶部时,我需要加载更多数据。我在这里找到了相同的 thread,但在那上面,我不明白什么是 MyScrollView
。
private void OnScrolled(object sender,ScrolledEventArgs e)
{
MyScrollView scrollView = sender as MyScrollView;
double scrollingSpace = scrollView.ContentSize.Height - scrollView.Height;
if (scrollingSpace <= e.ScrollY)
{
//reached end
}
}
我在 ListView
中使用 ItemAppearing
事件实现了相同的功能。但目前,我在 UI 上使用 Expander
来显示数据。扩展器到达终点和起点是否存在相同类型的事件?扩展器位于滚动视图内部,这就是我开始研究滚动视图结束事件的原因。
如何在滚动视图到达结束或开始时触发某种事件?
更新
我的滚动视图内容如下,它包含 BindableLayout
和 Expander
。
<ScrollView
x:Name="MyScrollView"
Scrolled="OnScrolled">
<StackLayout BindableLayout.ItemsSource="{Binding AllItems,Mode=TwoWay}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Expander>
</Expander>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
解决方法
MyScrollView 可能是使用 ScrollView 的自定义视图。这是我使用 Listview 的示例代码。您也可以将其应用于您的自定义滚动视图。
CustomListview.cs
public class CustomListView : ListView
{
public CustomListView()
{
}
}
iOS
[assembly: ExportRenderer(typeof(CustomListView),typeof(CustomListViewRenderer))]
namespace YOUR_PROJECT_NAME.iOS.Renderers
{
public class CustomListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if (Element != null)
{
Control.AlwaysBounceVertical = Element.IsPullToRefreshEnabled;
Control.Bounces = Element.IsPullToRefreshEnabled;
}
}
protected override void OnElementPropertyChanged(object sender,PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender,e);
if (e.PropertyName == nameof(Element.IsPullToRefreshEnabled))
{
Control.AlwaysBounceVertical = Element.IsPullToRefreshEnabled;
Control.Bounces = Element.IsPullToRefreshEnabled;
}
}
}
}
安卓
No custom renderer is needed
XML
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0"
x:Name="DashboardBarGrid"
BackgroundColor="#263A43"
RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid Grid.Row="0"
HorizontalOptions="CenterAndExpand" VerticalOptions="Center">
<Label Text="Title" TextColor="White"/>
</Grid>
</Grid>
<controls:CustomListView Grid.Row="1" ItemsSource="{Binding Items}" Scrolled="listView_Scrolled" IsPullToRefreshEnabled="False"/>
</Grid>
页面.cs
...
private Animation _lastRowAnimation;
private readonly double _initialLastRowHeight;
private readonly RowDefinition _lastRowDefinition;
private bool _isScrolled;
private bool _isFirstRun;
public List<string> Items { get; set; } = new List<string>();
...
public MyPage()
{
InitializeComponent();
_lastRowDefinition = DashboardBarGrid.RowDefinitions[0];
_initialLastRowHeight = _lastRowDefinition.Height.Value;
_isFirstRun = true;
Items.Add("A");
Items.Add("B");
Items.Add("C");
...
Items.Add("Z");
BindingContext = this;
}
...
private void listView_Scrolled(object sender,ScrolledEventArgs e)
{
var listView = (ListView)sender;
if (e.ScrollY > 50) _isFirstRun = false;
if (_isScrolled && e.ScrollY == 0 && _lastRowDefinition?.Height.Value < _initialLastRowHeight){
listView.IsEnabled = false;
_lastRowAnimation = new Animation((d) => _lastRowDefinition.Height = new GridLength(d.Clamp(50,double.MaxValue)),_lastRowDefinition.Height.Value,_initialLastRowHeight,Easing.Linear,() => _lastRowAnimation = null);
_lastRowAnimation.Commit(this,"Animation",16,500,(v,c) =>
{
_isScrolled = false;
listView.IsEnabled = true;
});
}
// Hide the rows
else if (!_isScrolled && _lastRowDefinition?.Height.Value >=
_initialLastRowHeight && !_isFirstRun)
{
listView.IsEnabled = false;
_lastRowAnimation = new Animation((d) => _lastRowDefinition.Height = new GridLength(d.Clamp(0,c) => {
_isScrolled = true;
listView.IsEnabled = true;
});
}
}
,
您的原始代码在正确的轨道上。前段时间我花了一些时间才让它工作,但这是我使用的代码。它比 MyScrollView 类简单得多。
private void TheScrollView_Scrolled(object sender,ScrolledEventArgs e)
{
if (TheScrollView.ScrollY >= TheScrollView.ContentSize.Height - TheScrollView.Height)
{
//All the way to the bottom.
}
else if (TheScrollView.ScrollX <= 0)
{
//All the way to the top.
}
else
{
//Neither all the way to the top nor to the right.
}
}
,
就像我在问题中提到的那样,我使用 ListView
事件在 ItemAppearing
中实现了相同的功能。但在这种情况下,我的数据是另一个列表中的项目列表。这就是我强制使用 Expander
组件在 UI 上显示数据的原因。
同时,当 Expander
底部到达时,我需要加载更多项目。但 Expander
不提供相关事件,因为它不是可滚动控件。所以我试图找出 ScrollView
组件的事件。但也没有运气。
最后,我决定将数据从另一个列表中的列表更改为单个列表。我已经使用一些 for 循环对其进行了转换,现在数据适用于 ListView
。我已经使用 ItemAppearing
事件实现了加载更多功能。
谢谢