Xamarin 实现 Android 无限循环展示, FlipView

先发个图, 让你们知道我说的是什么:

在这之前,  写过一个用于 Xamarin.Form (以下简称 XF ) 的 FlipView,  Android 下是用 HorizontalScrollView 模拟的.

上上周, 无意间看到了 ViewPager 如何实现无限循环的方法 , 于是捉摸在 Xamarin 下把它给实现一下.

在 XF 下, 你可以看到从网络加载的 大图 显示的很流畅 , 因为 XF 下, UriImageSource 这个图片源有这么两个属性:

CacheValidity 缓存多长时间

CachingEnabled 是否启用缓存

这说明在 XF 下, 已经封装好了类似于 Android 的 LRUCacheDiskLRUCache , 注意, 这仅仅是在 XF 下才有这个功能.

一开始不了解这个个梗, 在 Android 项目(不是 XF 项目) 遇到了这几个问题:

1, 在主线程上无法加载网络图片

不了解这个的原因, 查到的资料说在 Android 4.0 以后 (未验证) , 不允许阻塞主线程.

直接从网络加载图片明显会有阻塞, 所以运行肯定是没有结果的等待, 直至崩溃.

2, OOM

这个问题, 对搞 Android 开发的人来说, 在普通不过了.全称是 Out Of Memory,  就是内存溢出.

OOM 的解决办法介绍最多的就是用缓存, 也就是上面提到的 LRUCache (这个Android SDK 中提供的有) 和 DiskLRUCache (SDK中没有, 但是有源码).

LRUCache 是放到内存中的, 应用一关闭, 缓存的数据就丢失了.

DiskLRUCache 是把文件存放到手机的 "硬盘" (区分于内存)中.

3, Adapter 的数据源为 IEnumerable

自定义的 Adapter,  如果数据源是一个 IEnumerable , 如果传给 Adapter 之前, 没有 ToList, 在执行的时候, 会一直的去调用这个 IEnumerable 的生成函数.

如这样:

1         private IEnumerable<AV.View> GetChildrenViews() {
2             foreach (var v in this.Element.Children) {
3                 var render = RendererFactory.GetRenderer(v);
4                 var c = new AW.FrameLayout(this.Context);
5                 c.SetBackgroundColor(Color.Blue.ToAndroid());
6                 c.AddView(render.ViewGroup, LayoutParams.MatchParent, LayoutParams.MatchParent);
7                 yield return c;
8             }
9         }

如果不 ToList 就把这个函数的结果传入 Adapter, foreach 这块会一直的被调用.

4, System.IO.IOException: Sharing violation on path XXX

报这个问题, 是因为使用了 Mono 的 IsolatedStorage,  在 Stream.CopyToAsync 时如果不指定 bufferSize 就会报这个错,

诡异的是, 在公司的电脑上如果指定 bufferSize , 就没有这个错误, 在家里的电脑上指不指定 bufferSize 都会报这个错.

但是放try..catch.. 之中, 文件又可以写成功 (从调试输出的内容看, 第二次运行,不会在从网络上加载图片).

是不是我写法有问题?

 1         public async Task WriteStream(string file, Stream stm) {
 2             var path = this.GetPath(file);
 3
 4             try {
 5                 using (var fs = ISF.OpenFile(path, FileMode.OpenOrCreate, FileAccess.Write)) {
 6                     //await stm.CopyToAsync(fs); 如果不指定 buff size , 会报错
 7                     await stm.CopyToAsync(fs, 16384);
 8                 }
 9             } catch {
10
11             }
12         }

5, 如何实现无限循环

这部分是参考别人的 (来源找不到了), 通俗来说, 是这样的:

A, Adapter 的 Count 属性返回真实数据条数的整数, 假如我只有3条数据, 我会欺骗 Adapter , 我有6条.

B, 在确定要显示哪一条数据的时候, 要获取给出 position 对应的真实的数据条目. 用这个 position 求余 真实数据的条目.

即在 Adapter 的 InstantiateItem 方法中, 用 position %= this.Items.Count() 来取出真正的要显示哪条数据. 假如有 3 条数据, 当前的 position 是 5, 其实要显示的就是第2条数据.

C, Adapter 的 FinishUpdate 方法.

 1         public override void FinishUpdate(ViewGroup container) {
 2             var vp = container as ViewPager;
 3             var pos = vp.CurrentItem;
 4
 5             if (pos == 0) {
 6                 pos = this.Items.Count();/////////////
 7             } else if (pos == this.Count - 1) {
 8                 pos = this.Items.Count() - 1;///////////////
 9             }
10             //System.Diagnostics.Debug.WriteLine("====> pos {0}", pos);
11             vp.SetCurrentItem(pos, false);
12         }

如果真实条数是 3, Adapter 的 Count 被设为 6, 就会这样:

0 1 2 0 1 2

如果当前的 pos 是 0 , 就设置 pos 为第4位上的那个0, 即第二轮的第0位 (下标从0开始啊).

如果 pos 为 5 (下标从0开始), 就设置 pos 为第一轮的最后一个, 即第一个2.

-----------------

OK , 就这些, 照例, 上源码:

直接的 Android 项目: https://github.com/gruan01/Xamarin-Example/tree/master/FlipView

用于 Xamarin.Form 的: https://github.com/gruan01/FlipView

另外, 我并没有实现网上流传的那个 DiskLruCache , 而是用 IsolatedStorage 实现了个简单的. 很大可能隐藏其它问题.

时间: 2024-07-29 13:05:19

Xamarin 实现 Android 无限循环展示, FlipView的相关文章

使用Axure制作无限循环展示图片效果

一.实现的效果 如图: 1.此次需要实现的效果是,进入界面后,在图片展示区域的图片根据事先设定好的时间,自动切换不同的图片: 2.循环不间断: 3.页面不出现闪烁的现象. 二.做前工作 图片:4张 软件:Axure 三.制作流程 1.在开打的空页面上添加一个动态面板(X:20 ,Y:20 :W:600,H:382)如图: 2.给动态面板取名为“动态广告”,再在该动态面板上添加4个字状态,分别取名为,图01.图02.图03.图04.如图: 3.为每个状态分别添加不同的图片.如图: 4.为了实现这个

[android] 轮播图-无限循环

实现无限循环 在getCount()方法中,返回一个很大的值,Integer.MAX_VALUE 在instantiateItem()方法中,获取当前View的索引时,进行取于操作,传递进来的int position是个非常大的数,对他进行求余数 在destroyItem()方法中,同样 在onPageSelected()监听方法中,对传递进来的索引进行取于 反向的无限循环 调用ViewPager对象的setCurrentItem()方法,设置第一次进来时候的当前页,参数:int数字,我们把它定

无限轮播(循环展示)

无限轮播(循环展示) 一.简单说明 之前的程序还存在一个问题,那就是不能循环展示,因为plist文件中只有五个数组,因此第一个和最后一个之后就没有了,下面介绍处理这种循环展示问题的小技巧. 方法一:使用一个for循环,循环200次,创建200*=1000个模型,且默认程序启动后处在第100组的位置,向前有500个模型,向后也有500个模型,产生一种循环展示的假象. 代码如下: 8 9 #import "YYViewController.h" 10 #import "MJExt

iOS开发UI篇—无限轮播(循环展示)

一.简单说明 之前的程序还存在一个问题,那就是不能循环展示,因为plist文件中只有五个数组,因此第一个和最后一个之后就没有了,下面介绍处理这种循环展示问题的小技巧. 方法一:使用一个for循环,循环200次,创建200*=1000个模型,且默认程序启动后处在第100组的位置,向前有500个模型,向后也有500个模型,产生一种循环展示的假象. 代码如下: 1 // 2 // YYViewController.m 3 // 07-无限滚动(循环利用) 4 // 5 // Created by ap

【Android】ViewPager实现无限循环滚动

最近做的一个项目,客户要求在ViewPager实现的主页面中滑动到最后一页后继续滑动能返回到第一页,也就是实现无限循环滚动,效果如下: 看了下ViewPager没有滑到尽头的回调方法,因此想到的解决方案是,在原来的最后一页之后再加上一个第一页,也就是原本有编号为a1,b,c的三个页面,现在在最后面再加一个a页面,变为a1.b.c.a2四个页面,然后使用OnPageChangeListener中的onPageSelected方法来监听到页面切换,当发现是从第三个页面(c)切换到第四个页面(a1)时

详细分析Android viewpager 无限循环滚动图片

由于最近在忙于项目,就没时间更新博客了,于是趁着周日在房间把最近的在项目中遇到的技术总结下.最近在项目中要做一个在viewpager无限滚动图片的需求,其实百度一下有好多的例子,但是大部分虽然实现了,但是讲的都不清楚,我查了很多资料,我就知道position/list.size().但是怎么用,我还是不明白.我后来看了百度工程师任玉刚的循环广告位组件的实现突然明白了无限滚动的原理.总结如下: 1.要在int getCount() 方法里 写 return BANNER_SIZE.  这个 BAN

android-自定义广告轮播Banner(无限循环实现)

关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户"友好性",下面来看几个示例图:    再来看下我仿写的效果: 关于广告轮播Banner这个东西,GitHub上面应该有现成的开源组件,不过我没去找过,觉得实现起来不会太难,就自己去仿写了,下面我说下实现的思路: 1.首先看到这个可以滑动切换图片的界面,我们很自然就会想到ViewPager控

安卓开发笔记——自定义广告轮播Banner(无限循环实现)

关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户"友好性",下面来看几个示例图:     再来看下我仿写的效果: 关于广告轮播Banner这个东西,GitHub上面应该有现成的开源组件,不过我没去找过,觉得实现起来不会太难,就自己去仿写了,下面我说下实现的思路: 1.首先看到这个可以滑动切换图片的界面,我们很自然就会想到ViewPager

ViewPager使用记录3——循环展示

ViewPager是v4支持库中的一个控件,相信几乎所有接触Android开发的人都对它不陌生.之所以还要在这里翻旧账,是因为我在最近的项目中有多个需求用到了它,觉得自己对它的认识不够深刻.我计划从最简单的使用场景出发,记录我到目前为止所对ViewPager的使用情况以及有关它的一些知识点. 这个系列的代码将存放在Github仓库中,每篇文章对应一个分支或几个分支. 这是第三篇文章,将讨论集中有关如何使用ViewPager展示无限循环视图的方法. 方法1:极大化PagerAdapter.getC