Android之双击回到顶部

转自:http://blog.csdn.net/My_Luna/article/details/50261925

双击回到顶部在Android应用中用的很多,众所周知的微信消息列表,朋友圈都提供这样的效果,下面我将自己自项目中的实践记录下来,分享给大家

首先:获取双击事件

网上有很多的获取双击事件的方法,这里我讲它稍加封装,整个工程也可以使用

首先我们来定义双击事件的接口

[java]  view plain  copy
  1. package com.....activity.info;  
  2.   
  3. import android.view.View;  
  4.   
  5. /** 
  6.  * @author wfy 
  7.  * 单击双击事件接口 
  8.  */  
  9. public interface OnDoubleClickListener {  
  10.     public void OnSingleClick(View v);  
  11.         public void OnDoubleClick(View v);  
  12. }  
下来定义一个DoubleClick类,它提供一个静态方法给一个view注册双击事件,注释我已经写的及其详细了,不再多说
[java]  view plain  copy
  1. package com.....activity.info;  
  2.   
  3. import android.os.Handler;  
  4. import android.os.Message;  
  5. import android.view.View;  
  6.   
  7. /** 
  8.  * @author wfy 
  9.  * 消息列表+好友动态的双击回到顶部 
  10.  */  
  11. public class DoubleClick {  
  12.     public static void registerDoubleClickListener(View view, final OnDoubleClickListener listener){  
  13.         if(listener==nullreturn;  
  14.         view.setOnClickListener(new View.OnClickListener() {  
  15.             //双击间隔时间350毫秒  
  16.             private static final int DOUBLE_CLICK_TIME = 350;  
  17.             private boolean flag = true;  
  18.             private Handler handler = new Handler(){  
  19.                 @Override  
  20.                 public void handleMessage(Message msg) {  
  21.                     listener.OnSingleClick((View)msg.obj);  
  22.                 }  
  23.                    
  24.             };  
  25.             //等待双击  
  26.             public void onClick(final View v) {  
  27.                 if(flag){  
  28.                     flag = false;//与执行双击事件  
  29.                     new Thread(){  
  30.                         public void run() {  
  31.                             try {  
  32.                                 Thread.sleep(DOUBLE_CLICK_TIME);  
  33.                                 //此时线程沉睡 而flag被修改为false  在DOUBLE_CLICK_TIME内点击则 进入else  
  34.                             } catch (InterruptedException e) {  
  35.                                 e.printStackTrace();  
  36.                             }    //等待双击时间,否则执行单击事件  
  37.                             if(!flag){  
  38.                                 //睡醒了看一看flag被人动过没,没有人动,则认作单击事件  
  39.                                 //因此不建议用此方法执行单击事件 因为会等待睡醒,有点击延迟的存在  
  40.                                   
  41.                                 //没有人动,自己把它改成true,以接受下次点击  
  42.                                 flag = true;  
  43.                                 Message msg = handler.obtainMessage();    
  44.                                 msg.obj = v;  
  45.                                 //发个消息,让执行单击  
  46.                                 handler.sendMessage(msg);  
  47.                             }  
  48.                         }  
  49.                            
  50.                     }.start();  
  51.                 }else{  
  52.                     flag = true;  
  53.                     listener.OnDoubleClick(v);    //执行双击  
  54.                 }  
  55.             }  
  56.         });  
  57.     }  
  58. }  

其次:给你要双击的组件注册双击事件,此处用button演示一下

[java]  view plain  copy
  1. Button button=new Button(this);  
  2.         DoubleClick.registerDoubleClickListener(button, new OnDoubleClickListener() {  
  3.               
  4.             @Override  
  5.             public void OnSingleClick(View v) {  
  6.                 // TODO Auto-generated method stub  
  7.                   
  8.             }  
  9.               
  10.             @Override  
  11.             public void OnDoubleClick(View v) {  
  12.                 // TODO Auto-generated method stub  
  13.                 GoTopTask task=new GoTopTask();  
  14.                                 task.execute(firstposition);  
  15.             }  
  16.         });  

最后:细心的会发现,在上面的OnDoubleClick方法中我启动了一个异步任务,下面贴出代码,这是一个内部类

[java]  view plain  copy
  1. private class GoTopTask extends AsyncTask<Integer, Integer, String>{  
  2.         @Override  
  3.         protected void onPreExecute() {  
  4.             //回到顶部时间置0  此处的时间不是侠义上的时间  
  5.             time=0;  
  6.             super.onPreExecute();  
  7.         }  
  8.         @Override  
  9.         protected String doInBackground(Integer... params) {  
  10.             // TODO Auto-generated method stub  
  11.               
  12.             for(int i=params[0];i>=0;i--){  
  13.                 publishProgress(i);  
  14.                 //返回顶部时间耗费15个item还没回去,则直接去顶部  
  15.                 //目的:要产生滚动的假象,但也不能耗时过多  
  16.                 time++;  
  17.                 if(time>15){  
  18.                     publishProgress(0);  
  19.                     return null;  
  20.                 }  
  21.                 try {  
  22.                     Thread.sleep(5);  
  23.                 } catch (InterruptedException e) {  
  24.                     e.printStackTrace();  
  25.                 }  
  26.             }  
  27.             return null;  
  28.         }  
  29.         @Override  
  30.         protected void onProgressUpdate(Integer... values) {  
  31.             lv.setSelection(values[0]);  
  32.             super.onProgressUpdate(values);  
  33.         }  
  34.         @Override  
  35.         protected void onPostExecute(String result) {  
  36.             super.onPostExecute(result);  
  37.         }  
  38.         @Override  
  39.         protected void onCancelled() {  
  40.             // TODO Auto-generated method stub  
  41.             super.onCancelled();  
  42.         }  
  43.           
  44.     }  
写到这里相信大家都明白思路了,就是用lv.setSelection(0)让list回到顶部,可是这里存在三个问题:1、直接闪回到顶部用户体验不是很好,很突兀   2、如1所说,那一个个往会显示,可是你有1000个item,我看到好几百个时,往回一个一个滚吗?相信没有人有那个耐心等   3、不能每次都从最后往会滚,从当前可见的第一个item滚,那么如何获取当前可见的第一个item?

对于第一个问题和第二个问题:我在异步任务里已经做了判断,先一个一个滚,滚到第十五个(也就是异步任务里的time)还没回去则直接回顶部,这样既有了滚动的动作,也不会因为有好多item让用户等待太久

对于第三个问题:首先在当前的activity里定义一个静态的变量,用来持续追踪当前可见的第一个item,然后通过监听lv滚动事件实时修改firstposition,这里贴出代码

[java]  view plain  copy
  1. lv.setOnScrollListener(new OnScrollListener() {  
  2.               
  3.             @Override  
  4.             public void onScrollStateChanged(AbsListView view, int scrollState) {  
  5.                 // TODO Auto-generated method stub  
  6.                   
  7.             }  
  8.               
  9.             @Override  
  10.             public void onScroll(AbsListView view, int firstVisibleItem,  
  11.                     int visibleItemCount, int totalItemCount) {  
  12.                 // TODO Auto-generated method stub  
  13.                 firstposition=firstVisibleItem;  
  14.             }  
  15.         });  
好了,到这里就大功告成了,是不是很简单,之所以写的很详细,是想让看的人理解,而不是仅仅copy我的code,理解了就是自己的,方法很重要。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值