您的位置:首页 > 移动开发 > Android开发

Android之双击回到顶部

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


首先:获取双击事件

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

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

[java] view
plain copy

package com.....activity.info;  

  

import android.view.View;  

  

/** 

 * @author wfy 

 * 单击双击事件接口 

 */  

public interface OnDoubleClickListener {  

    public void OnSingleClick(View v);  

        public void OnDoubleClick(View v);  

}  

下来定义一个DoubleClick类,它提供一个静态方法给一个view注册双击事件,注释我已经写的及其详细了,不再多说

[java] view
plain copy

package com.....activity.info;  

  

import android.os.Handler;  

import android.os.Message;  

import android.view.View;  

  

/** 

 * @author wfy 

 * 消息列表+好友动态的双击回到顶部 

 */  

public class DoubleClick {  

    public static void registerDoubleClickListener(View view, final OnDoubleClickListener listener){  

        if(listener==null) return;  

        view.setOnClickListener(new View.OnClickListener() {  

            //双击间隔时间350毫秒  

            private static final int DOUBLE_CLICK_TIME = 350;  

            private boolean flag = true;  

            private Handler handler = new Handler(){  

                @Override  

                public void handleMessage(Message msg) {  

                    listener.OnSingleClick((View)msg.obj);  

                }  

                   

            };  

            //等待双击  

            public void onClick(final View v) {  

                if(flag){  

                    flag = false;//与执行双击事件  

                    new Thread(){  

                        public void run() {  

                            try {  

                                Thread.sleep(DOUBLE_CLICK_TIME);  

                                //此时线程沉睡 而flag被修改为false  在DOUBLE_CLICK_TIME内点击则 进入else  

                            } catch (InterruptedException e) {  

                                e.printStackTrace();  

                            }    //等待双击时间,否则执行单击事件  

                            if(!flag){  

                                //睡醒了看一看flag被人动过没,没有人动,则认作单击事件  

                                //因此不建议用此方法执行单击事件 因为会等待睡醒,有点击延迟的存在  

                                  

                                //没有人动,自己把它改成true,以接受下次点击  

                                flag = true;  

                                Message msg = handler.obtainMessage();    

                                msg.obj = v;  

                                //发个消息,让执行单击  

                                handler.sendMessage(msg);  

                            }  

                        }  

                           

                    }.start();  

                }else{  

                    flag = true;  

                    listener.OnDoubleClick(v);    //执行双击  

                }  

            }  

        });  

    }  

}  


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

[java] view
plain copy

Button button=new Button(this);  

        DoubleClick.registerDoubleClickListener(button, new OnDoubleClickListener() {  

              

            @Override  

            public void OnSingleClick(View v) {  

                // TODO Auto-generated method stub  

                  

            }  

              

            @Override  

            public void OnDoubleClick(View v) {  

                // TODO Auto-generated method stub  

                GoTopTask task=new GoTopTask();  

                                task.execute(firstposition);  

            }  

        });  


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

[java] view
plain copy

private class GoTopTask extends AsyncTask<Integer, Integer, String>{  

        @Override  

        protected void onPreExecute() {  

            //回到顶部时间置0  此处的时间不是侠义上的时间  

            time=0;  

            super.onPreExecute();  

        }  

        @Override  

        protected String doInBackground(Integer... params) {  

            // TODO Auto-generated method stub  

              

            for(int i=params[0];i>=0;i--){  

                publishProgress(i);  

                //返回顶部时间耗费15个item还没回去,则直接去顶部  

                //目的:要产生滚动的假象,但也不能耗时过多  

                time++;  

                if(time>15){  

                    publishProgress(0);  

                    return null;  

                }  

                try {  

                    Thread.sleep(5);  

                } catch (InterruptedException e) {  

                    e.printStackTrace();  

                }  

            }  

            return null;  

        }  

        @Override  

        protected void onProgressUpdate(Integer... values) {  

            lv.setSelection(values[0]);  

            super.onProgressUpdate(values);  

        }  

        @Override  

        protected void onPostExecute(String result) {  

            super.onPostExecute(result);  

        }  

        @Override  

        protected void onCancelled() {  

            // TODO Auto-generated method stub  

            super.onCancelled();  

        }  

          

    }  

写到这里相信大家都明白思路了,就是用lv.setSelection(0)让list回到顶部,可是这里存在三个问题:1、直接闪回到顶部用户体验不是很好,很突兀   2、如1所说,那一个个往会显示,可是你有1000个item,我看到好几百个时,往回一个一个滚吗?相信没有人有那个耐心等   3、不能每次都从最后往会滚,从当前可见的第一个item滚,那么如何获取当前可见的第一个item?

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

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

[java] view
plain copy

lv.setOnScrollListener(new OnScrollListener() {  

              

            @Override  

            public void onScrollStateChanged(AbsListView view, int scrollState) {  

                // TODO Auto-generated method stub  

                  

            }  

              

            @Override  

            public void onScroll(AbsListView view, int firstVisibleItem,  

                    int visibleItemCount, int totalItemCount) {  

                // TODO Auto-generated method stub  

                firstposition=firstVisibleItem;  

            }  

        });  

好了,到这里就大功告成了,是不是很简单,之所以写的很详细,是想让看的人理解,而不是仅仅copy我的code,理解了就是自己的,方法很重要。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: