Android ListView监听上下滑动(判断是否显示返回顶部按钮)

在有些listview上面和ScrollView上,当滑动到底部的时候,在右下角会出现一个回到顶部的按钮,提供更好的用户体验。

效果图如下:

Android ListView监听上下滑动(判断是否显示返回顶部按钮)_第1张图片


布局 

先说布局,可以用帧布局Framelayout,也可以用相对布局relativelayout.看下listview的布局文件:

[html]  view plain  copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="@android:color/white" >  
  6.   
  7.     <ListView  
  8.         android:id="@+id/my_listView"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_marginLeft="10dp"  
  12.         android:layout_marginRight="10dp" />  
  13.   
  14.     <Button  
  15.         android:id="@+id/top_btn"  
  16.         android:layout_width="50dp"  
  17.         android:layout_height="50dp"  
  18.         android:visibility="gone"  
  19.         android:layout_alignParentBottom="true"  
  20.         android:layout_alignParentRight="true"  
  21.         android:layout_marginBottom="6dp"  
  22.         android:layout_marginRight="6dp"  
  23.         android:background="@drawable/top_btn_bg"  
  24.         android:gravity="center"  
  25.         android:text="顶" />  
  26.   
  27. </RelativeLayout>  

Listview 回到顶部的活动代码 

是从网上找到的代码,作者为:zihao 
[java]  view plain  copy
  1. /** 
  2.  * 主界面 
  3.  *  
  4.  * @author zihao 
  5.  * @details 因为有些手机是有虚拟按键的(在计算屏幕分辨率的时候,有些可以去除掉虚拟区域的区域->如三星,有些不行->如MX3),为了计算的准确性, 
  6.  *          各位可以设置Activity为Theme 
  7.  *          .NoTitleBar.Fullscreen填满屏幕(解决类似MX3这种在计算过程中把虚拟键盘算入屏幕高度的)。 
  8.  */  
  9. public class ListActivity extends Activity implements OnClickListener {  
  10.   
  11.     private ListView listView;// List数据列表  
  12.     private Button toTopBtn;// 返回顶部的按钮  
  13.     private MyAdapter adapter;  
  14.     private boolean scrollFlag = false;// 标记是否滑动  
  15.     private int lastVisibleItemPosition = 0;// 标记上次滑动位置  
  16.   
  17.     @Override  
  18.     protected void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.activity_list);  
  21.   
  22.         initView();  
  23.     }  
  24.   
  25.     /** 
  26.      * 初始化视图 
  27.      */  
  28.     private void initView() {  
  29.         listView = (ListView) findViewById(R.id.my_listView);  
  30.         toTopBtn = (Button) findViewById(R.id.top_btn);  
  31.   
  32.         adapter = new MyAdapter(this, getTitleDatas());  
  33.         listView.setAdapter(adapter);  
  34.   
  35.         toTopBtn.setOnClickListener(this);  
  36.         listView.setOnScrollListener(new OnScrollListener() {  
  37.   
  38.             @Override  
  39.             public void onScrollStateChanged(AbsListView view, int scrollState) {  
  40.                 // TODO Auto-generated method stub  
  41.                 switch (scrollState) {  
  42.                 // 当不滚动时  
  43.                 case OnScrollListener.SCROLL_STATE_IDLE:// 是当屏幕停止滚动时  
  44.                     scrollFlag = false;  
  45.                     // 判断滚动到底部  
  46.                     if (listView.getLastVisiblePosition() == (listView  
  47.                             .getCount() - 1)) {  
  48.                         toTopBtn.setVisibility(View.VISIBLE);  
  49.                     }  
  50.                     // 判断滚动到顶部  
  51.                     if (listView.getFirstVisiblePosition() == 0) {  
  52.                         toTopBtn.setVisibility(View.GONE);  
  53.                     }  
  54.   
  55.                     break;  
  56.                 case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:// 滚动时  
  57.                     scrollFlag = true;  
  58.                     break;  
  59.                 case OnScrollListener.SCROLL_STATE_FLING:// 是当用户由于之前划动屏幕并抬起手指,屏幕产生惯性滑动时  
  60.                     scrollFlag = false;  
  61.                     break;  
  62.                 }  
  63.             }  
  64.   
  65.             /** 
  66.              * firstVisibleItem:当前能看见的第一个列表项ID(从0开始) 
  67.              * visibleItemCount:当前能看见的列表项个数(小半个也算) totalItemCount:列表项共数 
  68.              */  
  69.             @Override  
  70.             public void onScroll(AbsListView view, int firstVisibleItem,  
  71.                     int visibleItemCount, int totalItemCount) {  
  72.                 // 当开始滑动且ListView底部的Y轴点超出屏幕最大范围时,显示或隐藏顶部按钮  
  73.                 if (scrollFlag  
  74.                         && ScreenUtil.getScreenViewBottomHeight(listView) >= ScreenUtil  
  75.                                 .getScreenHeight(ListActivity.this)) {  
  76.                     if (firstVisibleItem > lastVisibleItemPosition) {// 上滑  
  77.                         toTopBtn.setVisibility(View.VISIBLE);  
  78.                     } else if (firstVisibleItem < lastVisibleItemPosition) {// 下滑  
  79.                         toTopBtn.setVisibility(View.GONE);  
  80.                     } else {  
  81.                         return;  
  82.                     }  
  83.                     lastVisibleItemPosition = firstVisibleItem;  
  84.                 }  
  85.             }  
  86.         });  
  87.     }  
  88.   
  89.     /** 
  90.      * 获取标题数据列表 
  91.      *  
  92.      * @return 
  93.      */  
  94.     private List<String> getTitleDatas() {  
  95.         List<String> titleArray = new ArrayList<String>();  
  96.         for (int i = 0; i < 30; i++) {  
  97.             titleArray.add("这是第" + i + "个item");  
  98.         }  
  99.         return titleArray;  
  100.     }  
  101.   
  102.     /** 
  103.      * 滚动ListView到指定位置 
  104.      *  
  105.      * @param pos 
  106.      */  
  107.     private void setListViewPos(int pos) {  
  108.         if (android.os.Build.VERSION.SDK_INT >= 8) {  
  109.             listView.smoothScrollToPosition(pos);  
  110.         } else {  
  111.             listView.setSelection(pos);  
  112.         }  
  113.     }  
  114.   
  115.     @Override  
  116.     public void onClick(View v) {  
  117.         // TODO Auto-generated method stub  
  118.         switch (v.getId()) {  
  119.         case R.id.top_btn:// 点击按钮返回到ListView的第一项  
  120.             setListViewPos(0);  
  121.             break;  
  122.         }  
  123.     }  
  124.   
  125. }  

