使用观察者模式解决ViewPager加载照片中更新其他Fragment内容

1. 问题

     在用ViewPager加载fragment浏览图片的时候,需要删除当前浏览的照片,删除后要加载下一张或者上一张照片,并且照片的位置等信息都要更新,

但是因为ViewPager每次都是预加载前一张和后一张,在删除照片之前前一张和后一张的照片信息已经加载完成了,

那这个时候该如何更新已经加载了的照片的信息呢,并且当前又该如何显示下一张照片呢,尝试了很多方法都失败了,当然也可以禁止预加载,但是用户体验不好;

经过一天的研究,发现安卓的观察者模式能够解决这个问题,于是研究了下,完美解决了。

2. 观察者模式

    观察者模式的原理网上一大堆,简单点说就是定义一个被观察者和多个观察者,被观察者改变的时候通知所有的观察者都改变;

在实际使用的时候和回调函数有点相似,但是却比回调功能更强,这里不过多的介绍观察者模式了,网上有一个朋友介绍得很详细了,可以了解下:

http://www.apkbus.com/forum.php?mod=viewthread&tid=112815&extra=page%3D1&page=1

3. 解决问题

   使用观察者模式,最重要的一点就是得知道谁是观察者Observer,谁是被观察者Observable,那么在本文讨论的问题中,观察者就是ViewPager中的每一项,

被观察者需要自定义一个继承自Observable的类,在这个类中做一些接口做数据的变更,需要注意一点,就是在更新数据的时候必须加上setChanged();和notifyObservers();通知观察者更新,代码如下:

public class MyObservable extends Observable {

	private List<MyFileInfor> list = null;
	private int position = 0;
	
	public void setPosition(int position)
	{
		this.position = position;
		setChanged();
		notifyObservers();
	}
	public int getPosition()
	{
		return position;
	}
	public List<MyFileInfor> getList() {
		return list;
	}

	public void setList(List<MyFileInfor> list) {
		this.list = list;
		setChanged();
		notifyObservers();
	}
}
 

被观察者定义好了,现在就定义观察者了,很简单,只需要在ViewPager中的每一个Fragment实现Observer接口,里面有一个回调函数:

/**
	*callbacks
	*/
	@Override
	public void update(Observable observable, Object data)
	{
		// TODO Auto-generated method stub
		MyObservable myObservable = (MyObservable)observable;
		/*fileList = myObservable.getList();
		curPosition = myObservable.getPosition(); */
		MyLog.e("curPosition-->"+ curPosition);
		MyLog.e("curPosition get-->"+ myObservable.getPosition());
		PublicFun.sendMessage(handler, HANDLER_UPDATE_BY_OBSERVER);
	}

在这个回调函数中做界面更新,更新就很简单了,什么都不用做,只需要在删除的时候将那一张图片从列表中移除,然后和正常浏览一样更新UI就可以了;

最后就是给被观察者添加观察者了,在ViewPager的适配器中有添加Fragment和移除Fragment ,同样在这里添加观察者和被观察者:

@Override
		public Fragment getItem(int position) 
		{
			
			PicFullScreenViewFragment view = PicFullScreenViewFragment.newInstance(type, fileList, position, mAdapter);
			viewList.add(view);
			obervable.addObserver(view);
			return view;
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) 
		{
			final PicFullScreenViewFragment fragment = (PicFullScreenViewFragment) object;
			obervable.deleteObserver(fragment);
			viewList.remove(fragment);
			fragment.cancelWork();
			super.destroyItem(container, position, object);
		}
		
		public void updateObserver(List<MyFileInfor> list, int position)
		{
			obervable.setList(list);
			obervable.setPosition(position);
		}

其中,updateObserver函数就在删除照片操作的时候调用的,当调用这个函数时,被观察者就会通知其他观察者更新,即调用上面说的update函数。

采用观察者模式,基本上解决了问题,但是具体细节还需要自己去调整,比如说,但删除最后一张照片的时候就会出现黑屏的问题,这个问题也很好解决,

当出现黑屏的时候用手滑动一下,就会显示当前列表的最后一张照片,在代码中处理就是,当删除的是最后一张照片的时候,将ViewPager设置为当前的位置就行了,

问题基本上解决了,由于是公司的项目,不便上传源码,有疑问可以留言。




更新:

以前是按照列表一样对ViewPager进行更新操作,但是当删除其中一个View然后再notifidatasetchanged的时候,并没有达到期望的效果,当前一页变成黑色的了,所以才用观察者模式来更新ViewPager,

但是今天却看到了ViewPager的一个方法:

public int getItemPosition(Object object) {  
              return POSITION_NONE;  
          } 

当删除其中一页的时候会回调这个方法更新ViewPager,自动显示下一页或者上一页,非常方便;


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值