解决方案

一、对于前两个要求的解决方案
1、将图片放在滚动控件RecyclerView中,以下两行代码用处是在RecyclerView中使用GridLayoutManager这种布局来设置屏幕显示的列数(我想了一下,我今天说的那个卡片式布局不能用,因为卡片式布局更多的是用于等大小的图片的,所以像这样不规则的图片,很难控制)

GridLayoutManager layoutManager=new GriLayoutManager(this,2);
recyclerView.setLayoutManager(layoutManager);

2、把准备要渲染的图片放在一个容器中(可以是一个数组),然后由于依次左右左右把图片放入到屏幕上,可能会导致屏幕其中一列有巨大空白的问题,所以第一个想法是将图片按照高度进行分类,然后进行依次渲染,但是这样的处理会导致图片最终的排列顺序不能和最初的存储顺序相近。所以最终的解决方案是:通过BitmapFactory的outHeight()方法来获取图片的高度

BitmapFactory.Options options = new BitmapFactory.Options();
return options.outHeight

3、然后每当需要添加一张图片时,会将这张图片的宽度压缩成和列一样宽,然后在这两列中找出当前高度最小(这个高度最小是通过此列已有图片高度和来判断的)的一列,将图片添加到这一列中。之后每当需要添加一张新图片时,都去重复上面的操作,就会形成瀑布流格局的照片墙。

另一种思路:
将整体布局设置为ScrollView,然后在ScrollView中嵌入一个LinearLayout布局,再在这个LinearLayout布局中嵌套两个LinearLayout布局作为两列。在每次添加图片的时候,都取出每一列最下面的图片,然后在这两张图片中寻找最靠上的那个图片所在列,(可以通过计算最下面图片分别到屏幕最低端的的距离,距离越长,说明越靠上)这就是新图片应该插入的位置。
具体步骤:
(1)自定义一个AnotherScrollView类继承于ScrollView类

public class MyScrollView extends ScrollView

(2)在AnotherScrollView类中重写onLayout()方法,这个方法用来初始化操作,包括初始化第一张页面。再定义一个用于加载下一张页面。至于每一张页面的每一张图片该怎么加载,就要用到上述的判断方法。
(3)然后重写onTouch方法去设置一个监听到手指离开屏幕的事件,当滑动页面的时候就对当前ScrollView的滚动状态进行判断,如果发现已经滚动到了最底部,就会调用方法加载下一页的图片。

二、关于内存和图片回收复用的解决方案(以下都是以手指从下往上滑,下面页面作为新页面来说明的)
既然图片已经大致可以按照输入的顺序以及保证两列不留空白的情况进行添加了。但是考虑一个情况就是不断地加入图片会占用大量内存,甚至会出现内存溢出的情况,所以考虑到尽量占用少的内存,从以下方面考虑:
1、在图片进行读取的时候,尽量适当的压缩
2、改变堆内存的大小
3、对显示在屏幕上的图片进行复用,对移出去的图片进行回收,下面具体说一下实现这个的想法:

回收思路:(定义一个内存,用算法让它先进先出,或者把最近最少使用的先出)
(1)给每一张图片加入索引,这个想法是首先获取当前页面的首位置以及图片数N,那么首张照片的索引就是0,最后一张就是N-1.这样的话把每一张照片的索引作为key值,让每张照片作为value值,通过索引可以锁定照片。索引和照片成为一对(key-value)
(2)因为每滑动新一页,最先消失的是上一页最顶端的图片,这里可以想作成最先被回收的是上一张最顶端的图片,同样地道理,最后被回收最先被复用的是上一张最低端的照片,所以对于回收,我想到优先把最近最少使用的(也就是前一张最顶端的图片)先回收掉,所以这里想到LinkedHashMap。
(3)具体就是当滑动到新的一页的时候,把上一页滑出去的图片根据索引从小到大利用头插法依次进入到LinkedHashMap中的双向链表中(因为LinkedHashMap就是数组加双向链表)。即便一旦发现内存不够,也可以将最先进入的图片(链表尾)删除掉,因为最先进入的代表被滑出去那一页最顶端的图片,它也是复用几率最小的。
复用思路(定义一个内存,用算法让它后进先出)
(1)跟回收相反,当滑动新一页的时候,再准备滑回去的时候是上一页最底端的图片先被复用。而且上一页最底端的图片在回收的时候是最后进入内存的,所以要保证它后进先出,所以想到栈。
(2)具体就是当滑动到新的一页的时候,把上一页滑出去的图片根据索引从小到大依次进栈,当需要复用的时候,再依次出栈,这可以保证最后被滑出去的可以被优先复用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值