一.基础
二.进阶
1.使用ListView实现多选
Android原生的ListView
2.在添加Item或者移除Item的过程中
ChildAdded and DescendentAdded 这两种方式是不会触发的
ItemAppearing会被触发,但是sender是ListView
3.布局
我们知道ListView本身就是一个可滑动的控件,就像ScrollView类型,所以它的高度不由它的元素的总高度确定的(如果高度是和子元素的总高度一致,还有能滑动吗?),而是我们来手动确定一个高度的,所以当下面的这种情况出现时,就很尴尬了
<ScrollView> <StackLayout> <ListView> </ListView> </StackLayout> </ScrollView>
Forms的界面是有一个计算顺序的,先从子元素计算,然后来根据子元素的大小计算父容器的大小(固定父容器大小的情况不一样),此时ListView是有一个默认的高度的,当界面布局下渲染结束后ScrollView的ScrollHeight(ScrollView并没有这个属性,仅用作表示)是固定的,一般情况下,如果ScrollView里面的元素的高度发生变化,ScrollView的ScrollHeight是会发生变化的,但现在你会发现,如果改变ListView的ItemsSource,一切都没有变化
原因:ListView的子元素增加并不会引起ListView的高度的变化(因为可以滑动)
验证:
1.监听ListView的SizeChanged事件,发现并没有被触发
2.直接在ListView下面放一个元素来观察高度变化
由于ListView和ScrollView都是可滚动的控件,所以当ListView放在ScrollView就形成了手势冲突,此时只能滚动ScrollView,ListView就只能显示上面的残缺布局
解决方法:
1.将ListView设置一个足够的固定高度(最简单)(但最后会有一片空白)
2.重写手势,将在ListView控件的部分滑动的是ListView而不是ScrollView(很困难,特别是Forms,要在两个平台单独写代码)
3.不使用ListView,直接使用StackLayout,手动的添加/移除 Item,此时StackLayout的Size会发生变化,也会引起ScrollView的大小变化(未测)
4.将ListView的高度设为0,ItemsSource变化的时候估摸着给ListView设置高度,ItemMaxSize*N(未测,此时ScrollView的高度会动态变化,但是ListView下面还是有一片空白区域,但是比方案1应该好一些)
4.分隔符高度
Android中的ListView是可以设置ListView的分割符的高度(DividerHeight),但是iOS中是不行的,如果只是需要在Android中设置分隔符高度,使用Style即可以实现,如果要通用的话,我做了一下的尝试:
1)设置Page的背景色为灰色,并且设置ListView为背景色为白色,隐藏掉ListView的分隔符,在ViewCell的下面添加一个同Page底色相同的BoxView
<ListView.ItemTemplate> <DataTemplate> <ViewCell> <Frame Padding="0"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="10" /> </Grid.RowDefinitions> <Grid Padding="5"> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> <RowDefinition Height="auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="80" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label Text="巡检路线" /> <Label Grid.Column="1" Text="{Binding inspectRoute}" /> <Label Grid.Row="1" Text="巡检车辆" /> <Label Grid.Row="1" Grid.Column="1" Text="{Binding vehicleUsr}" /> <Label Grid.Row="2" Grid.Column="0" Text="巡检人" /> <Label Grid.Row="2" Grid.Column="1" Text="{Binding inspectorDesc}" /> <Label Grid.Row="3" Grid.Column="0" Text="派发时间" /> <Label Grid.Row="3" Grid.Column="1" Text="{Binding createTime,StringFormat='{0:yyyy-MM-dd HH:mm:ss}'}" /> </Grid> <!--分隔符--> <BoxView Grid.Row="1" BackgroundColor="{StaticResource Color_Gray}" /> </Grid> </Frame> </ViewCell> </DataTemplate> </ListView.ItemTemplate>
大概实现的效果是直角的CardView样式,有按压效果
2)在1)的基础上,取消掉ListView的背景色(直接是默认的),然后将ViewCell最外层的Frame的背景色设为White,我们知道Frame是圆角的,最终的效果是:CardView的样式(圆角),有分隔符高度,但是没有按压效果(因为设置了ViewCell的背景色为White的原因)
但是这种方法会出现两个BUG:
.由于每个Item的分隔符是在Item中,如果只有一两个,最后一个Item后面会有分隔符
.由于iOS的操作的左滑,会出现阴影部分也会包含在里面左滑(Android的没影响,默认是长按操作),所以会对列表进行操作的这种,不要使用这种样式
5.风格
由于本人常用的是Android以及最开始开发的也是Android,所以考虑的风格总是以Android的角度来看
ListView这种控件在Android中其实可以风格多变,譬如官方的CardView风格,因为他的操作就是长按或者点击;
但是在iOS中,ListView的操作默认就是左滑,这种风格,ListView最好还是不要设置Margin(不然菜单很奇怪),应该设置Cell的Padding,也不适合设置分隔符的高度
在观察中,只发现'微博ipad客户端'发现有分隔符高度,但是他的Item操作是点击Item上面的按钮