Android ViewPager>Fragment>Listview>addHeaderView添加轮播图隐藏bug

写这篇文章,主要是阐述自己遇到的一些问题时的解决方法,小弟才疏学浅,若有说的不对的地方,请批评指正!!!大神勿喷啊!

最近在做App项目,根据客户要求,用了ViewPager来装入Fragment,然后每个Fragment装入一个Listview,当然肯定有可切换的标题头,刚开始做的很顺利,因为都是基础控件的应用,基本上没有什么问题,后来客户修改要求,在App的第一个页面也就是Listview上加一个轮播图的标题头,当然可以了,客户是上帝嘛,而且也简单啊,新建一个ViewPager,里面把需要装入的图片添加进去,然后通过listview.addheadView(view),搞定.轮播图肯定要让图片时刻动起来,常规思想,新建一个线程,每隔几秒钟切换一下,看代码:

//开启线程切换图片
		new  Thread(new Runnable() {
			
			@Override
			public void run() {
				while (true) {
					SystemClock.sleep(3000);
                                        //切换
					handler.post(new Runnable() {
						//该方法在主线程中执行
						@Override
						public void run() {
						    //获得当前的显示的索引
                                                    //headviewpager新建的viewpager
							int currentItem = headviewpager.getCurrentItem();
							int newItem = 0;
                                                     //headdatalist为viewpager的数据集合
							if(currentItem == (headdataList.size() -1)){
								newItem = 0;
							}else{
								newItem = currentItem + 1;
							}
						  headviewpager.setCurrentItem(newItem);
						}
					});
					
				}
			}
		}).start();
问题出现了,明明是线程睡3秒钟后才自动开始切换
SystemClock.sleep(3000);

但是在当viewpager切换Fragment后,刚开始没感觉,多切换几次,并且每次切换返回主页(就是有headview轮播图的主页),就会发现轮播图切换的时间越来越短,切换速度越来越快!完全没有睡3秒在切换,因为是用AS写的,以为没有编译好,重新编译,重新安装后,问题依然存在.

在网上搜索找了好久没有找到这种问题的说法,后来自己琢磨了一下,写出了和各位大神们请教一下;

原因是:viewpager创建fragment的时候自动创建子线程去切换轮播图,当viewpage左右切换时,fragment会销毁,而切换轮播图的子线程并没有随着一起销毁,还在后台执行,当viewpage再次回到主页(就是有headview轮播图的主页)时,fragment会重新创建,同时会再次新建一个子线程来切换轮播图,这样来回切换几次后,后天就会有很多子线程在切换轮播图,每个子线程启动的时间还不一样,这样累加起来,子线程与子线程之间启动切换轮播图时就没有时间间隔,所以轮播图切换会越来越快.

第一时间解决方法是利用Fragment的生命周期将子线程杀掉:

新建一个类继承Thread,里面放切换代码,然后重写Fragment的on Stop()方法:

@Override
public void onStop() {
    super.onStop();
    thread.destroy();
    Log.i("MainActivity", "onStop: 杀死任务");}

通过日志可以看到当viewpage切换Fragment生命后期on Stop()时,直接报错,错误是无法调用threa.destroy()方法;

这个时候我就懵了,为什么呢?

请教同事后是这样理解的,因为我的子线程执行的是while的死循环睡3秒切换图片,相当于线程没有执行完,所以无法被杀死,那么轮播图要在这样的环境下进行切换,该怎么办呢?

在网上找了很多方法,最后找了一个能解决问题的方法,直接看代码:

//把timer声明称全局变量
timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
    public void run() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                int cutrrentitem = headviewpager.getCurrentItem();
                int newitem = 0;
                if (cutrrentitem == (headviewpagedataList.size() -1)) {
                    newitem = 0;
                } else {
                    newitem = cutrrentitem + 1;
                }
                headviewpager.setCurrentItem(newitem);
            }
        });
    }
//每间隔两秒执行一次
}, 2000, 2000);
就是新建一个延迟任务,任务的代码就不解释那么多了,可以去查API!

然后还是利用fragment的生命周期;

    public void onStop() {
        super.onStop();
        //调用timer的cancel方法,结束延迟任务
        timer.cancel();
        Log.i("MainActivity", "onStop: 杀死任务");
    }

OK,问题搞定!



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值