在上面的代码中,对listview 设置 setOnScrollListener 监听;当有一点滑动(也可以提供一个值)或者是到达底部的时候就出现回到顶部的按钮。 

scrollview的代码 

有很多知识点:

  1. scrollview的滑动停止监听。
  2. scrollview回到顶部,或者底部的方法。
  3. scrollview到达顶部或者底部的判断方法。

上面的参考连接也都写在注释里面了。

[java]  view plain  copy
  1. public class ScrollViewActivity extends Activity implements OnClickListener {  
  2.   
  3.     private ScrollView scrollView;// scrollView数据列表  
  4.     private Button toTopBtn;// 返回顶部的按钮  
  5.   
  6.   
  7.     private int scrollY = 0;// 标记上次滑动位置  
  8.   
  9.     private View contentView;  
  10.   
  11.     private final String TAG="test";  
  12.       
  13.     @Override  
  14.     protected void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.activity_scroll);  
  17.   
  18.         initView();  
  19.     }  
  20.   
  21.     /** 
  22.      * 初始化视图 
  23.      */  
  24.     private void initView() {  
  25.         scrollView = (ScrollView) findViewById(R.id.my_scrollView);  
  26.         if (contentView == null) {  
  27.             contentView = scrollView.getChildAt(0);  
  28.         }  
  29.   
  30.         toTopBtn = (Button) findViewById(R.id.top_btn);  
  31.         toTopBtn.setOnClickListener(this);  
  32.   
  33.         //http://blog.csdn.net/jiangwei0910410003/article/details/17024287  
  34.         /******************** 监听ScrollView滑动停止 *****************************/  
  35.         scrollView.setOnTouchListener(new OnTouchListener() {  
  36.             private int lastY = 0;  
  37.             private int touchEventId = -9983761;  
  38.             Handler handler = new Handler() {  
  39.                 @Override  
  40.                 public void handleMessage(Message msg) {  
  41.                     super.handleMessage(msg);  
  42.                     View scroller = (View) msg.obj;  
  43.                     if (msg.what == touchEventId) {  
  44.                         if (lastY == scroller.getScrollY()) {  
  45.                             handleStop(scroller);  
  46.                         } else {  
  47.                             handler.sendMessageDelayed(handler.obtainMessage(  
  48.                                     touchEventId, scroller), 5);  
  49.                             lastY = scroller.getScrollY();  
  50.                         }  
  51.                     }  
  52.                 }  
  53.             };  
  54.   
  55.             public boolean onTouch(View v, MotionEvent event) {  
  56.                 if (event.getAction() == MotionEvent.ACTION_UP) {  
  57.                     handler.sendMessageDelayed(  
  58.                             handler.obtainMessage(touchEventId, v), 5);  
  59.                 }  
  60.                 return false;  
  61.             }  
  62.   
  63.             /** 
  64.              * ScrollView 停止 
  65.              *  
  66.              * @param view 
  67.              */  
  68.             private void handleStop(Object view) {  
  69.               
  70.                 Log.i(TAG,"handleStop");  
  71.                 ScrollView scroller = (ScrollView) view;  
  72.                 scrollY = scroller.getScrollY();  
  73.   
  74.                 doOnBorderListener();  
  75.             }  
  76.         });  
  77.         /***********************************************************/  
  78.   
  79.     }  
  80.   
  81.     /** 
  82.      * ScrollView 的顶部,底部判断: 
  83.      * http://www.trinea.cn/android/on-bottom-load-more-scrollview-impl/ 
  84.      *  
  85.      * 其中getChildAt表示得到ScrollView的child View, 因为ScrollView只允许一个child 
  86.      * view,所以contentView.getMeasuredHeight()表示得到子View的高度, 
  87.      * getScrollY()表示得到y轴的滚动距离,getHeight()为scrollView的高度。 
  88.      * 当getScrollY()达到最大时加上scrollView的高度就的就等于它内容的高度了啊~ 
  89.      *  
  90.      * @param pos 
  91.      */  
  92.     private void doOnBorderListener() {  
  93.         Log.i(TAG,ScreenUtil.getScreenViewBottomHeight(scrollView) + "  "  
  94.                 + scrollView.getScrollY()+" "+ ScreenUtil  
  95.                 .getScreenHeight(ScrollViewActivity.this));  
  96.           
  97.           
  98.         // 底部判断  
  99.         if (contentView != null  
  100.                 && contentView.getMeasuredHeight() <= scrollView.getScrollY()  
  101.                         + scrollView.getHeight()) {  
  102.             toTopBtn.setVisibility(View.VISIBLE);  
  103.             Log.i(TAG,"bottom");  
  104.         }  
  105.         // 顶部判断  
  106.         else if (scrollView.getScrollY() == 0) {  
  107.               
  108.             Log.i(TAG,"top");  
  109.         }  
  110.   
  111.         else if (scrollView.getScrollY() > 30) {  
  112.             toTopBtn.setVisibility(View.VISIBLE);  
  113.             Log.i(TAG,"test");  
  114.         }  
  115.   
  116.     }  
  117.   
  118.     /** 
  119.      * 下面我们看一下这个函数: scrollView.fullScroll(ScrollView.FOCUS_DOWN);滚动到底部 
  120.      * scrollView.fullScroll(ScrollView.FOCUS_UP);滚动到顶部 
  121.      *  
  122.      *  
  123.      * 需要注意的是,该方法不能直接被调用 因为Android很多函数都是基于消息队列来同步,所以需要一部操作, 
  124.      * addView完之后,不等于马上就会显示,而是在队列中等待处理,虽然很快, 但是如果立即调用fullScroll, 
  125.      * view可能还没有显示出来,所以会失败 应该通过handler在新线程中更新 
  126.      *  
  127.      * http://blog.csdn.net/t12x3456/article/details/12799825 
  128.      * http://www.tuicool.com/articles/zayIjq 
  129.      */  
  130.     @Override  
  131.     public void onClick(View v) {  
  132.         // TODO Auto-generated method stub  
  133.         switch (v.getId()) {  
  134.             case R.id.top_btn :  
  135.                 scrollView.post(new Runnable() {  
  136.                     @Override  
  137.                     public void run() {  
  138.                         scrollView.fullScroll(ScrollView.FOCUS_UP);  
  139.                     }  
  140.                 });  
  141.                 toTopBtn.setVisibility(View.GONE);  
  142.                 break;  
  143.         }  
  144.     }  
  145.   
  146. }  

很多细节都注释在代码里面了,参考链接也已经加上。大家下载下代码执行一下看看。

代码http://download.csdn.net/detail/jjdhshdahhdd/9059757

你可能感兴趣的:(Android ListView监听上下滑动(判断是否显示返回顶部按钮))